commit-gnue
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]