[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r7194 - in trunk/gnue-appserver/src: . gcd generator gld
From: |
johannes |
Subject: |
[gnue] r7194 - in trunk/gnue-appserver/src: . gcd generator gld |
Date: |
Sun, 13 Mar 2005 04:41:17 -0600 (CST) |
Author: johannes
Date: 2005-03-13 04:41:15 -0600 (Sun, 13 Mar 2005)
New Revision: 7194
Added:
trunk/gnue-appserver/src/repository.py
Removed:
trunk/gnue-appserver/src/classrep/
Modified:
trunk/gnue-appserver/src/data.py
trunk/gnue-appserver/src/gcd/GCParser.py
trunk/gnue-appserver/src/gcd/readgcd.py
trunk/gnue-appserver/src/geasFilter.py
trunk/gnue-appserver/src/geasGsdGen.py
trunk/gnue-appserver/src/geasInstance.py
trunk/gnue-appserver/src/geasRpcServer.py
trunk/gnue-appserver/src/geasSession.py
trunk/gnue-appserver/src/geasSessionManager.py
trunk/gnue-appserver/src/generator/classdef.py
trunk/gnue-appserver/src/generator/form.py
trunk/gnue-appserver/src/gld/GLParser.py
trunk/gnue-appserver/src/gld/readgld.py
Log:
Improved class repository (repository-rewrite) and fixed some memory leaks from
SIGHUP
Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py 2005-03-13 10:03:11 UTC (rev 7193)
+++ trunk/gnue-appserver/src/data.py 2005-03-13 10:41:15 UTC (rev 7194)
@@ -146,7 +146,7 @@
if dirty is None:
# We could use self.__has (), here but avoiding an additional function
# call here is a big deal regarding performance, as this function is
- # called about 100000 times for a (quite small) classrepository
+ # called about 100000 times for a (quite small) class-repository
return (self.__old.has_key (table) and self.__old [table].has_key (row) \
and self.__old [table][row].has_key (field)) or \
(self.__new.has_key (table) and self.__new [table].has_key (row) \
Modified: trunk/gnue-appserver/src/gcd/GCParser.py
===================================================================
--- trunk/gnue-appserver/src/gcd/GCParser.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/gcd/GCParser.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -26,7 +26,7 @@
from gnue.common.definitions.GParserHelpers import GContent
from gnue.common.formatting import GTypecast
from gnue.common.apps import errors
-from gnue.appserver.classrep import helpers, Namespace
+from gnue.appserver import repository
xmlElements = None
@@ -277,11 +277,12 @@
fieldType = self.type.lower ().strip ()
tpMatch = re.compile ('^(\w+)').match (fieldType)
if tpMatch is None:
- raise helpers.TypeNameError, (fieldType)
+ raise repository.TypeNameError, (fieldType)
typename = tpMatch.groups () [0]
- if not typename in helpers.BASE_TYPES and len (typename.split ('_')) !=
2:
- raise helpers.TypeNameError, (fieldType)
+ if not repository.BASE_TYPES.has_key (typename) and \
+ len (typename.split ('_')) != 2:
+ raise repository.TypeNameError, (fieldType)
# try to extract length and scale from fieldType
lsMatch = _LENGTH_SCALE.match (fieldType)
@@ -298,8 +299,8 @@
raise DuplicateDefinitionError, (self.name, False)
self.scale = int (sstr)
- if typename in helpers.BASE_TYPES:
- helpers.verifyBasetype (typename, self.length, self.scale)
+ if repository.BASE_TYPES.has_key (typename):
+ repository.verifyBasetype (typename, self.length, self.scale)
else:
if not self._refsAllowed:
raise ReferenceNotAllowedError, (typename, self._type, self.name)
@@ -307,14 +308,14 @@
self.isReference = True
if self.length:
- raise helpers.TypeFormatError, \
+ raise repository.TypeFormatError, \
u_("Reference type '%s' must not have a length") % typename
if self.scale:
- raise helpers.TypeFormatError, \
+ raise repository.TypeFormatError, \
u_("Reference type '%s' must not have a scale") % typename
- typename = 'string'
- self.length = 32
+ typename = repository.REF_TYPE
+ self.length = repository.REF_LENGTH
self.datatype = typename
@@ -378,7 +379,7 @@
if self.module != self._parent.name:
self.action = 'extend'
- self.fullName = Namespace.createName (self.module, self.name)
+ self.fullName = repository.createName (self.module, self.name)
# ---------------------------------------------------------------------------
@@ -399,7 +400,7 @@
pType = 'string', length = 8, nullable = True)
if hasattr (self, 'filter'):
- (fModule, fName) = Namespace.splitName (self.filter)
+ (fModule, fName) = repository.splitName (self.filter)
self.__addProperty (fName, module = fModule)
@@ -428,6 +429,11 @@
self._children.remove (prop)
+ # Release references of the no longer needed property instance (for gc)
+ del prop._inits [:]
+ prop._parent = None
+
+
# ---------------------------------------------------------------------------
# Add a property to the class
# ---------------------------------------------------------------------------
@@ -436,7 +442,7 @@
length = None, nullable = False):
items = [c.fullName for c in self.findChildrenOfType ('GCProperty')]
- fullName = Namespace.createName (module, name)
+ fullName = repository.createName (module, name)
if fullName in items:
return None
@@ -477,7 +483,7 @@
def _validate (self):
GCTypeDefinition._validate (self)
self.module = self.findParentOfType ('GCModule').name
- self.fullName = Namespace.createName (self.module, self.name)
+ self.fullName = repository.createName (self.module, self.name)
# =============================================================================
@@ -498,7 +504,7 @@
def _validate (self):
GCTypeDefinition._validate (self)
self.module = self.findParentOfType ('GCModule').name
- self.fullName = Namespace.createName (self.module, self.name)
+ self.fullName = repository.createName (self.module, self.name)
# =============================================================================
@@ -525,7 +531,7 @@
def _complete (self):
self.module = self.findParentOfType ('GCModule').name
- self.fullName = "ix_%s" % Namespace.createName (self.module, self.name)
+ self.fullName = "ix_%s" % repository.createName (self.module, self.name)
self.fields = self.findChildrenOfType ('GCIndexField')
def _getFieldNames (self):
@@ -543,7 +549,7 @@
def _complete (self):
if not '_' in self.name:
self.module = self._parent.module
- self.fullName = Namespace.createName (self.module, self.name)
+ self.fullName = repository.createName (self.module, self.name)
else:
- self.module = Namespace.splitName (self.name) [0]
+ self.module = repository.splitName (self.name) [0]
self.fullName = self.name
Modified: trunk/gnue-appserver/src/gcd/readgcd.py
===================================================================
--- trunk/gnue-appserver/src/gcd/readgcd.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/gcd/readgcd.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -33,7 +33,7 @@
from gnue.appserver import VERSION
from gnue.appserver.gcd import GCParser
-from gnue.appserver.classrep import Namespace, helpers
+from gnue.appserver import repository
from gnue.appserver import geasConfiguration
@@ -99,7 +99,7 @@
# =============================================================================
-# Update a database schema from GNUe Class Definitions and update classrep.
+# Update a database schema from GNUe Class Definitions and update repository.
# =============================================================================
class gcdClient (GClientApp):
@@ -224,24 +224,23 @@
self._connections = connections
self._database = database
self._filenames = files
- self._files = []
+ self._files = {}
self._dump = dump
self._fileonly = fonly
self._uuidType = gConfig ('uuidtype', section = 'appserver').lower ()
# ResultSets
- self.moduleRS = None
- self.classRS = None
- self.propRS = None
- self.procRS = None
- self.parmRS = None
+ self.__moduleRS = None
+ self.__classRS = None
+ self.__propRS = None
+ self.__procRS = None
# Lookup dictionaries
- self.__lpModule = {} # gnue_id -> name, name -> gnue_id
- self.__lpClass = {} # fqName -> gnue_id
+ self.lpModule = {} # gnue_id -> name, name -> gnue_id
+ self.lpClass = {} # fqName -> gnue_id
+ self.lpProperty = {} # class-id.module-id_name -> gnue_id
+ self.lpProcedure = {} # class-name.module-name_name -> gnue_id
self.__lpFilter = {} # fqName -> gnue_id
- self.__lpProperty = {} # class-id.module-id_name -> gnue_id
- self.__lpProcedure= {} # class-name.module-name_name -> gnue_id
self.__duplos = {} # fqName
# Data from gcd files
@@ -264,10 +263,11 @@
try:
for filename in files:
- self._files.append (openResource (filename))
+ self._files [filename] = openResource (filename)
except IOError, err:
- for item in self._files:
+ while self._files:
+ (name, item) = self._files.popitem ()
item.close ()
raise StartupError, u_("Unable to open input file: %s") % \
@@ -292,16 +292,27 @@
print o (u_("Loading gcd files ..."))
- for item in xrange (len (self._files)):
+ while self._files:
+ self.__currentFile, stream = self._files.popitem ()
+ self.__currentClass = None
+
try:
- self.__currentFile = self._filenames [item]
+ schema = GCParser.loadFile (stream)
- schema = GCParser.loadFile (self._files [item])
- schema.walk (self.__iterateObjects)
+ try:
+ schema.walk (self.__iterateObjects)
+ finally:
+ self.__currentClass = None
+
+ # Make sure to unlink all reference cycles to let the gc work
+ schema.unlink ()
+ schema = None
+
finally:
- self._files [item].close ()
+ stream.close ()
+
self.__integrityCheck ()
self.executeAndGenerateCode ()
@@ -370,7 +381,6 @@
"""
if sObject._type == 'GCModule':
- self.__currentModule = sObject
self.__addModuleToRepository (sObject)
elif sObject._type == 'GCClass':
@@ -403,21 +413,21 @@
to ids and vice versa
"""
- self.__lpModule = {}
+ self.lpModule.clear ()
- if self.moduleRS is None:
- self.moduleRS = self.__openSource ('gnue_module',
+ if self.__moduleRS is None:
+ self.__moduleRS = self.__openSource ('gnue_module',
['gnue_id', 'gnue_name', 'gnue_comment']).createResultSet ()
- rec = self.moduleRS.firstRecord ()
+ rec = self.__moduleRS.firstRecord ()
while rec is not None:
gid = rec.getField ('gnue_id')
name = rec.getField ('gnue_name')
- self.__lpModule [gid] = name
- self.__lpModule [name.lower ()] = gid
+ self.lpModule [gid] = name
+ self.lpModule [name.lower ()] = gid
- rec = self.moduleRS.nextRecord ()
+ rec = self.__moduleRS.nextRecord ()
@@ -432,29 +442,29 @@
defined it will be set into the filter dictionary.
"""
- self.__lpClass = {}
- self.__lpFilter = {}
+ self.lpClass.clear ()
+ self.__lpFilter.clear ()
- if self.classRS is None:
- self.classRS = self.__openSource ('gnue_class', ['gnue_id', 'gnue_name',
+ if self.__classRS is None:
+ self.__classRS = self.__openSource ('gnue_class', ['gnue_id',
'gnue_name',
'gnue_module', 'gnue_comment', 'gnue_filter']).createResultSet ()
- rec = self.classRS.firstRecord ()
+ rec = self.__classRS.firstRecord ()
while rec is not None:
gid = rec.getField ('gnue_id')
name = rec.getField ('gnue_name')
mid = rec.getField ('gnue_module')
fid = rec.getField ('gnue_filter')
- fqName = Namespace.createName (self.__lpModule [mid], name)
+ fqName = repository.createName (self.lpModule [mid], name)
- self.__lpClass [gid] = fqName
- self.__lpClass [fqName.lower ()] = gid
+ self.lpClass [gid] = fqName
+ self.lpClass [fqName.lower ()] = gid
if fid is not None:
self.__lpFilter [fqName.lower ()] = fid
- rec = self.classRS.nextRecord ()
+ rec = self.__classRS.nextRecord ()
@@ -468,23 +478,23 @@
constructed from "classid.moduleid_propertyname".
"""
- self.__lpProperty = {}
+ self.lpProperty.clear ()
- if self.propRS is None:
- self.propRS = self.__openSource ('gnue_property', ['gnue_id',
+ if self.__propRS is None:
+ self.__propRS = self.__openSource ('gnue_property', ['gnue_id',
'gnue_module', 'gnue_class', 'gnue_name', 'gnue_type', 'gnue_length',
'gnue_scale', 'gnue_nullable', 'gnue_comment']).createResultSet ()
- rec = self.propRS.firstRecord ()
+ rec = self.__propRS.firstRecord ()
while rec is not None:
mid = rec.getField ('gnue_module')
cid = rec.getField ('gnue_class')
name = rec.getField ('gnue_name')
key = "%s.%s_%s" % (cid, mid, name.lower ())
- self.__lpProperty [key] = rec.getField ('gnue_id')
+ self.lpProperty [key] = rec.getField ('gnue_id')
- rec = self.propRS.nextRecord ()
+ rec = self.__propRS.nextRecord ()
# ---------------------------------------------------------------------------
@@ -497,24 +507,24 @@
from "classname.modulename_procedurename".
"""
- self.__lpProcedure = {}
+ self.lpProcedure.clear ()
- if self.procRS is None:
- self.procRS = self.__openSource ('gnue_procedure', ['gnue_id',
+ if self.__procRS is None:
+ self.__procRS = self.__openSource ('gnue_procedure', ['gnue_id',
'gnue_module', 'gnue_class', 'gnue_name', 'gnue_type', 'gnue_length',
'gnue_scale', 'gnue_nullable', 'gnue_comment', 'gnue_code',
'gnue_language']).createResultSet ()
- rec = self.procRS.firstRecord ()
+ rec = self.__procRS.firstRecord ()
while rec is not None:
- mName = self.__lpModule.get (rec.getField ('gnue_module'))
- cName = self.__lpClass.get (rec.getField ('gnue_class'))
+ mName = self.lpModule.get (rec.getField ('gnue_module'))
+ cName = self.lpClass.get (rec.getField ('gnue_class'))
pName = rec.getField ('gnue_name')
key = "%s.%s_%s" % (cName, mName, pName)
- self.__lpProcedure [key.lower ()] = rec.getField ('gnue_id')
+ self.lpProcedure [key.lower ()] = rec.getField ('gnue_id')
- rec = self.procRS.nextRecord ()
+ rec = self.__procRS.nextRecord ()
# ---------------------------------------------------------------------------
@@ -531,7 +541,7 @@
mkey = item.name.lower ()
mDef = self.__fetchTags (item, ['name', 'comment'])
- mDef ['gnue_id'] = self.__lpModule.get (mkey)
+ mDef ['gnue_id'] = self.lpModule.get (mkey)
if not self.modules.has_key (mkey):
self.modules [mkey] = {}
@@ -602,7 +612,7 @@
key = item.fullName.lower ()
cDef = self.__fetchTags (item, ['module', 'name', 'comment', 'filter'])
- cDef ['gnue_id'] = self.__lpClass.get (key)
+ cDef ['gnue_id'] = self.lpClass.get (key)
if not self.classes.has_key (key):
self.classes [key] = {'_files': []}
@@ -660,10 +670,10 @@
"""
fqName = "%s.%s" % (item._parent.fullName, item.fullName)
- pkey = "%s.%s_%s" % (self.__lpClass.get (item._parent.fullName.lower ()),
- self.__lpModule.get (item.module.lower ()), item.name)
+ pkey = "%s.%s_%s" % (self.lpClass.get (item._parent.fullName.lower ()),
+ self.lpModule.get (item.module.lower ()), item.name)
- pDef = {'gnue_id' : self.__lpProperty.get (pkey.lower ()),
+ pDef = {'gnue_id' : self.lpProperty.get (pkey.lower ()),
'gnue_class': item._parent.fullName,
'gnue_type' : item.datatype}
@@ -738,20 +748,20 @@
# Make sure the module referenced is a valid module, either an existing
# or a new one
mname = item ['gnue_module'].lower ()
- if not self.__lpModule.get (mname) and not self.modules.get (mname):
+ if not self.lpModule.get (mname) and not self.modules.get (mname):
raise ModuleNotFoundError, (item ['gnue_module'], item ['_files'])
# Make sure the filter class will be available if one is defined
if item.get ('gnue_filter') is not None:
fname = item ['gnue_filter']
- if not self.__lpClass.get (fname) and not self.classes.get (fname):
+ if not self.lpClass.get (fname) and not self.classes.get (fname):
raise FilterNotFoundError, (name, fname, item ['_files'])
# For an existing class we need to make sure the filter-attribute won't
# get changed, because we cannot add a not NULL field to an existing
class
if item ['gnue_id'] is not None:
iFilter = item.get ('gnue_filter') and \
- self.__lpClass [item ['gnue_filter'].lower ()]
+ self.lpClass [item ['gnue_filter'].lower ()]
if iFilter != self.__lpFilter.get (name):
raise FilterChangeError, (name, item ['_files'])
@@ -762,9 +772,9 @@
classDef = self.classes [item ['gnue_class'].lower ()]
# If a property is a reference, make sure the referenced class exists
- if not item ['gnue_type'] in helpers.BASE_TYPES:
+ if not repository.BASE_TYPES.has_key (item ['gnue_type']):
refname = item ['gnue_type'].lower ()
- if not self.__lpClass.get (refname) and not self.classes.get (refname):
+ if not self.lpClass.get (refname) and not self.classes.get (refname):
raise ClassNotFoundError, (item ['gnue_type'], classDef ['_files'])
# For an existing class make sure to *not* add NOT NULL properties
@@ -793,14 +803,19 @@
"""
# Update the result set and the lookup dictionary
- stat = self.__processResultSet (self.moduleRS, self.modules, ['gnue_name'])
- self.__getModuleLookup ()
+ try:
+ stat = self.__processResultSet (self.__moduleRS, self.modules,
+ ['gnue_name'])
+ self.__getModuleLookup ()
- print o (u_(" Modules : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
- "unchanged.") \
- % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
+ print o (u_(" Modules : %(ins)3d inserted, %(upd)3d updated, "
+ "%(kept)3d unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
- return (stat [0] + stat [1]) > 0
+ return (stat [0] + stat [1]) > 0
+
+ finally:
+ self.__moduleRS.close ()
# ---------------------------------------------------------------------------
@@ -815,51 +830,55 @@
@return: True if a commit is needed, False otherwise
"""
- # First make sure we have valid 'gnue_module' entries for all classes
- self.__replaceReferences (self.classes, self.__lpModule, 'gnue_module')
+ try:
+ # First make sure we have valid 'gnue_module' entries for all classes
+ self.__replaceReferences (self.classes, self.lpModule, 'gnue_module')
- # Then have a look at the filters defined on the classes
- filterStack = []
+ # Then have a look at the filters defined on the classes
+ filterStack = []
- for (fullName, item) in self.classes.items ():
- if item.has_key ('gnue_filter'):
- filterName = item ['gnue_filter']
- filterId = self.__lpClass.get (filterName)
+ for (fullName, item) in self.classes.items ():
+ if item.has_key ('gnue_filter'):
+ filterName = item ['gnue_filter']
+ filterId = self.lpClass.get (filterName)
- # If the filter-class is available we can use it
- if filterId is not None:
- item ['gnue_filter'] = filterId
- else:
- # since the filter-id will be created later, we add it to the queue
- # and remove the attribute from the class.
- filterStack.append ((item, filterName, fullName))
- del item ['gnue_filter']
+ # If the filter-class is available we can use it
+ if filterId is not None:
+ item ['gnue_filter'] = filterId
+ else:
+ # since the filter-id will be created later, we add it to the queue
+ # and remove the attribute from the class.
+ filterStack.append ((item, filterName, fullName))
+ del item ['gnue_filter']
- # Merge all changes into the current result set
- cond = ['gnue_module', 'gnue_name']
- stat = self.__processResultSet (self.classRS, self.classes, cond)
- needCommit = (stat [0] + stat [1]) > 0
+ # Merge all changes into the current result set
+ cond = ['gnue_module', 'gnue_name']
+ stat = self.__processResultSet (self.__classRS, self.classes, cond)
+ needCommit = (stat [0] + stat [1]) > 0
- # Update the lookup dictionary for classes
- self.__getClassLookup ()
+ # Update the lookup dictionary for classes
+ self.__getClassLookup ()
- # Process all classes with a 'new' filter class
- filterChanged = False
+ # Process all classes with a 'new' filter class
+ filterChanged = False
- if filterStack:
- for (item, filterName, fullName) in filterStack:
- item ['gnue_filter'] = self.__lpClass.get (filterName)
+ if filterStack:
+ for (item, filterName, fullName) in filterStack:
+ item ['gnue_filter'] = self.lpClass.get (filterName)
- fst = self.__processResultSet (self.classRS, self.classes, cond)
- filterChanged = fst [1] > 0
+ fst = self.__processResultSet (self.__classRS, self.classes, cond)
+ filterChanged = fst [1] > 0
- print o (u_(" Classes : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
- "unchanged.") \
- % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
+ print o (u_(" Classes : %(ins)3d inserted, %(upd)3d updated, "
+ "%(kept)3d unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
- return needCommit or filterChanged
+ return needCommit or filterChanged
+ finally:
+ self.__classRS.close ()
+
# ---------------------------------------------------------------------------
# Update/add Properties to the class repository
# ---------------------------------------------------------------------------
@@ -871,21 +890,26 @@
@return: True if a commit is needed, False otherwise
"""
- # Make sure all properties have a valid 'gnue_module' and 'gnue_class'
- self.__replaceReferences (self.properties, self.__lpModule, 'gnue_module')
- self.__replaceReferences (self.properties, self.__lpClass, 'gnue_class')
+ try:
+ # Make sure all properties have a valid 'gnue_module' and 'gnue_class'
+ self.__replaceReferences (self.properties, self.lpModule, 'gnue_module')
+ self.__replaceReferences (self.properties, self.lpClass, 'gnue_class')
- # Load and update all properties
- cond = ['gnue_module', 'gnue_class', 'gnue_name']
- stat = self.__processResultSet (self.propRS, self.properties, cond)
+ # Load and update all properties
+ cond = ['gnue_module', 'gnue_class', 'gnue_name']
+ stat = self.__processResultSet (self.__propRS, self.properties, cond)
+ self.__getPropertyLookup ()
- print o (u_(" Properties: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
- "unchanged.") \
- % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
+ print o (u_(" Properties: %(ins)3d inserted, %(upd)3d updated, "
+ "%(kept)3d unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
- return (stat [0] + stat [1]) > 0
+ return (stat [0] + stat [1]) > 0
+ finally:
+ self.__propRS.close ()
+
# ---------------------------------------------------------------------------
# Update/add Procedures to the class repository
# ---------------------------------------------------------------------------
@@ -898,22 +922,26 @@
@return: True if a commit is needed, False otherwise
"""
- # Make sure all procedures have a valid 'gnue_module' and 'gnue_class'
- self.__replaceReferences (self.procedures, self.__lpModule, 'gnue_module')
- self.__replaceReferences (self.procedures, self.__lpClass, 'gnue_class')
+ try:
+ # Make sure all procedures have a valid 'gnue_module' and 'gnue_class'
+ self.__replaceReferences (self.procedures, self.lpModule, 'gnue_module')
+ self.__replaceReferences (self.procedures, self.lpClass, 'gnue_class')
- # Load and update all procedures
- cond = ['gnue_module', 'gnue_class', 'gnue_name']
- stat = self.__processResultSet (self.procRS, self.procedures, cond)
- self.__getProcedureLookup ()
+ # Load and update all procedures
+ cond = ['gnue_module', 'gnue_class', 'gnue_name']
+ stat = self.__processResultSet (self.__procRS, self.procedures, cond)
+ self.__getProcedureLookup ()
- print o (u_(" Procedures: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
- "unchanged.") \
- % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
+ print o (u_(" Procedures: %(ins)3d inserted, %(upd)3d updated, "
+ "%(kept)3d unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
- return (stat [0] + stat [1]) > 0
+ return (stat [0] + stat [1]) > 0
+ finally:
+ self.__procRS.close ()
+
# ---------------------------------------------------------------------------
# Update/add parameters to the class repository
# ---------------------------------------------------------------------------
@@ -926,24 +954,28 @@
"""
# Make sure all parameters have a valid 'gnue_procedure'
- self.__replaceReferences (self.parameters, self.__lpProcedure,
+ self.__replaceReferences (self.parameters, self.lpProcedure,
'gnue_procedure')
- self.parmRS = self.__openSource ('gnue_parameter', ['gnue_id',
+ resultSet = self.__openSource ('gnue_parameter', ['gnue_id',
'gnue_procedure', 'gnue_name', 'gnue_type', 'gnue_scale',
'gnue_length', 'gnue_comment']).createResultSet ()
- # Load and update all parameters
- cond = ['gnue_procedure', 'gnue_name']
- stat = self.__processResultSet (self.parmRS, self.parameters, cond)
+ try:
+ # Load and update all parameters
+ cond = ['gnue_procedure', 'gnue_name']
+ stat = self.__processResultSet (resultSet, self.parameters, cond)
- print o (u_(" Parameters: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
- "unchanged.") \
+ print o (u_(" Parameters: %(ins)3d inserted, %(upd)3d updated, "
+ "%(kept)3d unchanged.") \
% {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]})
- return (stat [0] + stat [1]) > 0
+ return (stat [0] + stat [1]) > 0
+ finally:
+ resultSet.close ()
+
# ---------------------------------------------------------------------------
# Update references in a dictionary
# ---------------------------------------------------------------------------
@@ -1135,6 +1167,5 @@
return UUID.generateRandom ()
-
if __name__ == "__main__":
gcdClient ().run ()
Modified: trunk/gnue-appserver/src/geasFilter.py
===================================================================
--- trunk/gnue-appserver/src/geasFilter.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/geasFilter.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -22,7 +22,6 @@
# $Id$
from language import Session
-from classrep import Namespace
from gnue.common.apps import errors
@@ -75,6 +74,7 @@
"""
result = []
+ repository = self.__sm.repository
for (fId, filterDef) in self.__labels:
# Create an ordered sequence of all search/info-properties as stated in
@@ -88,10 +88,10 @@
# order sequence by search-value or info-value
fields.sort ()
- classdef = self.__sm.classes.find (fId)
+ classdef = repository.classes [fId]
master = classdef.gnue_filter and classdef.gnue_filter or None
if master is not None:
- master = self.__sm.classes.find (master.gnue_id).fullName
+ master = repository.classes [master.gnue_id].fullName
labels = [(f [1], f [2]['search'], f [2]['name']) for f in fields]
names = [f [2]['name'] for f in fields]
@@ -126,9 +126,8 @@
self.__fDict = {}
# First get all filters defined in class repository
- for klass in self.__sm.classes.values ():
- if klass.gnue_filter:
- self.__addFilter (klass.gnue_filter)
+ for filterClass in self.__sm.repository.filters.values ():
+ self.__addFilter (filterClass)
result = []
add = self.__getIndependantFilters ()
@@ -232,7 +231,7 @@
for label in labels:
prop = label.gnue_property
- klass = self.__sm.classes.find (prop.gnue_class.gnue_id)
+ klass = self.__sm.repository.classes [prop.gnue_class.gnue_id]
fullName = None
for p in klass.properties.values ():
@@ -250,7 +249,7 @@
'search': label.gnue_search is not None}
if not len (labels):
- filterClass = self.__sm.classes.find (filterId)
+ filterClass = self.__sm.repository.classes [filterId]
prop = filterClass.properties ['gnue_id']
entry [prop.gnue_id] = {'C': {'order' : 0,
'label' : filterClass.fullName,
@@ -272,15 +271,15 @@
currently in use. This dictionary has the filter-id's as keys and another
dictionary - with language = label - as values.
- @return: dictionary {filter-id: {language: label}, {language: label} ..}
+ @return: dictionary {filter-id: {language: label, language: label} ..}
"""
result = {}
for filterId in self.__filters:
- filterClass = self.__sm.classes.find (filterId)
+ filterClass = self.__sm.repository.classes [filterId]
prop = filterClass.properties ['gnue_id']
- cond = ['eq', ['field', 'gnue_property'], ['const', prop.gnue_id]]
+ cond = {'gnue_property': prop.gnue_id}
labels = self.__session.find ('gnue_label', cond, [],
['gnue_language', 'gnue_label'])
@@ -367,7 +366,7 @@
"""
result = {}
- classname = self.__sm.classes.find (filterId).fullName
+ classname = self.__sm.repository.classes [filterId].fullName
# if we have a master-filter add the master-field to the query as well as a
# 'select-all' condition to prevent geasSession.request () of inserting a
Modified: trunk/gnue-appserver/src/geasGsdGen.py
===================================================================
--- trunk/gnue-appserver/src/geasGsdGen.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/geasGsdGen.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -184,7 +184,7 @@
@param className: fully qualified name of the class to be exported
"""
- cDef = self.sm.classes [className]
+ cDef = self.sm.repository.classes [className]
print o(u_("Exporting data of class '%s' ...") % className)
# Prepare the tabledata- and it's definition tags
@@ -470,12 +470,13 @@
result = {}
fNames = {}
+ repository = self.sm.repository
# first replace all class-names by there gnue-id's
for (filterName, data) in self.__filterParams.items ():
- if not self.sm.classes.has_key (filterName):
+ if not repository.classes.has_key (filterName):
raise StartupError, u_("Filter class '%s' not found") % filterName
- fc = self.sm.classes [filterName]
+ fc = repository.classes [filterName]
for field in data.keys ():
if not fc.properties.has_key (field):
raise StartupError, \
@@ -538,23 +539,25 @@
@param args: list of classnames or modulenames to be exported
"""
+ repository = self.sm.repository
+
if not len (args):
if self.__useFilter:
for filterId in self.filters.keys ():
- filterClass = self.sm.classes.find (filterId)
+ filterClass = repository.classes [filterId]
if not filterClass.fullName in args:
args.append (filterClass.fullName)
else:
- for c in self.sm.classes.values ():
- if c.module.fullName == 'gnue':
+ for c in repository.classes.values ():
+ if c.gnue_module.fullName == 'gnue':
continue
args.append (c.fullName)
if self.OPTIONS ['system']:
- for c in self.sm.classes.values ():
- if c.module.fullName == 'gnue' and not c.fullName in args:
+ for c in repository.classes.values ():
+ if c.gnue_module.fullName == 'gnue' and not c.fullName in args:
args.append (c.fullName)
self.__classes = {}
@@ -585,7 +588,8 @@
dependencies given by class-references.
"""
- cDef = self.sm.classes [className]
+ repository = self.sm.repository
+ cDef = repository.classes [className]
# every class has a sequence of master-classes
if not self.__classes.has_key (className):
@@ -612,7 +616,7 @@
# if 'include-details' is set, we've to add all detail-classes of the
# current class.
- for cClass in self.sm.classes.values ():
+ for cClass in repository.classes.values ():
for p in cClass.properties.values ():
if p.isReference and p.referencedClass.gnue_id == cDef.gnue_id:
if not self.__classes.has_key (cClass.fullName):
@@ -687,7 +691,7 @@
return result
for className in self.exports:
- classdef = self.sm.classes [className]
+ classdef = self.sm.repository.classes [className]
cond = []
@@ -744,21 +748,22 @@
@return: tuple with the datasource and it's field list
"""
- className = classdef.fullName
- alias = {classdef.table: ""}
+ className = classdef.fullName
+ alias = {classdef.table: ""}
+ repository = self.sm.repository
# prepare a dictionary with aliases for all tables needed
if self.conditions.has_key (className):
alias [classdef.table] = 't0'
index = 1
for (srcrel, srcitem, dstrel, dstitem) in self.conditions [className]:
- if not alias.has_key (self.sm.classes [srcrel].table):
- alias [self.sm.classes [srcrel].table] = "t%d" % index
+ if not alias.has_key (repository.classes [srcrel].table):
+ alias [repository.classes [srcrel].table] = "t%d" % index
index += 1
if dstrel is not None and \
- not alias.has_key (self.sm.classes [dstrel].table):
- alias [self.sm.classes [dstrel].table] = "t%d" % index
+ not alias.has_key (repository.classes [dstrel].table):
+ alias [repository.classes [dstrel].table] = "t%d" % index
index += 1
# make sure the list of tables is sorted by alias
@@ -774,13 +779,13 @@
conditions = None
if self.conditions.has_key (className):
for (srcrel, srcitem, dstrel, dstitem) in self.conditions [className]:
- sValue = "%s.%s" % (alias [self.sm.classes [srcrel].table], srcitem)
+ sValue = "%s.%s" % (alias [repository.classes [srcrel].table], srcitem)
if dstrel is None:
dType = 'const'
dValue = dstitem
else:
dType = 'field'
- dValue = "%s.%s" % (alias [self.sm.classes [dstrel].table], dstitem)
+ dValue = "%s.%s" % (alias[repository.classes [dstrel].table],
dstitem)
c = GConditions.buildTreeFromList ( \
['eq', ['field', sValue], [dType, dValue]])
Modified: trunk/gnue-appserver/src/geasInstance.py
===================================================================
--- trunk/gnue-appserver/src/geasInstance.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/geasInstance.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -33,7 +33,6 @@
from gnue import appserver
from gnue.appserver.language import Object, Session
from gnue.common.logic.language import getLanguageAdapter
-from gnue.appserver.classrep import Namespace
from gnue.common.apps import errors
# =============================================================================
@@ -280,14 +279,14 @@
# Do not call OnChange triggers while in OnInit code and when setting
# time/user stamp fields
if regular and self.status () != 'initializing':
- for proc in self.__classdef.procedures.values ():
- if proc.gnue_name.upper () == 'ONCHANGE':
- self.call (proc, {}, {'oldValue': self.__getValue (propertyname),
- 'newValue': __value,
- 'propertyName': propertydef.fullName})
+ for trigger in self.__classdef.OnChange:
+ self.call (trigger, {}, {'oldValue': self.__getValue (propertyname),
+ 'newValue': __value,
+ 'propertyName': propertydef.fullName})
self.__record.putField (propertydef.column, __value)
+
# ---------------------------------------------------------------------------
# Set the values of a list of properties
# ---------------------------------------------------------------------------
@@ -355,7 +354,7 @@
cx.bindFunction ('direct_call', self.__session.call)
# set context for the procedure
- sess.setcontext (proceduredef.module.gnue_name)
+ sess.setcontext (proceduredef.gnue_module.gnue_name)
method = cx.buildFunction (proceduredef.gnue_name,
proceduredef.gnue_code,
parameters)
@@ -384,22 +383,8 @@
is raised.
"""
- # First get all validation procedures of the class
- ownValidate = None
- triggers = []
- for proc in self.__classdef.procedures.values ():
- if proc.gnue_name.upper () == 'ONVALIDATE':
- if proc.module.fullName == self.__classdef.module.fullName:
- ownValidate = proc
- else:
- triggers.append (proc)
-
- # now call all triggers
- for proc in triggers:
- self.call (proc, None)
-
- if ownValidate is not None:
- self.call (ownValidate, None)
+ for trigger in self.__classdef.OnValidate:
+ self.call (trigger, None)
# after finishing all OnValidate calls, have a look at the required fields
for prop in self.__classdef.properties.values ():
Modified: trunk/gnue-appserver/src/geasRpcServer.py
===================================================================
--- trunk/gnue-appserver/src/geasRpcServer.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/geasRpcServer.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -40,7 +40,7 @@
from gnue.appserver import geasConfiguration
-_GC_DEBUG = False # Set this to True to activate garbage collection debugging
+_GC_DEBUG = False # Set this to True to activate garbage collection debugging
# =============================================================================
# RPC application class
@@ -285,30 +285,35 @@
print o(u_("Debugging garbage collection not activated."))
return
- r = gc.collect ()
+ unreachable = gc.collect ()
gf = open ('garbage.log', 'w')
print "=" * 70
- print "GARBAGE:", r, ":"
- gf.write ('GARBAGE: %d\n' % r)
+ print "GC unreachable objects:", unreachable
+ gf.write ('GARBAGE: %d\n' % unreachable)
n = 0
for x in gc.garbage:
n += 1
- s = str(x)
- if len(s) > 75: s = s[:75]
- print type(x),"\n ", s
- gf.write ("%s: %s\n" % (type (x), repr (x)))
+ try:
+ s = repr (x)
+ if len (s) > 75: s = s [:75]
- from gnue.common.datasources import GConditions
- if isinstance (x, GConditions.GCondition):
- gf.write ("Referrer of: %s\n" % x)
- for y in gc.get_referrers (x):
- gf.write ("--> %s: %s\n" % (type (y), y))
+ print type (x), "\n ", s
+ gf.write ("%s: %s\n" % (type (x), repr (x)))
- gf.write ("%s\n" % ("-" * 70))
+ #from gnue.appserver.gld import GLParser
+ #if isinstance (x, GLParser.GLModule):
+ #gf.write ("Referrer of: %s\n" % x)
+ #for y in gc.get_referrers (x):
+ #gf.write ("--> %s: %s\n" % (type (y), y))
+ #gf.write ("%s\n" % ("-" * 70))
+
+ except:
+ print "cannot create representation of object"
+
gf.close ()
del gc.garbage [:]
Modified: trunk/gnue-appserver/src/geasSession.py
===================================================================
--- trunk/gnue-appserver/src/geasSession.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/geasSession.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -31,7 +31,7 @@
from gnue.appserver import data, geasList, geasInstance
from gnue.appserver.geasAuthentication import AuthError
-from gnue.appserver.classrep.Property import PropertyNotFoundError
+from gnue.appserver.repository import PropertyNotFoundError
# =============================================================================
@@ -135,7 +135,7 @@
if not self.__authAdapter.hasAccess (self, self.user, classname):
raise AccessDeniedError, (classname)
- return self.sm.classes [classname]
+ return self.sm.repository.classes [classname]
# ---------------------------------------------------------------------------
@@ -496,30 +496,23 @@
def __newInstance (self, classdef):
- table = classdef.table
- record = self.__connection.insertRecord (table)
+ table = classdef.table
+ record = self.__connection.insertRecord (table)
+ repository = self.sm.repository
instance = geasInstance.geasInstance (self, self.__connection, record,
classdef)
if classdef.gnue_filter:
fId = classdef.gnue_filter.gnue_id
- fName = self.sm.classes.find (fId).fullName
+ fName = classdef.gnue_filter.fullName
instance.put ([fName], [self.__filterValue (fId)])
instance.updateStamp (True)
- onInits = {}
- for proc in classdef.procedures.values ():
- if proc.gnue_name.upper () == 'ONINIT':
- onInits [proc.module.fullName] = proc
+ # Fire all OnInit triggers of the class definition
+ for trigger in classdef.OnInit:
+ instance.call (trigger, None)
- if onInits.has_key (classdef.module.fullName):
- instance.call (onInits [classdef.module.fullName], None)
- del onInits [classdef.module.fullName]
-
- for proc in onInits.values ():
- instance.call (proc, None)
-
# all modifications are 'serious' from now on
record.initialized ()
@@ -553,7 +546,7 @@
typelist.append ('procedure')
else:
- raise PropertyNotFoundError, (classdef.fullName, p)
+ raise PropertyNotFoundError, (p, classdef.fullName)
result.append (typelist)
@@ -626,10 +619,10 @@
for objectId in obj_id_list:
instance = self.__findInstance (classdef, objectId, [])
- for proc in classdef.procedures.values ():
- if proc.gnue_name.upper () == 'ONDELETE':
- instance.call (proc, None)
+ for trigger in classdef.OnDelete:
+ instance.call (trigger, None)
+
for object_id in obj_id_list:
self.__connection.deleteRecord (classdef.table, object_id)
if self.__dirtyInstances.has_key (object_id):
@@ -701,7 +694,7 @@
if classdef.gnue_filter:
useFilter = True
- filterName = self.sm.classes.find (classdef.gnue_filter.gnue_id).fullName
+ filterName = classdef.gnue_filter.fullName
cList = cTree.findChildrenOfType ('GCCField', allowAllChildren = True)
if len (cList):
for item in cList:
@@ -762,7 +755,7 @@
if classdef.gnue_filter:
filterId = classdef.gnue_filter.gnue_id
- filterName = self.sm.classes.find (filterId).fullName
+ filterName = classdef.gnue_filter.fullName
filterCond = GConditions.buildConditionFromDict ( \
{filterName: self.__filterValue (filterId)})
else:
@@ -777,14 +770,14 @@
def __filterValue (self, filterId):
- filterName = self.sm.classes.find (filterId).fullName
+ filterName = self.sm.repository.classes [filterId].fullName
if not self.filters.has_key (filterName):
filterValue = self.parameters.get (filterName, None)
if filterValue is None:
raise NoFilterParamError, (filterName)
- cond = ['eq', ['field', 'gnue_id'], ['const', filterValue]]
- fList = self.request (filterName, cond, [], ['gnue_id'])
+ cond = {'gnue_id': filterValue}
+ fList = self.request (filterName, cond, [], ['gnue_id'])
idList = self.fetch (fList, 0, 5)
if not len (idList):
Modified: trunk/gnue-appserver/src/geasSessionManager.py
===================================================================
--- trunk/gnue-appserver/src/geasSessionManager.py 2005-03-13 10:03:11 UTC
(rev 7193)
+++ trunk/gnue-appserver/src/geasSessionManager.py 2005-03-13 10:41:15 UTC
(rev 7194)
@@ -25,7 +25,6 @@
import geasSession
import geasAuthentication
-import classrep
import geasFilter
import os.path
import fnmatch
@@ -34,6 +33,7 @@
from gnue import paths
from gnue.common.datasources import GConnections
from gnue.common.apps import i18n, GConfig, errors
+from gnue.appserver import repository
from gnue.appserver.gcd import readgcd
from gnue.appserver.gld import readgld
@@ -68,6 +68,7 @@
#prof.runctx ('self.updateRepository (haltOnError = True)', globals (),
#locals ())
#prof.dump_stats ('appserver.profile')
+ self.repository = repository.Repository (self._internalSession)
self.updateRepository (scanModules, haltOnError = True)
cfg = gConfigDict (section = 'appserver')
@@ -127,22 +128,25 @@
try:
(gcd, gld) = self._scanModulePath ()
+ # Lookup dictionaries for reuse by readgld
+ lpModule = {}
+ lpClass = {}
+ lpProperty = {}
+ lpProcedure = {}
+
if len (gcd):
- reader = readgcd.gcdReader (self._connections,
+ gcdreader = readgcd.gcdReader (self._connections,
gConfig ('connection'), gcd)
- reader.run ()
+ gcdreader.run ()
- modRS = reader.moduleRS
- clsRS = reader.classRS
- prpRS = reader.propRS
- prcRS = reader.procRS
- else:
- (modRS, clsRS, prpRS, prcRS) = (None, None, None, None)
+ lpModule = gcdreader.lpModule
+ lpClass = gcdreader.lpClass
+ lpProperty = gcdreader.lpProperty
+ lpProcedure = gcdreader.lpProcedure
if len (gld):
- reader = readgld.gldReader (self._connections,
- gConfig ('connection'), gld,
- modRS, clsRS, prpRS, prcRS)
+ reader = readgld.gldReader (self._connections, gConfig ('connection'),
+ gld, lpModule, lpClass, lpProperty, lpProcedure)
reader.run ()
except:
@@ -170,7 +174,7 @@
self._internalSession.rollback ()
- classrep.init (self)
+ self.repository.load ()
self._filter = geasFilter.geasFilter (self)
Modified: trunk/gnue-appserver/src/generator/classdef.py
===================================================================
--- trunk/gnue-appserver/src/generator/classdef.py 2005-03-13 10:03:11 UTC
(rev 7193)
+++ trunk/gnue-appserver/src/generator/classdef.py 2005-03-13 10:41:15 UTC
(rev 7194)
@@ -23,7 +23,7 @@
import mx
-from gnue.appserver.classrep import Namespace
+from gnue.appserver import repository
from gnue.common.apps import errors
# =============================================================================
@@ -57,7 +57,7 @@
self.__session = session
self.__class = klass
self.__language = language
- self.classname = Namespace.createName (klass.module.name, klass.name)
+ self.classname = "%s_%s" % (klass.module.name, klass.name)
self.classLabel = "%s %s" % (klass.module.name.title (),
klass.name.title ())
self.isReference = asReference
@@ -97,6 +97,24 @@
# ---------------------------------------------------------------------------
+ # Release all resources and pointers held by a classdef instance
+ # ---------------------------------------------------------------------------
+
+ def release (self):
+ """
+ Release all references and pointers of a class definition instance. This
+ allows the garbage collection to work fine.
+ """
+
+ for item in self.properties + self.specials:
+ item.parent = None
+ if item.reference is not None:
+ item.reference.release ()
+
+ item.reference = None
+
+
+ # ---------------------------------------------------------------------------
# Create a sequence of languages to be processed for labels
# ---------------------------------------------------------------------------
@@ -206,7 +224,7 @@
for label in self.__session.find ('gnue_label', cond, [], pList):
- full = Namespace.createName (label.gnue_property.module.name,
+ full = repository.createName (label.gnue_property.module.name,
label.gnue_property.name)
if full == 'gnue_id' and len (label.label):
self.classLabel = label.label
@@ -278,7 +296,7 @@
else:
for item in self.properties:
if '_' in item.propDef.gnue_type:
- (refMod, refName) = Namespace.splitName (item.propDef.gnue_type)
+ (refMod, refName) = repository.splitName (item.propDef.gnue_type)
refClass = self.__session.find ('gnue_class',
{'gnue_name': refName, 'gnue_module.gnue_name': refMod}, [], [])
cDef = ClassDef (self.__session, refClass [0], self.__language, True)
@@ -333,6 +351,7 @@
return [(p, pageDict [p]) for p in pageNames]
+
# =============================================================================
@@ -362,10 +381,10 @@
self.info = None
self.labelPos = None
- self.fullName = Namespace.createName (propDef.gnue_module.gnue_name,
+ self.fullName = repository.createName (propDef.gnue_module.gnue_name,
propDef.gnue_name)
if isCalculated:
- self.dbField = Namespace.createName (propDef.gnue_module.gnue_name,
+ self.dbField = repository.createName (propDef.gnue_module.gnue_name,
propDef.gnue_name [3:])
else:
self.dbField = self.fullName
Modified: trunk/gnue-appserver/src/generator/form.py
===================================================================
--- trunk/gnue-appserver/src/generator/form.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/generator/form.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -83,27 +83,31 @@
@return: string with XML code of the generated form
"""
- code = [u'<?xml version="1.0" encoding="utf-8"?>']
- code.extend (self.__xml ('form', {'title': self.__classDef.classLabel,
- None: self.__options}, "", True))
+ try:
+ code = [u'<?xml version="1.0" encoding="utf-8"?>']
+ code.extend (self.__xml ('form', {'title': self.__classDef.classLabel,
+ None: self.__options}, "", True))
- for item in self.__sources.values ():
- code.extend (self.__xml ('datasource', item, " "))
+ for item in self.__sources.values ():
+ code.extend (self.__xml ('datasource', item, " "))
- code.extend (self.__xml ('logic', {None: self.__blocksToXML ()}, " "))
+ code.extend (self.__xml ('logic', {None: self.__blocksToXML ()}, " "))
- tabPos = len (self.layoutManager.visualPages) > 1 and 'top' or 'none'
- code.extend (self.__xml ('layout', {'xmlns:c': 'GNUe:Layout:Char',
- 'c:height': self.layoutManager.maxPageHeight,
- 'c:width' : self.layoutManager.maxPageWidth,
- 'tabbed' : tabPos,
- None: self.__pagesToXML ()}, " "))
+ tabPos = len (self.layoutManager.visualPages) > 1 and 'top' or 'none'
+ code.extend (self.__xml ('layout', {'xmlns:c': 'GNUe:Layout:Char',
+ 'c:height': self.layoutManager.maxPageHeight,
+ 'c:width' : self.layoutManager.maxPageWidth,
+ 'tabbed' : tabPos,
+ None: self.__pagesToXML ()}, " "))
- code.append ('</form>')
+ code.append ('</form>')
- return string.join (code, "\n")
+ return string.join (code, "\n")
+ finally:
+ self.__classDef.release ()
+
# ---------------------------------------------------------------------------
# Update the logic of the form (blocks and datasources)
# ---------------------------------------------------------------------------
Modified: trunk/gnue-appserver/src/gld/GLParser.py
===================================================================
--- trunk/gnue-appserver/src/gld/GLParser.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/gld/GLParser.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -24,7 +24,7 @@
from gnue.common.definitions import GParser, GObjects, GRootObj
from gnue.common.definitions.GParserHelpers import GContent
from gnue.common.formatting import GTypecast
-from gnue.appserver.classrep import helpers, Namespace
+from gnue.appserver import repository
xmlElements = None
@@ -209,7 +209,7 @@
if len (nameParts) > 1:
(self.module, self.name) = nameParts [:2]
- self.fullName = Namespace.createName (self.module, self.name)
+ self.fullName = repository.createName (self.module, self.name)
if not hasattr (self, 'page'):
self.page = self._parent.page
@@ -269,7 +269,7 @@
if not hasattr (self, 'module'):
self.module = self._parent.name
- self.fullName = Namespace.createName (self.module, self.name)
+ self.fullName = repository.createName (self.module, self.name)
# ---------------------------------------------------------------------------
@@ -328,4 +328,4 @@
parent = self.findParentOfType ('GLModule')
self.module = parent.name
self.language = parent.language
- self.fullName = Namespace.createName (self.module, self.name)
+ self.fullName = repository.createName (self.module, self.name)
Modified: trunk/gnue-appserver/src/gld/readgld.py
===================================================================
--- trunk/gnue-appserver/src/gld/readgld.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/gld/readgld.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -33,7 +33,7 @@
from gnue.appserver import VERSION
from gnue.appserver import geasConfiguration
from gnue.appserver.gld import GLParser
-from gnue.appserver.classrep import Namespace
+from gnue.appserver import repository
from gnue.common.apps import GBaseApp
@@ -181,31 +181,34 @@
# Constructor
# ---------------------------------------------------------------------------
- def __init__ (self, connections, database, files, modRS = None, clsRS = None,
- prpRS = None, prcRS = None):
+ def __init__ (self, connections, database, files, moduleLookup = None,
+ classLookup = None, propertyLookup = None, procedureLookup = None):
"""
- Create a new instance of a gcd reader
+ Create a new instance of a gld reader
@param connections: GConnections instance to be used
@param database: name of the connection to use (in connection.conf)
@param files: sequence of filenames to integerate
- @param modRS: resultSet instance for 'gnue_modules'
- @param clsRS: resultSet instance for 'gnue_class'
- @param prpRS: resultSet instance for 'gnue_property'
- @param prcRS: resultSet instance for 'gnue_procedure'
+ @param moduleLookup: lookup dictionary for 'gnue_modules'
+ @param classLookup: lookup dictionary for 'gnue_class'
+ @param propertyLookup: lookup dictionary for 'gnue_property'
+ @param procedureLookup: lookup dictionary for 'gnue_procedure'
"""
self._connections = connections
self._database = database
self._filenames = files
- self._files = []
+ self._files = {}
self._uuidtype = gConfig ('uuidtype', section = 'appserver').lower ()
- self.__modRS = modRS
- self.__clsRS = clsRS
- self.__prpRS = prpRS
- self.__prcRS = prcRS
+ self.lpModule = moduleLookup
+ self.lpClass = classLookup
+ self.lpProperty = propertyLookup
+ self.lpProcedure = procedureLookup
+ self.labels = {}
+ self.messages = {}
+
if not len (self._filenames):
raise StartupError, u_("No input file specified.")
@@ -214,10 +217,11 @@
try:
for filename in files:
- self._files.append (openResource (filename))
+ self._files [filename] = openResource (filename)
except IOError, err:
- for item in self._files:
+ while self._files:
+ (name, item) = self._files.popitem ()
item.close ()
raise StartupError, u_("Unable to open input file: %s") % \
@@ -234,26 +238,36 @@
updates the repository using these dictionaries.
"""
- self.labels = {}
- self.messages = {}
+ self.labels.clear ()
+ self.messages.clear ()
print _("Loading GNUe language definitions")
- for ix in xrange (len (self._files)):
- gDebug (1, "Loading gld file '%s'" % self._filenames [ix])
+ while self._files:
+ self.__currentFile, stream = self._files.popitem ()
try:
- self.__currentFile = self._filenames [ix]
+ gDebug (1, "Loading gld file '%s'" % self.__currentFile)
+
self.__currentModule = None
self.__currentClass = None
# Load xml file and process all it's objects
- schema = GLParser.loadFile (self._files [ix])
- schema.walk (self.__iterateObjects)
+ schema = GLParser.loadFile (stream)
+ try:
+ schema.walk (self.__iterateObjects)
+ finally:
+ self.__currentModule = None
+ self.__currentClass = None
+
+ schema.unlink ()
+ schema = None
+
finally:
- self._files [ix].close ()
+ stream.close ()
+
# Replace all references to modules, classes, properties and procedures
self.__replaceReferences ()
@@ -262,6 +276,7 @@
self.__updateMessages ()
+
# ---------------------------------------------------------------------------
# Iterate over all top level elements
# ---------------------------------------------------------------------------
@@ -320,7 +335,7 @@
# ---------------------------------------------------------------------------
- # Translate a message into a dictionary for later classrep update
+ # Translate a message into a dictionary for later class-repository update
# ---------------------------------------------------------------------------
def __translateMessage (self, item):
@@ -343,6 +358,7 @@
'_file' : self.__currentFile}
+
# ---------------------------------------------------------------------------
# Get a dictionary with all keys listed in tags and values from sObject
# ---------------------------------------------------------------------------
@@ -377,41 +393,49 @@
"""
# Build lookup dictionaries
- modules = self.__getModuleLookup ()
- classes = self.__getClassLookup (modules)
- properties = self.__getPrLookup (self.__prpRS, 'gnue_property')
- procedures = self.__getPrLookup (self.__prcRS, 'gnue_procedure')
+ if self.lpModule is None:
+ self.lpModule = self.__getModuleLookup ()
+ if self.lpClass is None:
+ self.lpClass = self.__getClassLookup ()
+
+ if self.lpProperty is None:
+ self.lpProperty = self.__getPropertyLookup ()
+
+ if self.lpProcedure is None:
+ self.lpProcedure = self.__getProcedureLookup ()
+
# Replace references for all labels
for label in self.labels.values ():
classname = label ['gnue_class'].lower ()
- classid = classes.get (classname)
+ classid = self.lpClass.get (classname)
if classid is None:
raise ClassNotFoundError, (label ['gnue_class'], label ['_file'])
del label ['gnue_class']
if label ['gnue_property'] is not None:
- (module, name) = Namespace.splitName (label ['gnue_property'].lower ())
- key = "%s.%s_%s" % (classid, modules [module], name)
- ckey = "%s.%s_get%s" % (classid, modules [module], name)
- if properties.has_key (key):
- label ['gnue_property'] = properties [key]
+ (module, name) = repository.splitName (label ['gnue_property'].lower
())
+ key = "%s.%s_%s" % (classid, self.lpModule [module], name)
+ ckey = "%s.%s_get%s" % (classname, module, name)
+
+ if self.lpProperty.has_key (key):
+ label ['gnue_property'] = self.lpProperty [key]
label ['gnue_procedure'] = None
- elif procedures.has_key (ckey):
- label ['gnue_procedure'] = procedures [ckey]
- label ['gnue_property'] = None
+ elif self.lpProcedure.has_key (ckey):
+ label ['gnue_procedure'] = self.lpProcedure [ckey]
+ label ['gnue_property'] = None
else:
raise PropertyNotFoundError, \
(classname, label ['gnue_property'], label ['_file'])
elif label ['gnue_procedure'] is not None:
- (module, name) = Namespace.splitName (label ['gnue_procedure'].lower
())
- key = "%s.%s_%s" % (classid, modules [module], name)
- ckey = "%s.%s_get%s" % (classid, modules [module], name)
- ref = procedures.get (key) or procedures.get (ckey)
+ (module, name) = repository.splitName (label
['gnue_procedure'].lower())
+ key = "%s.%s_%s" % (classname, module, name)
+ ckey = "%s.%s_get%s" % (classname, module, name)
+ ref = self.lpProcedure.get (key, self.lpProcedure.get (ckey))
if ref is None:
raise ProcedureNotFoundError, \
(classname, label ['gnue_procedure'], label ['_file'])
@@ -423,7 +447,7 @@
# Replace references for all messages
for message in self.messages.values ():
- message ['gnue_module'] = modules [message ['gnue_module'].lower ()]
+ message ['gnue_module'] = self.lpModule [message ['gnue_module'].lower
()]
del message ['_file']
@@ -441,88 +465,129 @@
result = {}
- if self.__modRS is None:
- src = self.__openSource ('gnue_module', ['gnue_id', 'gnue_name'])
- self.__modRS = src.createResultSet ()
+ resultSet = self.__openSource ('gnue_module',
+ ['gnue_id', 'gnue_name']).createResultSet ()
+ try:
+ rec = resultSet.firstRecord ()
+ while rec is not None:
+ name = rec.getField ('gnue_name')
+ gid = rec.getField ('gnue_id')
- rec = self.__modRS.firstRecord ()
- while rec is not None:
- name = rec.getField ('gnue_name')
- gid = rec.getField ('gnue_id')
+ result [gid] = name
+ result [name.lower ()] = gid
- result [gid] = name
- result [name.lower ()] = gid
+ rec = resultSet.nextRecord ()
- rec = self.__modRS.nextRecord ()
+ return result
- return result
+ finally:
+ resultSet.close ()
# ---------------------------------------------------------------------------
# Create a lookup dictionary for classes
# ---------------------------------------------------------------------------
- def __getClassLookup (self, modules):
+ def __getClassLookup (self):
"""
This function creates a lookup dictionary for classes, where the full
qualified name is the key and the gnue_id is the value.
- @param modules: lookup dictionary for modules
@return: dictionary with class mapping
"""
result = {}
- if self.__clsRS is None:
- src = self.__openSource ('gnue_class',
- ['gnue_id', 'gnue_module', 'gnue_name'])
- self.__clsRS = src.createResultSet ()
+ resultSet = self.__openSource ('gnue_class',
+ ['gnue_id', 'gnue_module', 'gnue_name']).createResultSet ()
+ try:
+ rec = resultSet.firstRecord ()
+ while rec is not None:
+ module = self.lpModule.get (rec.getField ('gnue_module'))
+ name = rec.getField ('gnue_name')
+ gid = rec.getField ('gnue_id')
+ key = repository.createName (module, name)
- rec = self.__clsRS.firstRecord ()
- while rec is not None:
- module = rec.getField ('gnue_module')
- name = rec.getField ('gnue_name')
- key = Namespace.createName (modules [module.lower ()], name)
- result [key.lower ()] = rec.getField ('gnue_id')
+ result [key.lower ()] = gid
+ result [gid] = key.lower ()
- rec = self.__clsRS.nextRecord ()
+ rec = resultSet.nextRecord ()
- return result
+ return result
+ finally:
+ resultSet.close ()
+
# ---------------------------------------------------------------------------
- # Create a lookup dictionary for properties or procedures
+ # Build a lookup-dictionary for properties
# ---------------------------------------------------------------------------
- def __getPrLookup (self, resultSet, table):
+ def __getPropertyLookup (self):
"""
- This function creates a lookup dictionary for properties or procedures.
+ This function creates a lookup dictionary for properties where the key is
+ constructed from "classid.moduleid_propertyname".
+ """
- @param resultSet: a resultSet instance to use or None if a new resultSet
- should be created.
- @param table: if no resultSet is given this tablename will be used to
- create a new one.
- @return: dictionary with the property- or procedure-mapping
+ result = {}
+
+ resultSet = self.__openSource ('gnue_property', ['gnue_id',
+ 'gnue_module', 'gnue_class', 'gnue_name', 'gnue_type', 'gnue_length',
+ 'gnue_scale', 'gnue_nullable', 'gnue_comment']).createResultSet ()
+
+ try:
+ rec = resultSet.firstRecord ()
+ while rec is not None:
+ mid = rec.getField ('gnue_module')
+ cid = rec.getField ('gnue_class')
+ name = rec.getField ('gnue_name')
+ key = "%s.%s_%s" % (cid, mid, name.lower ())
+
+ result [key] = rec.getField ('gnue_id')
+
+ rec = resultSet.nextRecord ()
+
+ return result
+
+ finally:
+ resultSet.close ()
+
+
+ # ---------------------------------------------------------------------------
+ # Build a lookup-dictionary for procedures
+ # ---------------------------------------------------------------------------
+
+ def __getProcedureLookup (self):
"""
+ This function creates a procedure lookup dictionary where the key is built
+ from "classname.modulename_procedurename".
+ """
result = {}
- if resultSet is None:
- src = self.__openSource (table,
- ['gnue_id', 'gnue_module', 'gnue_class', 'gnue_name'])
- resultSet = src.createResultSet ()
+ resultSet = self.__openSource ('gnue_procedure', ['gnue_id',
+ 'gnue_module', 'gnue_class', 'gnue_name', 'gnue_type', 'gnue_length',
+ 'gnue_scale', 'gnue_nullable', 'gnue_comment', 'gnue_code',
+ 'gnue_language']).createResultSet ()
- rec = resultSet.firstRecord ()
- while rec is not None:
- key = "%s.%s_%s" % (rec ['gnue_class'], rec ['gnue_module'],
- rec ['gnue_name'])
- result [key.lower ()] = rec ['gnue_id']
+ try:
+ rec = resultSet.firstRecord ()
+ while rec is not None:
+ mName = self.lpModule.get (rec.getField ('gnue_module'))
+ cName = self.lpClass.get (rec.getField ('gnue_class'))
+ pName = rec.getField ('gnue_name')
+ key = "%s.%s_%s" % (cName, mName, pName)
- rec = resultSet.nextRecord ()
+ result [key.lower ()] = rec.getField ('gnue_id')
- return result
+ rec = resultSet.nextRecord ()
+ return result
+ finally:
+ resultSet.close ()
+
+
# ---------------------------------------------------------------------------
# Create a new datasource for a given class
# ---------------------------------------------------------------------------
@@ -562,20 +627,24 @@
# Load and update all labels. To identify a label without gnue_id, use
# 'gnue_language', 'gnue_property' and 'gnue_procedure'.
rSet = src.createResultSet ()
- cond = ['gnue_language', 'gnue_property', 'gnue_procedure']
- stat = self.__processResultSet (rSet, self.labels, cond)
+ try:
+ cond = ['gnue_language', 'gnue_property', 'gnue_procedure']
+ stat = self.__processResultSet (rSet, self.labels, cond)
- if stat [0] + stat [1]:
- self._connections.commitAll ()
+ if stat [0] + stat [1]:
+ self._connections.commitAll ()
- msg = u_(" Labels : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
- "unchanged.") \
- % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
+ msg = u_(" Labels : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
+ "unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
- gDebug (1, msg)
- print o(msg)
+ gDebug (1, msg)
+ print o(msg)
+ finally:
+ rSet.close ()
+
# ---------------------------------------------------------------------------
# Update all messages in the repository
# ---------------------------------------------------------------------------
@@ -591,20 +660,24 @@
# Load and update all messages. To identify a message without a gnue_id
# 'gnue_language', 'gnue_module' and 'gnue_name' will be used.
rSet = src.createResultSet ()
- cond = ['gnue_language', 'gnue_module', 'gnue_name']
- stat = self.__processResultSet (rSet, self.messages, cond)
+ try:
+ cond = ['gnue_language', 'gnue_module', 'gnue_name']
+ stat = self.__processResultSet (rSet, self.messages, cond)
- if stat [0] + stat [1]:
- self._connections.commitAll ()
+ if stat [0] + stat [1]:
+ self._connections.commitAll ()
- msg = u_(" Messages: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
- "unchanged.") \
- % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
+ msg = u_(" Messages: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
+ "unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
- gDebug (1, msg)
- print o(msg)
+ gDebug (1, msg)
+ print o(msg)
+ finally:
+ rSet.close ()
+
# ---------------------------------------------------------------------------
# Update a given resultset using a dictionary of records
# ---------------------------------------------------------------------------
Added: trunk/gnue-appserver/src/repository.py
===================================================================
--- trunk/gnue-appserver/src/repository.py 2005-03-13 10:03:11 UTC (rev
7193)
+++ trunk/gnue-appserver/src/repository.py 2005-03-13 10:41:15 UTC (rev
7194)
@@ -0,0 +1,1069 @@
+# GNU Enterprise Application Server - Class Repository
+#
+# Copyright 2001-2005 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+from gnue.common.apps import errors
+from gnue.common.utils.CaselessDict import CaselessDict
+
+from gnue.appserver import data
+from gnue.appserver.language import Session
+
+# =============================================================================
+# Exceptions
+# =============================================================================
+
+class ModuleNotFoundError (errors.ApplicationError):
+ def __init__ (self, module):
+ msg = u_("Module '%s' not found in class repository") % module
+ errors.ApplicationError.__init__ (self, msg)
+
+class ClassNotFoundError (errors.ApplicationError):
+ def __init__ (self, classname):
+ msg = u_("Class '%s' not found in class repository") % classname
+ errors.ApplicationError.__init__ (self, msg)
+
+class FilterNotFoundError (errors.ApplicationError):
+ def __init__ (self, classname):
+ msg = u_("Filter '%s' not found in class repository") % classname
+ errors.ApplicationError.__init__ (self, msg)
+
+class PropertyNotFoundError (errors.ApplicationError):
+ def __init__ (self, name, classname):
+ msg = u_("Class '%(classname)s' has no property '%(property)s'") \
+ % {"classname": classname, "property": name}
+ errors.ApplicationError.__init__ (self, msg)
+
+class ProcedureNotFoundError (errors.ApplicationError):
+ def __init__ (self, name, classname):
+ msg = u_("Class '%(classname)s' has no procedure '%(procedure)s'") \
+ % {"classname": classname, "procedure": name}
+ errors.ApplicationError.__init__ (self, msg)
+
+class ParameterNotFoundError (errors.ApplicationError):
+ def __init__ (self, parameter, procedure):
+ msg = u_("Procedure '%(procedure)s' has no parameter '%(parameter)s'") \
+ % {"procedure": procedure, "parameter": parameter}
+ errors.ApplicationError.__init__ (self, msg)
+
+class MissingFilterClassError (errors.ApplicationError):
+ def __init__ (self, classname, filterid):
+ msg = u_("Filter '%(filter)s' defined in class '%(classname)s' not found "
+ "in class repository") \
+ % {'classname': classname, 'filter': filterid}
+ errors.ApplicationError.__init__ (self, msg)
+
+class ValidationError (errors.ApplicationError):
+ pass
+
+class TypeNameError (ValidationError):
+ def __init__ (self, typename):
+ msg = u_("'%s' is not a valid type") % typename
+ ValidationError.__init__ (self, msg)
+
+class TypeFormatError (ValidationError):
+ pass
+
+class ParameterValidationError (ValidationError):
+ def __init__ (self, procedure, parameter, error):
+ msg = u_("Error validating parameter '%(parameter)s' of procedure "
+ "'%(procedure)s': %(errors)s") \
+ % {'procedure': procedure, 'parameter': parameter, 'error': error}
+ ValidationError.__init__ (self, msg)
+
+class InvalidNameError (errors.ApplicationError):
+ def __init__ (self, name):
+ msg = u_("'%s' is not a valid, fully qualified identifier") % name
+ errors.ApplicationError.__init__ (self, name)
+
+# =============================================================================
+# This class implements the class repository
+# =============================================================================
+
+class Repository:
+ """
+ This class provides access to the class repository of AppServer. To load the
+ repository from the backend database call the method 'load'. After this the
+ following instance variables are available:
+
+ @ivar modules: dictionary with all modules available. The dictionary has
both,
+ the modulenames and their gnue_id's as keys.
+ @ivar classes: dictionary with all classes available. The dictionary has
+ both, the classnames and their gnue_id's as keys.
+ @ivar filters: dictionary with all filter classes available. The dictionary
+ uses the 'gnue_id' as keys.
+ """
+
+ # ---------------------------------------------------------------------------
+ # Create a new repository instance
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session):
+ """
+ @param session: geasSession instance to use for data retrieval
+ """
+
+ self._session = session
+ self._langSession = Session.InternalSession (session.sm)
+ self._connection = data.connection (session.connections, session.database)
+
+ self.modules = None
+ self.classes = None
+ self.filters = None
+
+
+ # ---------------------------------------------------------------------------
+ # Load the repository into modules and classes
+ # ---------------------------------------------------------------------------
+
+ def load (self):
+ """
+ This function reloads the whole class repository, which is available
+ through the properties 'modules' and 'classes'.
+ """
+
+ modules = CaselessDict (ModuleNotFoundError)
+ classes = CaselessDict (ClassNotFoundError)
+ filters = CaselessDict (FilterNotFoundError)
+
+ properties = {}
+ procedures = {}
+
+ try:
+ # First load all raw data from the gnue_* tables
+ self.__loadRawData ()
+
+ # Wrap all modules
+ for (key, value) in self.__rawModules.items ():
+ module = Module (self._langSession, value)
+ modules [key] = module
+ modules [module.fullName] = module
+
+ # Wrap all classes and install them into the apropriate module
+ for (key, value) in self.__rawClasses.items ():
+ aClass = Class (self._langSession, value, self.__rawModules)
+ module = aClass.gnue_module
+ modules [module]._installClass (aClass)
+
+ classes [key] = aClass
+ classes [aClass.fullName] = aClass
+
+ # If a class has a filter defined, we add it to the filter dictionary,
+ # which will be completed right after loading all classes
+ if aClass.gnue_filter is not None:
+ if not self.__rawClasses.has_key (aClass.gnue_filter):
+ raise MissingFilterClassError, (aClass.fullName,
aClass.gnue_filter)
+
+ filters [aClass.gnue_filter] = None
+
+ # After all classes are loaded, complete the filter dictionary
+ for key in filters.keys ():
+ filters [key] = classes [key]
+
+ # Wrap all properties and install them into the apropriate class
+ for (key, value) in self.__rawProperties.items ():
+ aProperty = Property (self._langSession, value, self.__rawModules)
+ classes [aProperty.gnue_class]._installProperty (aProperty)
+ properties [key] = aProperty
+
+ # Wrap all procedures and link them into a lookup dictionary first
+ for (key, value) in self.__rawProcedures.items ():
+ aProcedure = Procedure (self._langSession, value, self.__rawModules)
+ procedures [key] = aProcedure
+
+ # Now create all parameters and install them to their procedures.
+ for (key, value) in self.__rawParameters.items ():
+ aParameter = Parameter (self._langSession, value)
+ procedures [aParameter.gnue_procedure]._installParameter (aParameter)
+
+ # After having all parameters installed to their procedures, we can then
+ # run their second level initialization. Here it'll be determined wether
+ # a procedure is a calculated field or not. Finally the procedures will
+ # be installed to their corresponding class.
+ for item in procedures.values ():
+ item.secondaryInit (self.__rawModules)
+ classes [item.gnue_class]._installProcedure (item)
+
+ # Now finalize and verify all properties and procedures
+ for item in properties.values ():
+ item.finalize (classes)
+
+ # The verification of procedures implicitly runs a type-check for all
+ # calculated properties.
+ map (verifyProcedure, procedures.values ())
+
+
+ # To finish the build process, all references (unicode-strings) are
+ # replaced by the corresponding wrapper instance. This way a
+ # 'someClass.gnue_module.fullName' will work.
+ for item in modules.values ():
+ item.updateLinks (modules, classes)
+
+ except:
+ raise
+
+ else:
+ # We keep referernces to the old dictionaries before replacing them, so
+ # we can release them later. This eliminates a time gap between having
+ # and old and a new repository available.
+ oldmodules = self.modules
+ oldclasses = self.classes
+ oldfilters = self.filters
+
+ self.modules = modules
+ self.classes = classes
+ self.filters = filters
+
+ # finally, if we had an old repository, release it
+ if oldmodules is not None:
+ self.release (oldmodules, oldclasses, oldfilters)
+
+
+ # ---------------------------------------------------------------------------
+ # Release resources of the repository
+ # ---------------------------------------------------------------------------
+
+ def release (self, modules = None, classes = None, filters = None):
+ """
+ Release the current repository dictionaries so garbage collection still
+ works fine.
+
+ @param modules: module dictionary to release
+ @param classes: class dictionary to release
+ @param filters: filter dictionary to release
+ """
+
+ if modules is None: modules = self.modules
+ if classes is None: classes = self.classes
+ if filters is None: filters = self.filters
+
+ for item in modules.values ():
+ item.updateLinks (None, None, True)
+
+ filters.clear ()
+ classes.clear ()
+ modules.clear ()
+
+
+ # ---------------------------------------------------------------------------
+ # Load the raw data from all repository tables
+ # ---------------------------------------------------------------------------
+
+ def __loadRawData (self):
+ """
+ This function reads all repository tables into dictionaries.
+ """
+
+ self.__rawModules = self.__loadTable (u'gnue_module', [u'gnue_name'])
+ self.__rawClasses = self.__loadTable (u'gnue_class', \
+ [u'gnue_module', u'gnue_name', u'gnue_filter'])
+ self.__rawProperties = self.__loadTable (u'gnue_property', \
+ [u'gnue_module', u'gnue_class', u'gnue_name', u'gnue_length',
+ u'gnue_scale', u'gnue_nullable', u'gnue_type'])
+ self.__rawProcedures = self.__loadTable (u'gnue_procedure', \
+ [u'gnue_module', u'gnue_class', u'gnue_name', u'gnue_language',
+ u'gnue_length', u'gnue_nullable', u'gnue_scale',
u'gnue_type'])
+
+ self.__rawParameters = self.__loadTable (u'gnue_parameter', \
+ [u'gnue_procedure', u'gnue_name', u'gnue_type', u'gnue_length',
+ u'gnue_scale'])
+
+
+ # ---------------------------------------------------------------------------
+ # Load fields from a given table
+ # ---------------------------------------------------------------------------
+
+ def __loadTable (self, table, fields):
+ """
+ This function reads all rows from a table into a dictionary.
+
+ @param table: name of the table to load data from.
+ @param fields: sequence of fields to load per record.
+
+ @return: dictionary with the primary key as key and another dictionary as
+ value, using the fieldnames as keys.
+ """
+
+ result = {}
+ contents = {None: (table, None, None, fields)}
+ resultSet = self._connection.query (contents, None, [u'gnue_id'])
+
+ try:
+ rec = resultSet.nextRecord ()
+ while rec is not None:
+ row = result.setdefault (rec.getField (u'gnue_id'), {})
+
+ for field in fields:
+ row [field] = rec.getField (field)
+
+ rec = resultSet.nextRecord ()
+
+ finally:
+ resultSet.close ()
+
+ return result
+
+
+# =============================================================================
+# Base class implementing a repository element
+# =============================================================================
+
+class BaseItem:
+
+ # ---------------------------------------------------------------------------
+ # Create a new instance of a repository item
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session, classname, predefined = None):
+ """
+ This function creates a new instance of a repository item. If a predefined
+ dictionary is given, all it's elements are copied into the instances'
+ __dict__. Access to other attributes will be delegated to the corresponding
+ language interface Object.
+
+ @param session: language interface session
+ @param classname: name of the class wrapped by this item
+ @param predefined: dictionary with predefined values
+ """
+
+ self._session = session
+ self.__object = None
+ self.classname = classname
+
+ if predefined is not None:
+ self.__dict__.update (predefined)
+
+
+ # ---------------------------------------------------------------------------
+ # Access to a non-prefdefined attribute
+ # ---------------------------------------------------------------------------
+
+ def __getattr__ (self, attr):
+ """
+ This function delegates property access to the bound language interface
+ object and caches the result for following access.
+
+ @param attr: name of the attribute to retrieve
+ @return: value of the attribute
+ """
+
+ if self.__object is None:
+ self.__object = self._session._get (self.classname, self.gnue_id)
+
+ # Fetch
+ result = getattr (self.__object, attr)
+ self.__dict__ [attr] = result
+
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Dictionary emulation for wrapper instances
+ # ---------------------------------------------------------------------------
+
+ def __getitem__ (self, attr):
+ """
+ This function emulates a dictionary access to the wrapper instance.
+
+ @param attr: attribute to return
+ @return: value of the attribute 'attr'
+ """
+
+ return getattr (self, attr)
+
+
+# =============================================================================
+# This class implements a wrapper for module items of the repository
+# =============================================================================
+
+class Module (BaseItem):
+
+ # ---------------------------------------------------------------------------
+ # Create a new module item of the repository
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session, predefined = None):
+ """
+ @param session: language interface session
+ @param predefined: dictionary with predefined ('builtin') values
+ """
+
+ BaseItem.__init__ (self, session, u'gnue_module', predefined)
+
+ self.classes = CaselessDict (ClassNotFoundError)
+ self.fullName = self.gnue_name
+
+
+ # ---------------------------------------------------------------------------
+ # Install a class into the module's class list
+ # ---------------------------------------------------------------------------
+
+ def _installClass (self, aClass):
+ """
+ This function adds the given class to the modules' list of classes.
+ @param aClass: Class instance to be added
+ """
+
+ self.classes [aClass.gnue_id] = aClass
+ self.classes [aClass.fullName] = aClass
+
+
+ # ---------------------------------------------------------------------------
+ # Update links of a module item
+ # ---------------------------------------------------------------------------
+
+ def updateLinks (self, modules, classes, unlink = False):
+ """
+ This class updates links of a module item by updating the links of all it's
+ classes.
+
+ @param modules: dictionary with all modules available
+ @param classes: dictionary with all classes available
+ @param unlink: if set to True, references will be cleared
+ """
+
+ for (key, item) in self.classes.items ():
+ item.updateLinks (modules, classes, unlink)
+
+
+
+# =============================================================================
+# This class implements a class item of the repository
+# =============================================================================
+
+class Class (BaseItem):
+
+ # ---------------------------------------------------------------------------
+ # Create a new class item of the repository
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session, predefined, moduleLookup):
+ """
+ @param session: language interface session
+ @param predefined: dictionary with predefined ('builtin') values
+ @param moduleLookup: (raw) lookup-dictionary with all modules available
+ """
+
+ BaseItem.__init__ (self, session, u'gnue_class', predefined)
+
+ moduleName = moduleLookup [self.gnue_module] ['gnue_name']
+ self.fullName = createName (moduleName, self.gnue_name)
+ self.table = self.fullName
+
+ self.properties = CaselessDict (PropertyNotFoundError, self.fullName)
+ self.procedures = CaselessDict (ProcedureNotFoundError, self.fullName)
+
+ self.OnInit = []
+ self.OnChange = []
+ self.OnValidate = []
+ self.OnDelete = []
+
+
+ # ---------------------------------------------------------------------------
+ # Install a new property to the property dictionary of the class
+ # ---------------------------------------------------------------------------
+
+ def _installProperty (self, aProperty):
+ """
+ This function installs a given property to the property dictionary
+
+ @param aProperty: Property instance to be installed
+ """
+
+ self.properties [aProperty.gnue_id] = aProperty
+ self.properties [aProperty.fullName] = aProperty
+
+
+ # ---------------------------------------------------------------------------
+ # Install a new procedure to the procedure dictionary of the class
+ # ---------------------------------------------------------------------------
+
+ def _installProcedure (self, aProcedure):
+ """
+ This function adds a procedure to the procedure dictionary. If the
+ procedure is a 'calculated property' it also adds it to the property
+ dictionary. If a procedure is a trigger it will be added to the apropriate
+ trigger sequence.
+
+ @param aProcedure: procedure to be installed
+ """
+
+ self.procedures [aProcedure.gnue_id] = aProcedure
+ self.procedures [aProcedure.fullName] = aProcedure
+
+ if aProcedure.isCalculated:
+ aProperty = CalculatedProperty (aProcedure)
+ self._installProperty (aProperty)
+
+ # If the procedure is an OnInit trigger add it to the OnInit sequence. If
+ # the trigger is defined by the classes' module, it will be the first
+ # trigger to fire.
+ if aProcedure.gnue_name.upper () == 'ONINIT':
+ if aProcedure.gnue_module == self.gnue_module:
+ self.OnInit.insert (0, aProcedure)
+ else:
+ self.OnInit.append (aProcedure)
+
+ # If the procedure is an OnValidate trigger add it to the trigger sequence.
+ # The OnValidate trigger defined by the classes' module will be the last
+ # one fired.
+ if aProcedure.gnue_name.upper () == 'ONVALIDATE':
+ if aProcedure.gnue_module == self.gnue_module:
+ self.OnValidate.append (aProcedure)
+ else:
+ self.OnValidate.insert (0, aProcedure)
+
+ # If the procedure is an OnChange trigger add it to the trigger sequence.
+ if aProcedure.gnue_name.upper () == 'ONCHANGE':
+ self.OnChange.append (aProcedure)
+
+ # If the procedure is an OnDelete trigger add it to the trigger sequence.
+ if aProcedure.gnue_name.upper () == 'ONDELETE':
+ self.OnDelete.append (aProcedure)
+
+
+ # ---------------------------------------------------------------------------
+ # Update all links within a class wrapper
+ # ---------------------------------------------------------------------------
+
+ def updateLinks (self, modules, classes, unlink = False):
+ """
+ This class updates links of a class item by updating the links of all it's
+ properties and procedures.
+
+ @param modules: dictionary with all modules available
+ @param unlink: if set to True, references will be cleared
+ """
+
+ if unlink:
+ self.gnue_module = None
+ self.gnue_filter = None
+
+ del self.OnInit [:]
+ del self.OnChange [:]
+ del self.OnValidate [:]
+ del self.OnDelete [:]
+
+ else:
+ if not isinstance (self.gnue_module, Module):
+ self.gnue_module = modules [self.gnue_module]
+
+ if self.gnue_filter and not isinstance (self.gnue_filter, Class):
+ self.gnue_filter = classes [self.gnue_filter]
+
+ for item in self.properties.values () + self.procedures.values ():
+ item.updateLinks (self, modules, unlink)
+
+
+
+# =============================================================================
+# This class wraps a property item of the repository
+# =============================================================================
+
+class Property (BaseItem):
+
+ # ---------------------------------------------------------------------------
+ # Create a new property item
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session, predefined, moduleLookup):
+ """
+ @param session: language interface session
+ @param predefined: dictionary with predefined ('builtin') values
+ @param moduleLookup: (raw) lookup-dictionary with all modules available
+ """
+
+ updateTypeInfo (predefined)
+ BaseItem.__init__ (self, session, u'gnue_property', predefined)
+
+ moduleName = moduleLookup [self.gnue_module]['gnue_name']
+ self.fullName = createName (moduleName, self.gnue_name)
+ self.column = self.fullName
+
+ self.isCalculated = False
+ self.isReference = False
+ self.referencedClass = None
+
+
+ # ---------------------------------------------------------------------------
+ # Update the links of a property item
+ # ---------------------------------------------------------------------------
+
+ def updateLinks (self, aClass, modules, unlink = False):
+ """
+ This function updates the links of a property item to it's module and
+ class. If unlink is set the references are cleared.
+
+ @param aClass: Class instance the property belongs to
+ @param modules: Module dictionary with all modules available
+ @param unlink: this boolean Flag determines wether to establish links or to
+ break them
+ """
+
+ if unlink:
+ self.gnue_module = None
+ self.gnue_class = None
+ self.referencedClass = None
+
+ else:
+ self.gnue_class = aClass
+ if not isinstance (self.gnue_module, Module):
+ self.gnue_module = modules [self.gnue_module]
+
+
+ # ---------------------------------------------------------------------------
+ # Finalize the definition of a property
+ # ---------------------------------------------------------------------------
+
+ def finalize (self, classes):
+ """
+ This function verifies the type of the property and set's the reference
+ flags for rerference properties.
+
+ @param classes: dictionary with all classes available
+ """
+
+ r = verifyType (self.gnue_type, self.gnue_length, self.gnue_scale, classes)
+
+ self.isReference = r is not None
+ self.referencedClass = r
+
+
+
+# =============================================================================
+# This class wraps a calculated property (= special procedures)
+# =============================================================================
+
+class CalculatedProperty (BaseItem):
+
+ # ---------------------------------------------------------------------------
+ # Create a new calculated property
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, aProcedure):
+ """
+ @param aProcedure: procedure to bind as calculated property
+ """
+
+ predefined = {
+ 'gnue_id' : aProcedure.gnue_id,
+ 'gnue_name' : aProcedure.calcName,
+ 'gnue_type' : aProcedure.gnue_type,
+ 'gnue_length' : aProcedure.gnue_length,
+ 'gnue_scale' : aProcedure.gnue_scale,
+ 'gnue_module' : aProcedure.gnue_module,
+ 'gnue_class' : aProcedure.gnue_class,
+ 'gnue_nullable': aProcedure.gnue_nullable}
+ updateTypeInfo (predefined)
+
+ BaseItem.__init__ (self, aProcedure._session, u'gnue_procedure',
predefined)
+
+ self.fullName = aProcedure.calcFullName
+ self.column = None
+
+ self.isReference = False
+ self.referencedClass = None
+ self.isCalculated = True
+ self.procedure = aProcedure
+
+
+ # ---------------------------------------------------------------------------
+ # Update the links of a calculated property item
+ # ---------------------------------------------------------------------------
+
+ def updateLinks (self, aClass, modules, unlink = False):
+ """
+ If in unlink mode this function clears the pointer to the bound procedure.
+
+ @param aClass: Class instance the property belongs to
+ @param modules: Module dictionary with all modules available
+ @param unlink: this boolean Flag determines wether to establish links or to
+ break them
+ """
+
+ if unlink:
+ self.gnue_module = None
+ self.gnue_class = None
+ self.procedure = None
+
+ else:
+ self.gnue_class = aClass
+ if not isinstance (self.gnue_module, Module):
+ self.gnue_module = modules [self.gnue_module]
+
+
+
+
+# =============================================================================
+# This class wraps a procedure item of the repository
+# =============================================================================
+
+class Procedure (BaseItem):
+
+ # ---------------------------------------------------------------------------
+ # Create a new procedure wrapper
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session, predefined, moduleLookup):
+ """
+ @param session: language interface session
+ @param predefined: dictionary with predefined ('builtin') values
+ @param moduleLookup: (raw) lookup-dictionary with all modules available
+ """
+
+ BaseItem.__init__ (self, session, u'gnue_procedure', predefined)
+
+ moduleName = moduleLookup [self.gnue_module]['gnue_name']
+ self.fullName = createName (moduleName, self.gnue_name)
+
+ self.isCalculated = False
+ self.calcFullName = None
+ self.calcName = None
+
+ self.parameters = CaselessDict (ParameterNotFoundError)
+
+
+ # ---------------------------------------------------------------------------
+ # Second level initialization for a procedure
+ # ---------------------------------------------------------------------------
+
+ def secondaryInit (self, moduleLookup):
+ """
+ This function determines wether a procedure can be used as a calculated
+ field or not. If so the flag 'isCalcualted' will be set.
+
+ @param moduleLookup: lookup dictionary for modules
+ """
+
+ self.isCalculated = self.gnue_type is not None and \
+ not len (self.parameters) and self.gnue_name [:3].lower () == 'get'
+
+ if self.isCalculated:
+ self.calcName = self.gnue_name [3:]
+ moduleName = moduleLookup [self.gnue_module]['gnue_name']
+ self.calcFullName = createName (moduleName, self.calcName)
+
+
+ # ---------------------------------------------------------------------------
+ # Install a parameter to the procedures parameter dictionary
+ # ---------------------------------------------------------------------------
+
+ def _installParameter (self, aParameter):
+ """
+ This function installs the given parameter to the procedure's parameter
+ dictionary.
+
+ @param aParameter: the parameter to be installed.
+ """
+
+ self.parameters [aParameter.gnue_id] = aParameter
+ self.parameters [aParameter.fullName] = aParameter
+
+
+ # ---------------------------------------------------------------------------
+ # Update the links of a procedure item
+ # ---------------------------------------------------------------------------
+
+ def updateLinks (self, aClass, modules, unlink = False):
+ """
+ This function updates the links of a procedure item to it's module and
+ class. If unlink is set the references are cleared.
+
+ @param aClass: Class instance the procedure belongs to
+ @param modules: Module dictionary with all modules available
+ @param unlink: this boolean Flag determines wether to establish links or to
+ break them
+ """
+
+ if unlink:
+ self.gnue_module = None
+ self.gnue_class = None
+
+ else:
+ self.gnue_class = aClass
+ if not isinstance (self.gnue_module, Module):
+ self.gnue_module = modules [self.gnue_module]
+
+ for param in self.parameters.values ():
+ param.updateLinks (self, unlink)
+
+
+
+# =============================================================================
+# This class implements a parameter item of the repository
+# =============================================================================
+
+class Parameter (BaseItem):
+
+ # ---------------------------------------------------------------------------
+ # Create a new parameter wrapper instance
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session, predefined):
+ """
+ @param session: language interface session
+ @param predefined: dictionary with predefined ('builtin') values
+ """
+
+ BaseItem.__init__ (self, session, u'gnue_parameter', predefined)
+ self.fullName = self.gnue_name
+
+ if NONREF_TYPES.has_key (self.gnue_type):
+ self.dbType = self.gnue_type
+ else:
+ self.dbType = REF_TYPE
+
+
+ # ---------------------------------------------------------------------------
+ # Update links
+ # ---------------------------------------------------------------------------
+
+ def updateLinks (self, aProcedure, unlink = False):
+ """
+ This functions updates the link to the owning procedure.
+
+ @param aProcedure: the owning procedure
+ @param unlink: if set to True the reference will be cleared
+ """
+
+ if unlink:
+ self.gnue_procedure = None
+
+ else:
+ self.gnue_procedure = aProcedure
+
+
+
+# =============================================================================
+# Type checking support
+# =============================================================================
+
+NONREF_TYPES = {'boolean': True, 'date' : True, 'datetime': True,
+ 'number' : True, 'string': True, 'time' : True}
+BASE_TYPES = {'id': True}
+BASE_TYPES.update (NONREF_TYPES)
+
+NOLS_TYPES = {'id': 1, 'date': 1, 'time': 1, 'datetime': 1, 'boolean': 1}
+
+REF_TYPE = "string"
+REF_LENGTH = 32
+REF_SCALE = 0
+
+
+# -----------------------------------------------------------------------------
+# Check if a combination of typename, length and scale is valid
+# -----------------------------------------------------------------------------
+
+def verifyBasetype (typename, length, scale):
+ """
+ This function verifies a given typename with length and scale. If this
+ combination makes no sense a TypeFormatError will be raised. If typename
+ is no valid base type a TypeNameError will be raised.
+
+ @param typename: name of the datatype
+ @param length: length of the datatype
+ @param scale: scale of the datatype
+ """
+
+ if not BASE_TYPES.has_key (typename):
+ raise TypeNameError, (typename)
+
+ # A string type must not have a scale
+ if typename == 'string':
+ if scale:
+ raise TypeFormatError, u_("string does not support 'scale'")
+
+ # All of the following types must not have length nor scale
+ if NOLS_TYPES.has_key (typename):
+ if length:
+ raise TypeFormatError, u_("%s does not support 'length'") % typename
+ if scale:
+ raise TypeFormatError, u_("%s does not support 'scale'") % typename
+
+ # A number must have at least a 'length'
+ if typename == 'number':
+ if not length:
+ raise TypeFormatError, u_("number without 'length'")
+
+
+# -----------------------------------------------------------------------------
+# Verify a given type
+# -----------------------------------------------------------------------------
+
+def verifyType (typename, length, scale, classes):
+ """
+ This function verifies a given type, length and scale combination, optionally
+ using the given class dictionary for lookups of references.
+
+ @param typename: name of the datatype
+ @param length: length of the datatype
+ @param scale: scale of the datatype
+ @param classes: class dictionary to check for reference types
+
+ @return: If 'typename' is a reference type this function returns the class
+ definition of this reference type, otherwise None
+ """
+
+ if classes.has_key (typename):
+ if length:
+ raise TypeFormatError, u_("Reference types must not have a 'length'")
+
+ if scale:
+ raise TypeFormatError, u_("Reference types must not have a 'scale'")
+
+ return classes [typename]
+
+ else:
+ verifyBasetype (typename, length, scale)
+ return None
+
+
+# -----------------------------------------------------------------------------
+# Verify a procedure definition
+# -----------------------------------------------------------------------------
+
+def verifyProcedure (aProc):
+ """
+ This function checks the resulttype of a procedure definition, and all
+ parameter types (if available).
+
+ @param aProc: procedure wrapper item to be checked
+ """
+
+ # If a result type is specified, check it
+ if aProc.gnue_type is not None:
+ verifyBasetype (aProc.gnue_type, aProc.gnue_length, aProc.gnue_scale)
+
+ else:
+ # otherwise there must not be anything concerning a result type
+ if aProc.gnue_length:
+ raise TypeFormatError, u_("%s: Procedure has no result, but a 'length' "
+ "is specified.") % aProc.fullName
+ if aProc.gnue_scale:
+ raise TypeFormatError, u_("%s: Procedure has no result, but a 'scale' "
+ "is specified.") % aProc.fullName
+
+ # verify all given parameter types
+ for pa in aProc.parameters.values ():
+ try:
+ verifyBasetype (pa.gnue_type, pa.gnue_length, pa.gnue_scale)
+
+ except ValidationError, vErr:
+ raise ParameterValidationError, \
+ (aProc.fullName, pa.fullName, vErr.message)
+
+
+# -----------------------------------------------------------------------------
+# Create a type information dictionary for a given wrapper item
+# -----------------------------------------------------------------------------
+
+def updateTypeInfo (item):
+ """
+ This function updates all type information in a given dictionary. It assumes
+ to find the keys 'gnue_type', 'gnue_length' and 'gnue_scale' in the
+ dictionary. After updating the dictionary will contain the following
+ additional keys: fullType, dbFullType, dbType, dbLength and dbScale
+
+ @param item: dictionary to update type information
+ """
+
+ gType = dbType = fullType = item ['gnue_type']
+ length = dbLength = item ['gnue_length']
+ scale = dbScale = item ['gnue_scale']
+
+ if gType in ["string", "number"]:
+ if gType == "number" and length and scale:
+ fullType = "%s(%d,%d)" % (gType, length, scale)
+
+ elif length:
+ fullType = "%s(%d)" % (gType, length)
+
+ # build database specific type information
+ if not NONREF_TYPES.has_key (gType):
+ (dbType, dbLength, dbScale) = (REF_TYPE, REF_LENGTH, REF_SCALE)
+
+ dbFullType = dbType
+ if dbType in ["string", "number"]:
+ if dbType == "number" and dbLength and dbScale:
+ dbFullType = "%s(%d,%d)" % (dbType, dbLength, dbScale)
+
+ elif dbLength:
+ dbFullType = "%s(%d)" % (dbType, dbLength)
+
+ item.update ({'fullType' : fullType,
+ 'dbFullType': dbFullType,
+ 'dbType' : dbType,
+ 'dbLength' : dbLength,
+ 'dbScale' : dbScale})
+
+
+# -----------------------------------------------------------------------------
+# Create a fully qualified name from namespace and identifier
+# -----------------------------------------------------------------------------
+
+def createName (namespace, identifier):
+ """
+ This function creates a fully qualified name from namespace and identifier.
+ If the result is not a valid name, an InvalidNameError will be raised.
+
+ @param namespace: the namespace to use
+ @param identifier: the identifier to use
+
+ @return: fully qualified name: 'namespace_idendifier'
+ """
+
+ result = "%s_%s" % (namespace, identifier)
+
+ if len (result.split ('_')) != 2:
+ raise InvalidNameError, result
+
+ return result
+
+
+# -----------------------------------------------------------------------------
+# Split a fully qualified name into namespace and identifier
+# -----------------------------------------------------------------------------
+
+def splitName (name):
+ """
+ This function splits the given name into namespace and identifier parts. If
+ name does not contain a namespace at all, it will be left empty. If the
+ resulting tuple has more than two parts an InvalidNameError will be raised.
+
+ @param name: the name to be split into namespace and identifier
+
+ @return: tuple (namespace, identifier) where namespace could be an empty
+ string if name had no namespace information at all
+ """
+
+ parts = name.split ('_')
+ items = len (parts)
+
+ if items == 1:
+ result = ('', name)
+
+ elif items == 2:
+ result = tuple (parts)
+
+ else:
+ raise InvalidNameError, name
+
+ return result
Property changes on: trunk/gnue-appserver/src/repository.py
___________________________________________________________________
Name: svn:keywords
+ Id
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r7194 - in trunk/gnue-appserver/src: . gcd generator gld,
johannes <=