[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r6467 - trunk/gnue-appserver/src
From: |
johannes |
Subject: |
r6467 - trunk/gnue-appserver/src |
Date: |
Mon, 11 Oct 2004 04:12:50 -0500 (CDT) |
Author: johannes
Date: 2004-10-11 04:12:49 -0500 (Mon, 11 Oct 2004)
New Revision: 6467
Modified:
trunk/gnue-appserver/src/geasGsdGen.py
Log:
*) added supports of 'include-details' option
*) added support of filters; one can now select data to be exported using
filters on the commandline like: foobar.barbaz=someval
Modified: trunk/gnue-appserver/src/geasGsdGen.py
===================================================================
--- trunk/gnue-appserver/src/geasGsdGen.py 2004-10-10 18:33:35 UTC (rev
6466)
+++ trunk/gnue-appserver/src/geasGsdGen.py 2004-10-11 09:12:49 UTC (rev
6467)
@@ -23,12 +23,14 @@
import sys
import types
+import copy
+import string
import mx.DateTime
from gnue.common.apps import i18n, errors
from gnue.common.schema import Objects
from gnue.common.apps.GClientApp import *
-from gnue.common.datasources import GDataSource
+from gnue.common.datasources import GDataSource, GConditions
from gnue.common.definitions import GParserHelpers
from gnue.appserver import VERSION
@@ -41,10 +43,15 @@
class CircularReferenceError (errors.ApplicationError):
def __init__ (self):
- msg = _("Classes have circular or unresolveable references")
+ msg = u_("Classes have circular or unresolveable references")
errors.ApplicationError.__init__ (self, msg)
+class CircularFishHookError (errors.UserError):
+ def __init__ (self, classname):
+ msg = u_("The class '%s' contains circular data-references") % classname
+ errors.UserError.__init__ (self, msg)
+
# =============================================================================
# Generate GNUe Schema Definition files
# =============================================================================
@@ -58,8 +65,6 @@
SUMMARY = _("A tool to dump data from a database into a GNUe Schema "
"Definition (gsd) file.")
-
-
# ---------------------------------------------------------------------------
# Constructor
# ---------------------------------------------------------------------------
@@ -76,6 +81,10 @@
self.addCommandOption ('system', 's', default = False,
help = _("If flag is set include system classes ('gnue_*')"))
+ self.addCommandOption ('include-details', 'i', default = False,
+ help = _("If set all detail-classes of the requestd classes will be "
+ "exported too"))
+
ConfigOptions = {}
GClientApp.__init__ (self, connections, 'appserver', ConfigOptions)
@@ -88,191 +97,213 @@
if self.OPTIONS ["database"] is not None:
cparser.set ('appserver', 'database', self.OPTIONS ["database"])
+ self.__filterParams = self.__getFilterParams ()
+ self.__useFilter = False
+
# ---------------------------------------------------------------------------
# Main program
# ---------------------------------------------------------------------------
def run (self):
+ """
+ This is the main function of the gsd generator. If parses the options
+ given, creates the GSD object tree and dumps it to the output file.
+ """
+
if self.OPTIONS ['output'] is None:
raise StartupError, u_("No output file specified.")
self.__filename = self.OPTIONS ['output']
args = [unicode (a, i18n.encoding) for a in self.ARGUMENTS]
- print _("Loading class repository ...")
+ print o(u_("Loading class repository ..."))
self.sm = geasSessionManager (self.connections)
+ self.filters = self.__verifyFilters ()
+ self.__useFilter = len (self.filters.keys ()) > 0
- print _("Generating schema definition ...")
+ print o(u_("Building list of classes and calculating dependencies ..."))
- try:
- self._createClassList (args)
+ self.exports = self.__createClassList (args)
+ self.conditions = self.__createConditionDicts ()
- schema = Objects.GSSchema ()
- schema.title = 'Appserver Data Dump'
- schema.author = self.COMMAND
- schema.version = '1.0'
- self._data = Objects.GSData (schema)
+ print o(u_("Generating schema definition ..."))
- for classname in self.exports:
- self._exportClass (classname)
+ schema = Objects.GSSchema ()
+ schema.title = 'Appserver Data Dump'
+ schema.author = self.COMMAND
+ schema.version = '1.0'
+ self._data = Objects.GSData (schema)
- dest = open (self.__filename, "w")
- dest.write ("""<?xml version="1.0" encoding="UTF-8"?>\n""")
- dest.write (schema.dumpXML ().encode ('utf-8'))
- dest.close ()
+ for classname in self.exports:
+ self.__exportClass (classname)
+ dest = open (self.__filename, "w")
+ dest.write ("""<?xml version="1.0" encoding="UTF-8"?>\n""")
+ dest.write (schema.dumpXML ().encode ('utf-8'))
+ dest.close ()
- except Exception:
- msg = "%s\n" % str (sys.exc_info () [1])
- sys.stderr.write (msg)
- sys.exit (1)
+ print o(u_("Generation run complete."))
- print _("Generation run complete.")
-
# ---------------------------------------------------------------------------
- # Create a list of classes to be exported
+ # Export data of a given class
# ---------------------------------------------------------------------------
- def _createClassList (self, args):
+ def __exportClass (self, className):
"""
- This function creates a sequence of classnames to be dumped. This sequence
- is in a proper order so no constraint-violations should occur.
+ Create a TableData object tree with all data of the given class.
+
+ @param className: fully qualified name of the class to be exported
"""
- if not len (args):
- for c in self.sm.classes.values ():
- if not self.OPTIONS ['system'] and c.module.fullName == 'gnue':
- continue
- args.append (c.fullName)
+ cDef = self.sm.classes [className]
+ print o(u_("Exporting data of class '%s' ...") % className)
- self.classes = {}
- for cName in args:
- self._addClass (cName)
+ # Prepare the tabledata- and it's definition tags
+ table = Objects.GSTableData (self._data)
+ table.name = "%s_dump" % cDef.table
+ table.tablename = cDef.table
- self.exports = []
- res = self._shrinkList ()
+ columns = Objects.GSDefinition (table)
- while len (res):
- self.exports.extend (res)
- res = self._shrinkList ()
+ fieldlist = []
+ for prop in cDef.properties.values ():
+ if prop.isCalculated: continue
+ column = Objects.GSColumn (columns)
+ column.field = prop.column
+ column.type = prop.dbFullType
+ if prop.fullName == 'gnue_id':
+ column.key = True
+ fieldlist.append (prop.column)
+
+ rows = Objects.GSRows (table)
+
+ if self.__fishes.has_key (className):
+ self.__fishDataDump (cDef, fieldlist, rows)
+ else:
+ self.__normalDataDump (cDef, fieldlist, rows)
+
+
# ---------------------------------------------------------------------------
- # add a class to the classlist and iterate over all references
+ # Dump all records of a class without any sorting stuff
# ---------------------------------------------------------------------------
- def _addClass (self, className):
+ def __normalDataDump (self, classDef, fieldlist, rows):
"""
- This function adds a class to the list of classes respecting all
- dependencies given by class-references.
+ This function creates a resultset for the given class and iterates over all
+ records. All fields with a value other than <None> will be added to the
+ rows collection.
+
+ @param classDef: class definition of the class to be dumped
+ @param fieldlist: list of fieldnames to be exported
+ @param rows: GSRows collection to which new records will be added
"""
- cDef = self.sm.classes [className]
- if not self.classes.has_key (className):
- self.classes [className] = []
- for p in cDef.properties.values ():
- if p.isReference:
- refClass = p.referencedClass.fullName
- if not refClass in self.classes [className]:
- self.classes [className].append (refClass)
- self._addClass (refClass)
+ (dts, fields) = self.__openSource (classDef, fieldlist)
+ resultSet = dts.createResultSet ()
+ record = resultSet.firstRecord ()
+ while record is not None:
+ self.__addRow (record, classDef, fields, rows)
+ record = resultSet.nextRecord ()
+
+
# ---------------------------------------------------------------------------
- # Return all items from the classlist, which have no dependencies
+ # Create a row object and add it to the rows collection
# ---------------------------------------------------------------------------
- def _shrinkList (self):
+ def __addRow (self, record, classDef, fields, rows):
"""
- This function returns a sequence of all classes without any dependencies.
- If no such classes were found but there are still classes in the dictionary
- a CircularReferenceError will be raised.
+ This function adds a new row to the given row collection using the values
+ from the given record.
+
+ @param record: record which should be exported
+ @param classDef: class definition of the record
+ @param fields: sequence of fieldnames to be exported
+ @param rows: GSRows instance which is parent of the newly created rows
"""
- result = []
- for (classname, refs) in self.classes.items ():
- if not len (refs):
- result.append (classname)
+ row = Objects.GSRow (rows)
- for ref in self.classes.values ():
- if classname in ref:
- ref.remove (classname)
+ for field in fields:
+ pName = "." in field and field.split (".", 1) [-1] or field
+ prop = classDef.properties [pName]
+ data = record.getField (field)
- del self.classes [classname]
+ if data is not None:
+ value = Objects.GSValue (row)
+ value.field = prop.column
- if not len (result) and len (self.classes.keys ()):
- raise CircularReferenceError
+ GParserHelpers.GContent ( \
+ value, self.__nativeToString (data, prop.dbFullType))
- return result
-
# ---------------------------------------------------------------------------
- # Export data of a given class
+ # Export data from a class with a fishhook
# ---------------------------------------------------------------------------
- def _exportClass (self, className):
+ def __fishDataDump (self, classDef, fieldlist, rows):
"""
- Create a TableData object tree with all data of the given class.
+ This function exports all records (according to an existing filter) of a
+ class which has a fishhook. All records are exported in an order which
+ allows reimporting without reference-violation.
+
+ @param classDef: class definition of the class to be dumped
+ @param fieldlist: list of fieldnames to be exported
+ @param rows: GSRows collection to which new records will be added
"""
- cDef = self.sm.classes [className]
- print u_("Exporting data of class '%s' ...") % className
- # Prepare the tabledata- and it's definition tags
- table = Objects.GSTableData (self._data)
- table.name = "%s_dump" % cDef.table
- table.tablename = cDef.table
+ (dts, fields) = self.__openSource (classDef, fieldlist)
- columns = Objects.GSDefinition (table)
+ dataDict = {}
+ idField = 't0.gnue_id' in fields and 't0.gnue_id' or 'gnue_id'
+ className = classDef.fullName
+ resultSet = dts.createResultSet ()
- fieldlist = []
- for prop in cDef.properties.values ():
- if prop.isCalculated: continue
+ # first we create a dependency-tree for all records
+ record = resultSet.firstRecord ()
- column = Objects.GSColumn (columns)
- column.field = prop.column
- column.type = prop.dbFullType
+ while record is not None:
+ gnue_id = record.getField (idField)
- fieldlist.append (prop.column)
+ if not dataDict.has_key (gnue_id):
+ dataDict [gnue_id] = []
- rows = Objects.GSRows (table)
+ for ref in self.__fishes [classDef.fullName]:
+ rField = "t0.%s" % ref in fields and "t0.%s" % ref or ref
+ refId = record.getField (rField)
+ if refId is not None and not refId in dataDict [gnue_id]:
+ dataDict [gnue_id].append (refId)
- # Create a datasource for the given class
- attrs = {'name' : "dts_%s" % cDef.table,
- 'database': self.sm._internalSession.database,
- 'table' : cDef.table}
- dts = GDataSource.DataSourceWrapper ( \
- connections = self.connections,
- attributes = attrs,
- fields = fieldlist,
- unicodeMode = True)
+ record = resultSet.nextRecord ()
- rs = dts.createResultSet ()
+ # now create an ordered sequence from that dependency tree
+ result = []
+ add = self.__shrinkList (dataDict, CircularFishHookError, className)
- rec = rs.firstRecord ()
+ while len (add):
+ result.extend (add)
+ add = self.__shrinkList (dataDict, CircularFishHookError, className)
- while rec is not None:
- row = Objects.GSRow (rows)
+ # and export all records according to this order
+ for gnue_id in result:
+ record = resultSet.firstRecord ()
- for prop in cDef.properties.values ():
- if prop.isCalculated: continue
+ while record is not None:
+ if record.getField (idField) == gnue_id:
+ self.__addRow (record, classDef, fields, rows)
+ break
- data = rec.getField (prop.column)
- if data is not None:
- value = Objects.GSValue (row)
- value.field = prop.column
- if prop.column == 'gnue_id':
- value.key = True
- GParserHelpers.GContent ( \
- value, self.__nativeToString (data, prop.dbFullType))
+ record = resultSet.nextRecord ()
- rec = rs.nextRecord ()
-
# ---------------------------------------------------------------------------
# Convert a native python object to a string according to datatype
# ---------------------------------------------------------------------------
@@ -280,9 +311,10 @@
def __nativeToString (self, native, datatype):
"""
This function creates a unicode string to be used in a <value>-tag of a GSD
- file. The native python object will be treated and theirfore converted as
+ file. The native python object will be treated and theirfore converted as
'datatype'.
"""
+
if datatype [:6] == "string" or datatype == "id":
checktype (native, [types.NoneType, types.UnicodeType])
@@ -293,12 +325,8 @@
return native
elif datatype [:6] == "number":
- if native is None:
- return "0"
- else:
- return str (native)
+ return native is None and "0" or str (native)
-
elif datatype == "boolean":
if native is not None and native:
return u'TRUE'
@@ -330,13 +358,411 @@
return str (native)
else:
- raise ValueError, u_("%s is not a valid datetime object") % repr
(native)
+ raise ValueError, \
+ u_("%s is not a valid datetime object") % repr (native)
else:
# must be reference property
return native.gnue_id
+
+ # ---------------------------------------------------------------------------
+ # fetch and remove all 'filter'-like parameters from the command line
+ # ---------------------------------------------------------------------------
+
+ def __getFilterParams (self):
+ """
+ This function iterates over the command line arguments, picks out all
+ elements with an equal sign and removes them from the arguments sequence
+ Such elements are of the form 'classname[.property]=value' where the
+ property part is optional. From all these elements a dictionary is built
+ where the 'classname'-part acts as key and the value is another dictionary
+ with 'property'-part as key an 'value' as it's value. If no 'property' is
+ given 'gnue_id' will be used.
+
+ @return: dictionary with filter-parameters and their requested values
+ """
+
+ result = {}
+
+ # First we catch all 'foo=bar' like arguments
+ for item in self.ARGUMENTS [:]:
+ if '=' in item:
+ (name, value) = item.split ('=')
+
+ if not len (name):
+ raise StartupError, u_("Invalid command line argument '='")
+ if not len (value):
+ raise StartupError, \
+ u_("Filter '%s' started, but no value given") % name
+
+ self.ARGUMENTS.remove (item)
+
+ # and put them into a dictionary
+ parts = name.strip ().split ('.', 1)
+ field = len (parts) == 1 and 'gnue_id' or parts [1]
+
+ # if a filter has more than one field
+ if not result.has_key (parts [0]):
+ result [parts [0]] = {}
+
+ result [parts [0]][field] = value
+
+ gDebug (1, "Filter-Params: %s" % result)
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Verify the requested filters
+ # ---------------------------------------------------------------------------
+
+ def __verifyFilters (self):
+ """
+ This function iterates over all available filters and creates a dictionary
+ with all filter-ids and their values.
+ @return: dictionary with gnue-id of the filter-class as key and the gnue-id
+ of the filter-value as value
+ """
+
+ result = {}
+ fNames = {}
+
+ # 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):
+ raise StartupError, u_("Filter class '%s' not found") % filterName
+
+ fc = self.sm.classes [filterName]
+ for field in data.keys ():
+ if not fc.properties.has_key (field):
+ raise StartupError, \
+ u_("Filter '%(class)s' has no property '%(property)s'") \
+ % {'class' : filterName,
+ 'property': field}
+
+ self.__filterParams [fc.gnue_id] = data
+ fNames [fc.gnue_id] = filterName
+ del self.__filterParams [filterName]
+
+ srvFilters = self.sm.getFilters (i18n.getuserlocale ())
+
+ for (filterId, fields, master, values) in srvFilters:
+ if self.__filterParams.has_key (filterId):
+ match = None
+
+ # if the master has not been defined, be nice and check if the user has
+ # set the filter-value by it's gnue_id. This will give us an apropriate
+ # master-value since gnue_id *must* be unique.
+ if master is not None and not result.has_key (master):
+ if self.__filterParams [filterId].has_key ('gnue_id'):
+ searchId = self.__filterParams [filterId]['gnue_id']
+ for (mk, vsec) in values.items ():
+ for cfield in vsec:
+ if cfield.has_key ('gnue_id') and \
+ cfield ['gnue_id'] == searchId:
+ match = searchId
+ # result [master] = mk
+ break
+ else:
+ masterKey = master is not None and result [master] or None
+
+ for item in values [masterKey]:
+ for (field, fieldValue) in self.__filterParams [filterId].items ():
+ if item.has_key (field) and item [field] == fieldValue:
+ match = item ['gnue_id']
+ break
+
+ if match is None:
+ raise StartupError, \
+ u_("No filter '%s' found matching the requested values") \
+ % fNames [filterId]
+
+ result [filterId] = match
+
+ gDebug (1, "Filters: %s" % result)
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Create a list of classes to be exported
+ # ---------------------------------------------------------------------------
+
+ def __createClassList (self, args):
+ """
+ This function creates a sequence of classnames to be dumped. This sequence
+ is in a proper order so no constraint-violations should occur.
+
+ @param args: list of classnames or modulenames to be exported
+ """
+
+ if not len (args):
+ if self.__useFilter:
+ for filterId in self.filters.keys ():
+ filterClass = self.sm.classes.find (filterId)
+ if not filterClass.fullName in args:
+ args.append (filterClass.fullName)
+
+ else:
+ for c in self.sm.classes.values ():
+ if c.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:
+ args.append (c.fullName)
+
+ self.__classes = {}
+ self.__fishes = {}
+
+ for item in args:
+ self.__addClass (item)
+
+ self.__refDict = copy.deepcopy (self.__classes)
+
+ result = []
+ add = self.__shrinkList (self.__classes, CircularReferenceError)
+ while len (add):
+ result.extend (add)
+ add = self.__shrinkList (self.__classes, CircularReferenceError)
+
+ return result
+
+
+
+ # ---------------------------------------------------------------------------
+ # add a class to the classlist and iterate over all references
+ # ---------------------------------------------------------------------------
+
+ def __addClass (self, className):
+ """
+ This function adds a class to the list of classes respecting all
+ dependencies given by class-references.
+ """
+
+ cDef = self.sm.classes [className]
+
+ # every class has a sequence of master-classes
+ if not self.__classes.has_key (className):
+ self.__classes [className] = []
+
+ # now add all master-classes to the dependancy list
+ for p in cDef.properties.values ():
+ if p.isReference:
+ refClass = p.referencedClass.fullName
+
+ if refClass == className:
+ if not self.__fishes.has_key (className):
+ self.__fishes [className] = []
+ self.__fishes [className].append (p.fullName)
+
+ elif not refClass in self.__classes [className]:
+ self.__classes [className].append (refClass)
+
+ if not self.__classes.has_key (refClass):
+ self.__addClass (refClass)
+
+ if not self.OPTIONS ['include-details']:
+ return
+
+ # if 'include-details' is set, we've to add all detail-classes of the
+ # current class.
+ for cClass in self.sm.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):
+ self.__addClass (cClass.fullName)
+
+
+
+ # ---------------------------------------------------------------------------
+ # Return all items from the dictionary which have no dependencies
+ # ---------------------------------------------------------------------------
+
+ def __shrinkList (self, dataDict, circularError, *args):
+ """
+ This function returns a sequence of all keys without any dependencies.
+ If no such items were found but there are still entries in the dictionary
+ a CircularReferenceError will be raised.
+
+ @param dataDict: dictionary to extract items from. The values are sequences
+ with keys which are referencing to an item
+ @param circularError: exception class which will be raised if there are
+ circular references
+ @return: sequence of all keys which do not have any dependency
+ """
+
+ result = []
+
+ for (key, references) in dataDict.items ():
+ if not len (references):
+ # if an item has no dependencies add it to the result
+ result.append (key)
+
+ # remove it from all other entries it is referred to
+ for ref in dataDict.values ():
+ if key in ref:
+ ref.remove (key)
+
+ # and finally remove it from the dictionary
+ del dataDict [key]
+
+ # if no entry without a dependency was found, but there are still entries
+ # in the dictionary, they *must* have circular references
+ if not len (result) and len (dataDict.keys ()):
+ raise circularError, args
+
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Create a dictionary with conditions for classes
+ # ---------------------------------------------------------------------------
+
+ def __createConditionDicts (self):
+ """
+ This function creates a dictionary with sequences of condition-tuples for
+ all classes where every tuple represents an 'equal'-condition. To get the
+ final condition per class all tuples will be AND-connected.
+
+ Such a tuple has the following form:
+ (source-relation, souce-item, destination-relation, destination-item)
+
+ If destination-relation is None, destination-item is a field-value
+ otherwise it's a field-name.
+ Examples: (foo, bar, foobar, barbaz) means foo.bar = foobar.barbaz
+ (foo, bar, None, barbaz) means foo.bar = barbaz
+
+ @return: dictionary with conditions
+ """
+
+ result = {}
+
+ if not self.__useFilter:
+ return result
+
+ for className in self.exports:
+ classdef = self.sm.classes [className]
+
+ cond = []
+
+ # if a class is given as a filter create a direct condition
+ if self.filters.has_key (classdef.gnue_id):
+ cond = [(className, 'gnue_id', None, self.filters [classdef.gnue_id])]
+
+ else:
+ for p in classdef.properties.values ():
+ # add a condition if a reference property points to a class which has
+ # a condition already set. Otherwise there's no need to filter the
+ # class
+ if not p.isReference or \
+ not result.has_key (p.referencedClass.fullName):
+ continue
+
+ refClass = p.referencedClass.fullName
+ refClassId = p.referencedClass.gnue_id
+
+ if self.filters.has_key (refClassId):
+ dstRel = None
+ dstItem = self.filters [refClassId]
+
+ else:
+ dstRel = refClass
+ dstItem = 'gnue_id'
+
+ # if the reference is not a fishhook import the master's condition
+ if refClass != className:
+ cond.extend (result [refClass])
+
+ cond.append ((className, p.fullName, dstRel, dstItem))
+
+ # we do *not* add empty conditions to the dictionary
+ if len (cond):
+ result [className] = cond
+
+ gDebug (1, "Condition-Dict: %s" % result)
+ return result
+
+
+
+
+ # ---------------------------------------------------------------------------
+ # Create a new datasource for a table using a given field list
+ # ---------------------------------------------------------------------------
+
+ def __openSource (self, classdef, fieldList):
+ """
+ This function creates a new datasource for a table using a list of fields.
+ @param classdef: classdefinition to prepare a datasource for
+ @param fieldList: sequence with fieldnames
+
+ @return: tuple with the datasource and it's field list
+ """
+
+ className = classdef.fullName
+ alias = {classdef.table: ""}
+
+ # 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
+ 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
+ index += 1
+
+ # make sure the list of tables is sorted by alias
+ tl = [(al, name) for (name, al) in alias.items ()]
+ tl.sort ()
+ table = string.join (["%s %s" % (t, a.strip ()) for (a, t) in tl], ", ")
+
+ # add alias information to the field list
+ if len (alias [classdef.table]):
+ fieldList = ["%s.%s" % (alias [classdef.table], f) for f in fieldList
[:]]
+
+ # create a condition tree for joins and filters
+ 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)
+ if dstrel is None:
+ dType = 'const'
+ dValue = dstitem
+ else:
+ dType = 'field'
+ dValue = "%s.%s" % (alias [self.sm.classes [dstrel].table], dstitem)
+
+ c = GConditions.buildTreeFromList ( \
+ ['eq', ['field', sValue], [dType, dValue]])
+
+ if conditions is not None:
+ conditions = GConditions.combineConditions (conditions, c)
+ else:
+ conditions = c
+
+ result = GDataSource.DataSourceWrapper (connections = self.connections,
+ attributes = {'name' : "dts_%s" % table,
+ 'database' : self.sm._internalSession.database,
+ 'table' : table,
+ 'primarykey': 'gnue_id'},
+ fields = fieldList, unicodeMode = True)
+
+ if conditions is not None:
+ result.setCondition (conditions)
+
+ return (result, fieldList)
+
+
+
+
# =============================================================================
# Main program
# =============================================================================
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r6467 - trunk/gnue-appserver/src,
johannes <=