[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5921 - trunk/gnue-appserver/src/gcd
From: |
johannes |
Subject: |
r5921 - trunk/gnue-appserver/src/gcd |
Date: |
Wed, 7 Jul 2004 17:14:02 -0500 (CDT) |
Author: johannes
Date: 2004-06-21 13:14:44 -0500 (Mon, 21 Jun 2004)
New Revision: 5921
Modified:
trunk/gnue-appserver/src/gcd/GCParser.py
trunk/gnue-appserver/src/gcd/__init__.py
trunk/gnue-appserver/src/gcd/gcd2sql.py
Log:
gnue-gcd2sql now uses the new schema-creation, which means gcd's are sent to
the backend driver directly. Now extending classes should work well
Property changes on: trunk/gnue-appserver/src/gcd/GCParser.py
___________________________________________________________________
Name: svn:keywords
- +Id
+ Id
Property changes on: trunk/gnue-appserver/src/gcd/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: trunk/gnue-appserver/src/gcd/gcd2sql.py
===================================================================
--- trunk/gnue-appserver/src/gcd/gcd2sql.py 2004-06-21 18:11:52 UTC (rev
5920)
+++ trunk/gnue-appserver/src/gcd/gcd2sql.py 2004-06-21 18:14:44 UTC (rev
5921)
@@ -19,7 +19,7 @@
# write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
-# $Id: $
+# $Id$
import sys
import os
@@ -27,19 +27,33 @@
from gnue.common.apps import i18n
from gnue.common.apps.GClientApp import *
-from gnue.common.utils.FileUtils import openResource, dyn_import
+from gnue.common.utils.FileUtils import openResource
+from gnue.common.datasources import GDataSource, GConditions
from gnue.appserver import VERSION
from gnue.appserver.gcd import GCParser
-from gnue.common.schema.scripter.processors import vendors as VENDORS
-from gnue.common.schema.scripter import Definition
-from gnue.common.schema import Objects
-from gnue.common.definitions.GParserHelpers import GContent
+# =============================================================================
+# Exceptions
+# =============================================================================
+class Error (gException):
+ pass
+
+class ModuleNotFoundError (Error):
+ def __init__ (self, module):
+ msg = u_("Module '%s' not found in class repository") % module
+ Error.__init__ (self, msg)
+
+class ProcedureNotFoundError (Error):
+ def __init__ (self, procedure):
+ msg = u_("Procedure '%s' not found in class repository") % procedure
+ Error.__init__ (self, msg)
+
+
# =============================================================================
-# Generate SQL from GNUe Class Definition files
+# Update a database schema from GNUe Class Definitions and update classrep.
# =============================================================================
class gcdConverter (GClientApp):
@@ -49,36 +63,24 @@
COMMAND = "gcd2sql"
USAGE = "%s %s" % (GClientApp.USAGE, " [OPTIONS] file")
SUMMARY = _(
-"""A tool to create a SQL script from a GNUe Class Definition (gcd) file""")
+"""Create or update a database schema from a GNUe Class Definition (gcd) file
+and maintain data for all gnue_* classes""")
- _PROC_PATH = "gnue.common.schema.scripter.processors.%s"
- _GNUE_MODULE_ID = '0' * 32
-
-
# ---------------------------------------------------------------------------
# Constructor
# ---------------------------------------------------------------------------
def __init__ (self, connections = None):
- self.addCommandOption ('vendor', 'v', default = 'all', argument = 'vendor',
- help = _("The vendor to create a script for. If <vendor> is 'all',
then"
- " scripts for all supported vendors will be created. <vendor>
"
- "can also be a comma-separated list."))
+ self.addCommandOption ('connection', 'c', argument='connectionname',
+ help = _("Use the connection <connectionname> for creating the
schema"))
- self.addCommandOption('encoding', 'e', default='UTF-8', \
- argument = _('encoding'),
- help = _("The generated SQL script will be encoded using <encoding>. "
- "Default encoding is UTF-8") )
+ self.addCommandOption ('output','o', argument='filename',
+ help = _("Also send the code for creating the schema to this file."))
- self.addCommandOption ('output', 'o', argument = 'dest',
- help= _("The destination for the created files. This can be in several
"
- "formats. If <dest> is a file name, then output is written to "
- "this file. If <dest> is a directory, then <dest>/<Vendor>.sql
"
- "is created. The default is to create <Vendor>.sql in the "
- "current directory. "
- "NOTE: the first form (<dest> as a filename) "
- "is not supported for --vendors all."))
+ self.addCommandOption ('file-only', 'f', default = False,
+ help = _("If this flag is set, only code is sent to the output file "
+ "and the schema is not created automatically."))
ConfigOptions = {}
@@ -86,130 +88,90 @@
# ---------------------------------------------------------------------------
- # Print a message to stdout, if output is sent to a file
- # ---------------------------------------------------------------------------
- def __message (self, text):
- if self.__filename:
- print text
-
-
- # ---------------------------------------------------------------------------
# Verify the given commandline options
# ---------------------------------------------------------------------------
- def __check_options (self):
+ def __checkOptions (self):
+ """
+ This function checks wether the given command line arguments and options
+ are usefull or not.
+ """
self._args = [unicode (a, i18n.encoding) for a in self.ARGUMENTS]
- # do we have an accessible input file
if not len (self._args):
self.handleStartupError (_("No input file specified."))
- if len (self._args) > 1:
- self.handleStartupError (_("Too much input files specified."))
-
try:
- self._input = openResource (self._args [0])
+ self._files = []
+ for filename in self._args:
+ self._files.append (openResource (filename))
+
except IOError:
- self.handleStartupError (u_("Unable to open input file %s") % \
- self._args [0])
+ self.handleStartupError (_("Unable to open input file %s.") % filename)
- # check the specified vendors
- self._vendors = []
- if self.OPTIONS ['vendor'].lower () == 'all':
- self._vendors.extend (VENDORS)
- else:
- self._vendors.extend (self.OPTIONS ['vendor'].split (','))
- self._output = self.OPTIONS ['output']
- if len (self._vendors) > 1 and self._output is not None:
- if not os.path.isdir (self._output):
- self.handleStartupError (_("If multiple vendors are specified "
- "--output must be a directory or\n left empty."))
+ if not self.OPTIONS ['connection']:
+ self.handleStartupError (_("No connection specified."))
- # ---------------------------------------------------------------------------
- # Main program
- # ---------------------------------------------------------------------------
+ self.outfile = self.OPTIONS ['output']
- def run (self):
- self.__check_options ()
+ if self.OPTIONS ['file-only'] and self.outfile is None:
+ self.handleStartupError (_("Output to file only requested, but no "
+ "filename specified."))
- try:
- self.schema = GCParser.loadFile (self._input)
- except:
- print sys.exc_info () [1]
- sys.exit (1)
-
- for vendor in self._vendors:
- self._transform (vendor)
-
-
# ---------------------------------------------------------------------------
- # Transform the GCD tree to a given vendors' SQL
+ # Main program
# ---------------------------------------------------------------------------
-
- def _transform (self, vendor):
- aModule = dyn_import (self._PROC_PATH % vendor)
- if not self._output:
- filename = "%s.sql" % aModule.name
+ def run (self):
+ """
+ This is the main function of the whole process. It verifies the given
+ options, loads all schema definitions and then logs into the connection to
+ perform all actions requested.
+ """
- elif os.path.isdir (self._output):
- filename = os.path.join (self._output, "%s.sql" % aModule.name)
+ self.__checkOptions ()
- else:
- filename = self._output
-
try:
- self.destination = open (filename, 'w')
+ self.tables = []
+ self.modules = {}
+ self.classes = {}
+ self.properties = {}
+ self.procedures = {}
+ self.parameters = {}
- except IOError:
- sys.stderr.write (u_("Unable to create output file %s" % filename))
- sys.stderr.write (sys.exc_info () [1])
- sys.exit (1)
+ for item in range (len (self._files)):
+ print _("Loading gcd file '%s' ...") % self._args [item]
- self.processor = aModule.Processor (self.destination, self._args [0])
+ try:
+ schema = GCParser.loadFile (self._files [item])
+ schema.walk (self.__iterateObjects)
- print u_("Writing schema to %s ...") % filename
+ finally:
+ self._files [item].close ()
- try:
- self.tables = {}
- self.data = {}
- self.module = None
+ except Exception:
+ print sys.exc_info () [1]
- self.processor.startDump ()
- self.processor.client_encoding (self.OPTIONS ['encoding'])
+ else:
+ self.executeAndGenerateCode ()
- self.schema.walk (self.__iterateObjects)
+ self.updateRepository ()
- maxPhase = 0
- for table in self.tables.values ():
- maxPhase = max (maxPhase, max (table.phases.keys ()))
- for phase in range (0, maxPhase + 1):
- for table in self.tables.values ():
- self.processor.writePhase (table, phase)
-
- for table in ['gnue_module', 'gnue_class', 'gnue_property', \
- 'gnue_procedure', 'gnue_parameter']:
- if self.data.has_key (table):
- self.processor.writeData (self.data [table])
-
- self.processor.finishDump ()
-
- self.destination.close ()
-
- except:
- os.unlink (filename)
- raise
-
-
# ---------------------------------------------------------------------------
# Iterate over all top level elements
# ---------------------------------------------------------------------------
def __iterateObjects (self, sObject):
+ """
+ This function iterates over all objects of a GCD tree and processes the
+ GCModule and GCClass instances.
+
+ @param sObject: current GCD object to be processed
+ """
if sObject._type == 'GCModule':
self.__translateModule (sObject)
@@ -223,182 +185,520 @@
# ---------------------------------------------------------------------------
def __translateModule (self, aModule):
- self.module = aModule
- aModule.gnue_id = self.__generateId ()
+ """
+ This function adds a dictionary for the given module to the modules data
+ block for later update of the class repository.
- data = [('gnue_id', 'string', aModule.gnue_id),
- ('gnue_name', 'string', aModule.name)]
+ @param aModule: GCD Module object to be processed.
+ """
- if hasattr (aModule, 'comment'):
- data.append (('gnue_comment', 'string', aModule.comment))
+ self.modules [aModule.name] = self.fetchTags (aModule, ['name', 'comment'])
+ self.modules [aModule.name] ['gnue_id'] = None
- self.__addData ('gnue_module', data)
-
# ---------------------------------------------------------------------------
# A class translation needs a table creation/modification and a data entry
# ---------------------------------------------------------------------------
def __translateClass (self, aClass):
- aTable = Definition.TableDefinition (aClass.fullName, aClass.action)
- self.tables [aTable.name] = aTable
+ """
+ This function creates an entry for schema creation of the given class, as
+ well as a dictionary for the class repository update.
- if aClass.action == 'create':
- # New classes get a primary key for the gnue_id column
- primaryKey = aTable.addPrimaryKey ('gnue_id_pk_%s' % aClass.fullName)
- pkField = Objects.GSPKField (None)
- pkField.name = 'gnue_id'
- primaryKey.fields.append (pkField)
+ @param aClass: GCD Class object to be processed.
+ """
- # Add this new class to the data dictionary
- aClass.gnue_id = self.__generateId ()
+ self.tables.append ({'name': aClass.fullName, 'fields': []})
- data = [('gnue_id' , 'string', aClass.gnue_id),
- ('gnue_module', 'string', self.module.gnue_id),
- ('gnue_name' , 'string', aClass.name)]
+ if aClass.action == 'create':
+ self.tables [-1]['primarykey'] = {
+ 'name' : 'gnue_id_pk_%s' % aClass.fullName,
+ 'fields': ['gnue_id']}
- if hasattr (aClass, 'comment'):
- data.append (('gnue_comment', 'string', aClass.comment))
+ cDef = self.fetchTags (aClass, ['name', 'module', 'comment'])
+ cDef ['gnue_id'] = None
- self.__addData ('gnue_class', data)
- else:
- aClass.gnue_id = '---unknown---'
+ self.classes [aClass.fullName] = cDef
# After processing the class definition, iterate over all it's items
- aClass.walk (self.__iterateClassObjects, cClass = aClass, tableDef =
aTable)
+ aClass.walk (self.__iterateClassObjects, defs = self.tables [-1])
- self.processor.translateTableDefinition (aTable)
-
# ---------------------------------------------------------------------------
# Iterate over all elements of a class definition
# ---------------------------------------------------------------------------
- def __iterateClassObjects (self, sObject, cClass, tableDef):
+ def __iterateClassObjects (self, sObject, defs):
+ """
+ This function processes all child objects of a GCD class instance. For all
+ properties a schema creation dictionary will be created. Properties,
+ Procedures and Parameters will be added to the class repository update
+ dictionaries.
+
+ @param sObject: current GCD object to be processed
+ @param defs: schema creation dictionary describing the table definition for
+ the class.
+ """
+
if sObject._type == 'GCProperty':
- # Add a field to the table definition
- item = Objects.GSField (None)
- item.name = sObject.fullName
- item.type = sObject.datatype
+ fDef = {'name' : sObject.fullName,
+ 'type' : sObject.datatype,
+ 'nullable': sObject.nullable}
+
if sObject.length is not None and sObject.length:
- item.length = sObject.length
- item.precision = sObject.scale or 0
- item.nullable = sObject.nullable
- item.defaultwith = 'constant'
- if hasattr (sObject, 'comment'):
- item.description = sObject.comment
+ fDef ['length'] = sObject.length
+ if sObject.scale is not None and sObject.scale:
+ fDef ['precision'] = sObject.scale
- tableDef.fields.append (item)
+ defs ['fields'].append (fDef)
# Create a foreign key constraint for class references
if sObject.isReference:
- cName = "%s_%s_fk" % (cClass.fullName, sObject.type)
- constraint = tableDef.newConstraint (cName, 'foreignkey')
- constraint.reftable = sObject.type
- constraint.fields.append (item)
- ref = Objects.GSField (None)
- ref.name = 'gnue_id'
- constraint.reffields.append (ref)
+ cDef = {'name' : "%s_%s_fk" % (defs ['name'], sObject.type),
+ 'fields' : [fDef ['name']],
+ 'reftable' : sObject.type,
+ 'reffields': ['gnue_id']}
- # Create an entry for the gnue_property table
- if sObject.fullName == 'gnue_id':
- moduleId = self._GNUE_MODULE_ID
+ if not defs.has_key ('constraints'):
+ defs ['constraints'] = [cDef]
+ else:
+ defs ['constraints'].append (cDef)
+
+ fqName = "%s.%s" % (sObject._parent.fullName, sObject.fullName)
+ propDef = self.fetchTags (sObject, ['name', 'length', 'scale',
+ 'nullable', 'comment'])
+ if sObject.isReference:
+ propDef ['gnue_type'] = sObject.type
+ propDef ['gnue_length'] = None
+
+ elif sObject.fullName == 'gnue_id':
+ propDef ['gnue_type'] = 'id'
+ propDef ['gnue_length'] = None
else:
- moduleId = self.module.gnue_id
+ propDef ['gnue_type'] = sObject.datatype
- data = [('gnue_id' , 'string' , self.__generateId ()),
- ('gnue_module' , 'string' , moduleId),
- ('gnue_class' , 'string' , cClass.gnue_id),
- ('gnue_name' , 'string' , sObject.name),
- ('gnue_nullable', 'boolean', sObject.nullable)]
+ propDef ['gnue_id'] = None
+ propDef ['gnue_class'] = sObject._parent.fullName
+ propDef ['gnue_module'] = sObject.module
+ self.properties [fqName] = propDef
- if sObject.isReference:
- data.append (('gnue_type' , 'string' , sObject.type))
+
+ # Process a procedure of the class
+ elif sObject._type == 'GCProcedure':
+ fqName = "%s.%s" % (sObject._parent.fullName, sObject.fullName)
+ pDef = self.fetchTags (sObject, ['name', 'module', 'nullable',
+ 'language', 'length', 'scale', 'comment'])
+ pDef ['gnue_id'] = None
+ pDef ['gnue_class'] = sObject._parent.fullName
+ pDef ['gnue_type'] = sObject.datatype
+ pDef ['gnue_code'] = sObject.getChildrenAsContent ()
+ self.procedures [fqName] = pDef
+
+ sObject.walk (self.__iterateProcedure)
+
+
+ # ---------------------------------------------------------------------------
+ # Iterate over all child elements of a procedure
+ # ---------------------------------------------------------------------------
+
+ def __iterateProcedure (self, sObject):
+ """
+ This function processes any parameter definitions for a GCD procedure
+ instance. A dictionary for class repository update will be created.
+
+ @param sObject: the GCD parameter object to be processed
+ """
+ if sObject._type == 'GCParameter':
+ pDef = self.fetchTags (sObject, ['name', 'comment', 'length', 'scale'])
+ pDef ['gnue_type'] = sObject.datatype
+ pDef ['gnue_procedure'] = "%s.%s" % (sObject._parent._parent.fullName,
+ sObject._parent.fullName)
+ fqName = "%s.%s" % (pDef ['gnue_procedure'], sObject.name)
+ self.parameters [fqName] = pDef
+
+
+ # ---------------------------------------------------------------------------
+ # Get a dictionary with all keys listed in tags and values from sObject
+ # ---------------------------------------------------------------------------
+
+ def fetchTags (self, sObject, tags):
+ """
+ This function creates a dictionary with all attributes from sObject listed
+ in tags, where the keys are constructed by 'gnue_%s' % attributename.
+
+ @param sObject: Schema object to retriev attributes from
+ @param tags: list of all attributes to retrieve
+ @return: dictionary with the attribute names as keys and their values
+ """
+ res = {}
+ for item in tags:
+ if hasattr (sObject, item):
+ res ["gnue_%s" % item] = getattr (sObject, item)
+ return res
+
+
+ # ---------------------------------------------------------------------------
+ # Execute and generate the code
+ # ---------------------------------------------------------------------------
+
+ def executeAndGenerateCode (self):
+ """
+ This function logs into the given connection and calls it for an update of
+ it's schema according to the loaded table definitions. Additionally the
+ schema creation code is generated by this call, which will be stored in the
+ given output file (if requested by options).
+ """
+
+ connection = self.connections.getConnection (self.OPTIONS ['connection'],
+ login = True)
+
+ print _("Updating schema ...")
+ code = connection.updateSchema (self.tables, self.OPTIONS ['file-only'])
+
+ if self.outfile is not None:
+ dest = open (self.outfile, 'w')
+
+ for item in code:
+ for line in item:
+ dest.write (line + "\n")
+
+ dest.close ()
+
+
+ # ---------------------------------------------------------------------------
+ # Update the class repository
+ # ---------------------------------------------------------------------------
+
+ def updateRepository (self):
+ print _("Updating class repository ...")
+
+ self._updateModules ()
+ self._updateClasses ()
+ self._updateProperties ()
+ self._updateProcedures ()
+ self._updateParameter ()
+
+
+ # ---------------------------------------------------------------------------
+ # Update/add modules to the class repository
+ # ---------------------------------------------------------------------------
+
+ def _updateModules (self):
+ """
+ """
+ attributes = {'name' : "dts_gnueModule",
+ 'database': self.OPTIONS ['connection'],
+ 'table' : 'gnue_module'}
+ fieldList = ['gnue_id', 'gnue_name', 'gnue_comment']
+
+ self._dtsModules = GDataSource.DataSourceWrapper (
+ connections = self.connections,
+ attributes = attributes,
+ fields = fieldList,
+ unicodeMode = True)
+
+ stat = [0, 0, 0] # inserted, updated, unchanged
+
+ for module in self.modules.values ():
+ cond = GConditions.buildConditionFromDict ( \
+ {'gnue_name': module ['gnue_name']})
+ resultSet = self._dtsModules.createResultSet (cond)
+
+ if resultSet.firstRecord () is None:
+ resultSet.insertRecord ()
+ modifier = 0
+ module ['gnue_id'] = self.__generateId ()
else:
- data.append (('gnue_type' , 'string' , sObject.datatype))
+ module ['gnue_id'] = resultSet.current.getField ('gnue_id')
+ modifier = 1
+ if not self.doUpdate (resultSet, module):
+ modifier += 1
- if hasattr (sObject, 'comment'):
- data.append (('gnue_comment', 'string', sObject.comment))
- if sObject.length and not sObject.isReference:
- data.append (('gnue_length', 'number', sObject.length))
- if sObject.scale and not sObject.isReference:
- data.append (('gnue_scale', 'number', sObject.scale))
+ stat [modifier] += 1
- self.__addData ('gnue_property', data)
+ if stat [0] + stat [1]:
+ self.connections.commitAll ()
+ print _(" Modules : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
+ "unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
- elif sObject._type == 'GCProcedure':
- # Create an entry for the gnue_procedure table
- sObject.gnue_id = self.__generateId ()
- data = [('gnue_id' , 'string' , sObject.gnue_id),
- ('gnue_module' , 'string' , self.module.gnue_id),
- ('gnue_class' , 'string' , cClass.gnue_id),
- ('gnue_name' , 'string' , sObject.name),
- ('gnue_nullable', 'boolean', sObject.nullable),
- ('gnue_code' , 'string' , sObject.getChildrenAsContent ()),
- ('gnue_language', 'string' , sObject.language)]
-
- if sObject.datatype is not None:
- data.append (('gnue_type' , 'string' , sObject.datatype))
+ # ---------------------------------------------------------------------------
+ # Update/add classes to the class repository
+ # ---------------------------------------------------------------------------
- if hasattr (sObject, 'comment'):
- data.append (('gnue_comment', 'string', sObject.comment))
+ def _updateClasses (self):
+ """
+ """
+ attributes = {'name' : "dts_gnueClass",
+ 'database': self.OPTIONS ['connection'],
+ 'table' : 'gnue_class'}
+ fieldList = ['gnue_id', 'gnue_name', 'gnue_module', 'gnue_comment']
- if sObject.length:
- data.append (('gnue_length', 'number', sObject.length))
- if sObject.scale:
- data.append (('gnue_scale', 'number', sObject.scale))
+ datasource = GDataSource.DataSourceWrapper (
+ connections = self.connections,
+ attributes = attributes,
+ fields = fieldList,
+ unicodeMode = True)
- self.__addData ('gnue_procedure', data)
+ stat = [0, 0, 0] # inserted, updated, unchanged
- sObject.walk (self.__iterateProcObjects, cProc = sObject)
+ for klass in self.classes.values ():
+ cond = GConditions.buildConditionFromDict ( \
+ {'gnue_name': klass ['gnue_name'],
+ 'gnue_module': self.modules [klass ['gnue_module']]['gnue_id']})
+ resultSet = datasource.createResultSet (cond)
- def __iterateProcObjects (self, sObject, cProc):
- if sObject._type == 'GCParameter':
- sObject.gnue_id = self.__generateId ()
+ if resultSet.firstRecord () is None:
+ resultSet.insertRecord ()
+ modifier = 0
+ klass ['gnue_id'] = self.__generateId ()
+ else:
+ klass ['gnue_id'] = resultSet.current.getField ('gnue_id')
+ modifier = 1
- data = [('gnue_id' , 'string', sObject.gnue_id),
- ('gnue_procedure', 'string', cProc.gnue_id),
- ('gnue_name' , 'string', sObject.name)]
+ # replace the module's name by it's gnue_id
+ klass ['gnue_module'] = self.modules [klass ['gnue_module']] ['gnue_id']
- if hasattr (sObject, 'comment'):
- data.append (('gnue_comment', 'string', sObject.comment))
- if sObject.datatype:
- data.append (('gnue_type', 'string', sObject.datatype))
- if sObject.length:
- data.append (('gnue_length', 'number', sObject.length))
- if sObject.scale:
- data.append (('gnue_scale', 'number', sObject.scale))
+ if not self.doUpdate (resultSet, klass):
+ modifier += 1
- self.__addData ('gnue_parameter', data)
+ stat [modifier] += 1
+ if stat [0] + stat [1]:
+ self.connections.commitAll ()
+
+ print _(" Classes : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
+ "unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
+
+
# ---------------------------------------------------------------------------
- # Add a fields-tuple to the data-dictionary
+ # Update/add Properties to the class repository
# ---------------------------------------------------------------------------
- def __addData (self, table, fields):
- if not self.data.has_key (table):
- self.data [table] = Definition.DataDefinition (table)
+ def _updateProperties (self):
+ """
+ """
+ attributes = {'name' : "dts_gnueProperty",
+ 'database': self.OPTIONS ['connection'],
+ 'table' : 'gnue_property'}
+ fieldList = ['gnue_id', 'gnue_module', 'gnue_class', 'gnue_name',
+ 'gnue_type', 'gnue_length', 'gnue_scale', 'gnue_nullable',
+ 'gnue_comment']
- row = self.data [table].addRow ()
- for (name, datatype, value) in fields:
- item = Objects.GSValue (None)
- item.dataType = datatype
- item.value = value
+ datasource = GDataSource.DataSourceWrapper (
+ connections = self.connections,
+ attributes = attributes,
+ fields = fieldList,
+ unicodeMode = True)
- row.columns.append (name)
- row.values.append (item)
+ stat = [0, 0, 0] # inserted, updated, unchanged
+ for prop in self.properties.values ():
+ # make sure we have a valid gnue_id for the referenced module
+ if self.modules.has_key (prop ['gnue_module']):
+ moduleId = self.modules [prop ['gnue_module']] ['gnue_id']
+ else:
+ mc = GConditions.buildConditionFromDict ( \
+ {'gnue_name': prop ['gnue_module']})
+ rs = self._dtsModules.createResultSet (mc)
+ if rs.firstRecord () is None:
+ raise ModuleNotFoundError, (prop ['gnue_module'])
+ moduleId = rs.current.getField ('gnue_id')
+
+ cond = GConditions.buildConditionFromDict ( \
+ {'gnue_name' : prop ['gnue_name'],
+ 'gnue_module': moduleId,
+ 'gnue_class' : self.classes [prop ['gnue_class']] ['gnue_id']})
+ resultSet = datasource.createResultSet (cond)
+
+ if resultSet.firstRecord () is None:
+ resultSet.insertRecord ()
+ modifier = 0
+ prop ['gnue_id'] = self.__generateId ()
+ else:
+ prop ['gnue_id'] = resultSet.current.getField ('gnue_id')
+ modifier = 1
+
+ # replace module-name and class-name by their gnue_id's
+ prop ['gnue_module'] = moduleId
+ prop ['gnue_class'] = self.classes [prop ['gnue_class']] ['gnue_id']
+
+ if not self.doUpdate (resultSet, prop):
+ modifier += 1
+
+ stat [modifier] += 1
+
+ if stat [0] + stat [1]:
+ self.connections.commitAll ()
+
+ print _(" Properties: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
+ "unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
+
+
# ---------------------------------------------------------------------------
+ # Update/add Procedures to the class repository
+ # ---------------------------------------------------------------------------
+
+ def _updateProcedures (self):
+ attributes = {'name' : "dts_gnueProcedure",
+ 'database': self.OPTIONS ['connection'],
+ 'table' : 'gnue_procedure'}
+ fieldList = ['gnue_id', 'gnue_module', 'gnue_class', 'gnue_name',
+ 'gnue_type', 'gnue_length', 'gnue_scale', 'gnue_nullable',
+ 'gnue_comment', 'gnue_code', 'gnue_language']
+
+ self._dtsProcedure = GDataSource.DataSourceWrapper (
+ connections = self.connections,
+ attributes = attributes,
+ fields = fieldList,
+ unicodeMode = True)
+
+ stat = [0, 0, 0] # inserted, updated, unchanged
+
+ for proc in self.procedures.values ():
+
+ # make sure we have a valid gnue_id for the referenced module
+ if self.modules.has_key (proc ['gnue_module']):
+ moduleId = self.modules [proc ['gnue_module']] ['gnue_id']
+ else:
+ mc = GConditions.buildConditionFromDict ( \
+ {'gnue_name': proc ['gnue_module']})
+ rs = self._dtsModules.createResultSet (mc)
+ if rs.firstRecord () is None:
+ raise ModuleNotFoundError, (proc ['gnue_module'])
+ moduleId = rs.current.getField ('gnue_id')
+
+
+ cond = GConditions.buildConditionFromDict ( \
+ {'gnue_name' : proc ['gnue_name'],
+ 'gnue_module': moduleId,
+ 'gnue_class' : self.classes [proc ['gnue_class']] ['gnue_id']})
+ resultSet = self._dtsProcedure.createResultSet (cond)
+
+ if resultSet.firstRecord () is None:
+ resultSet.insertRecord ()
+ modifier = 0
+ proc ['gnue_id'] = self.__generateId ()
+ else:
+ proc ['gnue_id'] = resultSet.current.getField ('gnue_id')
+ modifier = 1
+
+ # replace module-name and class-name by their gnue_id's
+ proc ['gnue_module'] = moduleId
+ proc ['gnue_class'] = self.classes [proc ['gnue_class']] ['gnue_id']
+
+ if not self.doUpdate (resultSet, proc):
+ modifier += 1
+
+ stat [modifier] += 1
+
+ if stat [0] + stat [1]:
+ self.connections.commitAll ()
+
+ print _(" Procedures: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
+ "unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
+
+
+ # ---------------------------------------------------------------------------
+ # Update/add Procedures to the class repository
+ # ---------------------------------------------------------------------------
+
+ def _updateParameter (self):
+ attributes = {'name' : "dts_gnueParameter",
+ 'database': self.OPTIONS ['connection'],
+ 'table' : 'gnue_parameter'}
+ fieldList = ['gnue_id', 'gnue_procedure', 'gnue_name', 'gnue_type',
+ 'gnue_scale', 'gnue_length', 'gnue_comment']
+
+ self._dtsParameter = GDataSource.DataSourceWrapper (
+ connections = self.connections,
+ attributes = attributes,
+ fields = fieldList,
+ unicodeMode = True)
+
+ stat = [0, 0, 0] # inserted, updated, unchanged
+
+ for param in self.parameters.values ():
+
+ if self.procedures.has_key (param ['gnue_procedure']):
+ procId = self.procedures [param ['gnue_procedure']] ['gnue_id']
+ else:
+ raise ProcedureNotFoundError, (param ['gnue_procedure'])
+
+ cond = GConditions.buildConditionFromDict ( \
+ {'gnue_name' : param ['gnue_name'],
+ 'gnue_procedure': procId})
+ resultSet = self._dtsParameter.createResultSet (cond)
+
+ if resultSet.firstRecord () is None:
+ resultSet.insertRecord ()
+ modifier = 0
+ param ['gnue_id'] = self.__generateId ()
+ else:
+ param ['gnue_id'] = resultSet.current.getField ('gnue_id')
+ modifier = 1
+
+ # replace module-name and class-name by their gnue_id's
+ param ['gnue_procedure'] = procId
+
+ if not self.doUpdate (resultSet, param):
+ modifier += 1
+
+ stat [modifier] += 1
+
+ if stat [0] + stat [1]:
+ self.connections.commitAll ()
+
+ print _(" Parameters: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
+ "unchanged.") \
+ % {'ins': stat [0], 'upd': stat [1], 'kept': stat [2]}
+
+
+ # ---------------------------------------------------------------------------
+ # Perform an update on the given resultset using a given data dictionary
+ # ---------------------------------------------------------------------------
+
+ def doUpdate (self, resultSet, data):
+ """
+ This function sets all fields in the current record of the resultset base
+ on the key/values given by the data dictionary. It returns TRUE, if a field
+ value has been changed, otherwise FALSE. If a field was changed, the record
+ gets posted.
+
+ @param resultSet: resultset with the current record to be updated
+ @param data: dictionary with keys and values used for updates
+ @return: TRUE if a field has been changed, FALSE if no field has been
+ changed.
+ """
+ doPost = False
+
+ for key in data:
+ if resultSet.current.getField (key) != data [key]:
+ resultSet.current.setField (key, data [key])
+ doPost = True
+
+ if doPost:
+ resultSet.post ()
+
+ return doPost
+
+
+ # ---------------------------------------------------------------------------
# Generate a new object id
# ---------------------------------------------------------------------------
def __generateId (self):
-
- # TODO: need a better algorithm here
+ """
+ This function generates a new gnue_id like it is done by appserver. Once
+ this algorithm should be replace by a better one.
+ """
result = u''
for i in range (0, 32):
result = result + str (int (whrandom.random () * 10))
Property changes on: trunk/gnue-appserver/src/gcd/gcd2sql.py
___________________________________________________________________
Name: svn:keywords
- +Id
+ Id
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5921 - trunk/gnue-appserver/src/gcd,
johannes <=