commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gnue/common/src __init__.py schema/GSParser.py ...


From: Jason Cater
Subject: gnue/common/src __init__.py schema/GSParser.py ...
Date: Fri, 06 Dec 2002 01:25:19 -0500

CVSROOT:        /cvsroot/gnue
Module name:    gnue
Changes by:     Jason Cater <address@hidden>    02/12/06 01:25:17

Modified files:
        common/src     : __init__.py 
        common/src/schema: GSParser.py 
        common/src/schema/scripter: Scripter.py 
        common/src/schema/scripter/processors: __init__.py base.py 
                                               oracle.py postgresql.py 

Log message:
        * Made scripter.py into a GClientApp (run with --help to see)
        * Added indexes (unique and non-unique)
        * Added primary key support
        * Added Oracle driver

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/__init__.py.diff?tr1=1.22&tr2=1.23&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/schema/GSParser.py.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/schema/scripter/Scripter.py.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/schema/scripter/processors/__init__.py.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/schema/scripter/processors/base.py.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/schema/scripter/processors/oracle.py.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/schema/scripter/processors/postgresql.py.diff?tr1=1.1&tr2=1.2&r1=text&r2=text

Patches:
Index: gnue/common/src/__init__.py
diff -c gnue/common/src/__init__.py:1.22 gnue/common/src/__init__.py:1.23
*** gnue/common/src/__init__.py:1.22    Tue Nov 19 20:01:36 2002
--- gnue/common/src/__init__.py Fri Dec  6 01:25:17 2002
***************
*** 31,37 ****
  #   4. Set _release = 0
  #   5. Commit to CVS
  
! _version = (0,4,2)
  _release = 0
  
  # Version will be of the form "1.1.2" if a release or "1.1.1.99" if in CVS
--- 31,37 ----
  #   4. Set _release = 0
  #   5. Commit to CVS
  
! _version = (0,5,0)
  _release = 0
  
  # Version will be of the form "1.1.2" if a release or "1.1.1.99" if in CVS
Index: gnue/common/src/schema/GSParser.py
diff -c gnue/common/src/schema/GSParser.py:1.13 
gnue/common/src/schema/GSParser.py:1.14
*** gnue/common/src/schema/GSParser.py:1.13     Tue Nov 12 20:43:43 2002
--- gnue/common/src/schema/GSParser.py  Fri Dec  6 01:25:17 2002
***************
*** 205,210 ****
--- 205,211 ----
                 'Required': 1,
                 'Typecast': GTypecast.name },
              'unique': {
+                'Default': 0, 
                 'Typecast': GTypecast.boolean } },
           'ParentTags':  ('indexes',) },
  
Index: gnue/common/src/schema/scripter/Scripter.py
diff -c gnue/common/src/schema/scripter/Scripter.py:1.1 
gnue/common/src/schema/scripter/Scripter.py:1.2
*** gnue/common/src/schema/scripter/Scripter.py:1.1     Sun Nov 10 17:06:34 2002
--- gnue/common/src/schema/scripter/Scripter.py Fri Dec  6 01:25:17 2002
***************
*** 19,39 ****
  # Copyright 2002 Free Software Foundation
  #
  # FILE:
! # Objects.py
  #
  # DESCRIPTION:
! # GObjects for the Schema definitions
  #
  # NOTES:
  #
  
  from gnue.common.schema import GSParser
  from gnue.common.FileUtils import openResource, dyn_import
  from gnue.common.GClientApp import GClientApp
  
  import sys
  import os
  
  class Scripter:
    def __init__(self, source, oldsource=None):
  
--- 19,202 ----
  # Copyright 2002 Free Software Foundation
  #
  # FILE:
! # Scripter.py
  #
  # DESCRIPTION:
! # Schema definition scripter
  #
  # NOTES:
+ # Beware the Scriptor() class -- it smells like a billy goat.
  #
  
+ from gnue.common import VERSION
  from gnue.common.schema import GSParser
  from gnue.common.FileUtils import openResource, dyn_import
  from gnue.common.GClientApp import GClientApp
+ from processors import vendors
  
  import sys
  import os
  
+ class ScripterRunner(GClientApp):
+   #
+   # GClientApp() overrides
+   #
+   VERSION = VERSION
+   COMMAND = "gnue-schema"
+   NAME = "GNUe Schema Scripter"
+   USAGE = "[options] file [old-schema]"
+   COMMAND_OPTIONS = [
+       [ 'drop_tables',None,'drop-tables', 0, None, None,
+           'Generate commands to drop relevant tables.'],
+       [ 'ignore_schema','S','no-create', 0, None, None,
+           'Do not generate schema creation code.'],
+       [ 'ignore_data','D','no-data', 0, None, None,
+           'Do not generate data insertion code.'],
+       [ 'upgrade_schema','u','upgrade-schema', 0, None, None,
+           'Generate code to upgrade an older version of a schema to '
+           'the recent version. You must specify a previous schema with on the 
'
+           'command line.'],
+       [ 'upgrade_data','U','upgrade-data', 0, None, None,
+           'Generate code to upgrade an older version of schema data to '
+           'the recent version. You must specify a previous schema with on the 
'
+           'command line.'],
+       [ 'list_vendors','l','list-vendors', 0, None, None,
+           'List all supported vendors.'],
+       [ 'output','o','output', 1, None, 'dest',
+           'The destination for the created schemas. 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.' ],
+       [ 'vendor','v','vendor', 1, 'all', 'vendor',
+           '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.'],
+       ]
+   SUMMARY = \
+      "GNUe Schema Scripter creates SQL files based on GNUe Schema 
Definitions."
+ 
+   #
+   # Run
+   #
+   def run(self):
+ 
+     globals().update(self.OPTIONS)
+ 
+     # List vendors, if requested
+     if list_vendors:
+       self.listVendors()
+       sys.exit()
+ 
+     upgrading = 0
+ 
+     # Do some sanity checks on the options
+     if upgrade_schema or upgrade_data:
+       upgrading = 1
+ 
+       if drop_tables:
+         self.handleStartupError('--drop-tables is not compatable with the '
+                '--upgrade-?? options. Unable to create an upgrade schema.')
+       try:
+         old_schema = self.ARGUMENTS[1]
+       except IndexError:
+         self.handleStartupError('An --upgrade-?? option was selected, but '
+                'only one source file was specified. Unable to create '
+                'an upgrade schema.')
+ 
+     elif drop_tables and ignore_schema:
+       # If we are dropping tables and ignoring schema,
+       # then we can't possibly want the data.
+       ignore_data = 1
+ 
+ 
+     if vendor.lower() == 'all':
+       vens = vendors
+ 
+     else:
+       vens = vendor.split(',')
+ 
+     if len(vens) > 1 and not os.path.isdir(output       ):
+       self.handleStartupError('--output cannot reference a file '
+                               'if multiple vendors are specified.')
+ 
+     # Assign input file
+     try:
+       schema = self.ARGUMENTS[0]
+       input = openResource(schema)
+     except IndexError:
+       self.handleStartupError('No source file was specified.')
+     except IOError:
+       self.handleStartupError('Unable to open requested file: %s' % schema)
+ 
+     print
+     scripter = Scripter(schema)
+     for ven in vens:
+       if not output:
+         outfile = self.getVendorName(ven) + '.sql'
+       elif os.path.isdir(output):
+         outfile = os.path.join(self.getVendorName(ven) + '.sql')
+       else:
+         outfile = output
+ 
+       try:
+         out = open(outfile,'w')
+       except IOError, mesg:
+         self.handleStartupError('Unable to open destination file: %s\n\n%s' % 
(outfile,mesg))
+ 
+       print "Writing schema to %s ..." % outfile
+ 
+       try:
+         scripter.writeSql(ven, out)
+       except:
+         print "WARNING: Unable to create a schema for %s" % ven
+         raise
+ 
+       out.close()
+ 
+   #
+   # Get a vendor name
+   #
+   def getVendorName(self, vendor):
+     return dyn_import('processors.%s' % vendor).name
+ 
+   #
+   # List Vendors
+   #
+   def listVendors(self):
+     header = "%s\nVersion %s" % (self.NAME, self.VERSION)
+     print
+     print header
+     print
+     print "Supported Database Vendors"
+     print "--------------------------"
+ 
+     modules = {}
+     maxsize = 0
+     for vendor in vendors:
+       maxsize = max(maxsize, len(vendor))
+       try:
+         modules[vendor] = dyn_import('processors.%s' % vendor)
+       except ImportError:
+         pass
+ 
+     srt = modules.keys()
+     srt.sort()
+     for vendor in srt:
+       print vendor.ljust(maxsize+4), modules[vendor].description
+ 
+     print
+ 
+ 
+ 
+ 
+ 
+ 
+ ############################################################
+ #
+ # The actual worker class
+ #
  class Scripter:
    def __init__(self, source, oldsource=None):
  
***************
*** 59,79 ****
        self._postfields = []
        self._pretable = []
        self._posttable = []
        object.walk(self._walkTable, tablename=object.name)
        self.destination.write(self.processor.createTable(object.name, 
self._fields + self._postfields, self._pretable, self._posttable))
        self.destination.write('\n\n')
  
    def _walkTable(self, object, tablename):
      if object._type == 'GSField':
!       exec "field, extra, pretable,posttable = 
self.processor.createField(object.name,tablename,self.processor.%s(object), 
object)" % object.type in locals()
!       if field:
!         self._fields.append(field)
!       if extra:
!         self._postfields += extra
!       if pretable:
!         self._pretable += pretable
!       if posttable:
!         self._posttable += posttable
  
  if __name__ == '__main__':
!   Scripter(sys.argv[1]).writeSql(sys.argv[2])
--- 222,267 ----
        self._postfields = []
        self._pretable = []
        self._posttable = []
+       self._pkfields = []
+       self._pkname = ""
        object.walk(self._walkTable, tablename=object.name)
+       if len(self._pkfields):
+         self._handlePK(object.name)
        self.destination.write(self.processor.createTable(object.name, 
self._fields + self._postfields, self._pretable, self._posttable))
        self.destination.write('\n\n')
  
    def _walkTable(self, object, tablename):
      if object._type == 'GSField':
!       exec 
"self._handlePrePost(self.processor.createField(object.name,tablename,self.processor.%s(object),
 object))" % object.type in locals()
!     elif object._type == 'GSPKField':
!       self._pkfields.append(object.name)
!     elif object._type == 'GSIndex':
!       self._indexfields = []
!       object.walk(self._walkIndex, tablename)
!       
self._handlePrePost(self.processor.createIndex(object.name,tablename,self._indexfields,
 object.unique))
! 
! 
!   def _walkIndex(self, object, tablename):
!     if object._type == 'GSIndexField':
!       self._indexfields.append(object.name)
! 
! 
!   def _handlePK(self, tablename):
!     
self._handlePrePost(self.processor.createPrimaryKey(self._pkname,tablename, 
self._pkfields))
! 
! 
!   # Butt-ugly stuff
!   def _handlePrePost(self, results):
!     field, extra, pretable, posttable = results
!     if field:
!       self._fields.append(field)
!     if extra:
!       self._postfields += extra
!     if pretable:
!       self._pretable += pretable
!     if posttable:
!       self._posttable += posttable
! 
  
  if __name__ == '__main__':
!   ScripterRunner().run()
Index: gnue/common/src/schema/scripter/processors/__init__.py
diff -c gnue/common/src/schema/scripter/processors/__init__.py:1.1 
gnue/common/src/schema/scripter/processors/__init__.py:1.2
*** gnue/common/src/schema/scripter/processors/__init__.py:1.1  Sun Nov 10 
17:06:34 2002
--- gnue/common/src/schema/scripter/processors/__init__.py      Fri Dec  6 
01:25:17 2002
***************
*** 0 ****
--- 1 ----
+ vendors = ['postgresql','oracle']
\ No newline at end of file
Index: gnue/common/src/schema/scripter/processors/base.py
diff -c gnue/common/src/schema/scripter/processors/base.py:1.1 
gnue/common/src/schema/scripter/processors/base.py:1.2
*** gnue/common/src/schema/scripter/processors/base.py:1.1      Sun Nov 10 
17:06:34 2002
--- gnue/common/src/schema/scripter/processors/base.py  Fri Dec  6 01:25:17 2002
***************
*** 38,43 ****
--- 38,49 ----
    COMMENT_END = ""
    COMMENT_SINGLELINE=1
  
+   def __init__(self):
+     self.prepare()
+ 
+   def prepare(self):
+     pass
+ 
    def number(self, attributes={}):
      raise "Unsupported datatype: number"
  
***************
*** 87,98 ****
      rv += "CREATE TABLE %s\n (" % name
      rv += string.join(fields,',\n  ') + ');\n'
      if posttable:
!       rv += string.join(posttable,';\n') + ';\n'
  
      return rv
  
  
    def createField(self, name, tablename, datatype, object):
      rv = '%s %s' % (name, datatype)
!     return rv
  
--- 93,117 ----
      rv += "CREATE TABLE %s\n (" % name
      rv += string.join(fields,',\n  ') + ');\n'
      if posttable:
!       rv += "\n" + string.join(posttable,'\n') + '\n'
  
      return rv
  
  
    def createField(self, name, tablename, datatype, object):
      rv = '%s %s' % (name, datatype)
!     return ([rv], None, None, None)
! 
! 
!   def createPrimaryKey(self, name, tablename, fields):
!     rv = 'PRIMARY KEY (%s)' % string.join(fields,', ')
!     return (None, [rv], None, None)
! 
! 
!   def createIndex(self, name, tablename, fields, unique):
!     rv = 'CREATE %sINDEX %s ON %s (%s);' % (unique and "UNIQUE " or "",
!                            name, tablename, string.join(fields,', '))
!     return (None, None, None, [rv])
! 
! 
  
Index: gnue/common/src/schema/scripter/processors/oracle.py
diff -c gnue/common/src/schema/scripter/processors/oracle.py:1.1 
gnue/common/src/schema/scripter/processors/oracle.py:1.2
*** gnue/common/src/schema/scripter/processors/oracle.py:1.1    Sun Nov 10 
17:06:34 2002
--- gnue/common/src/schema/scripter/processors/oracle.py        Fri Dec  6 
01:25:17 2002
***************
*** 1,4 ****
  
  name = "Oracle"
! description = "Oracle 7.x/8i/9i+"
  
--- 1,108 ----
  
  name = "Oracle"
! description = "Oracle (7.x/8i/9i+)"
! 
! from base import BaseProcessor
! import string
! 
! _PK_PRECISION = 10
! 
! class Processor(BaseProcessor):
! 
! 
!   COMMENT_BEGIN = "REM ** "
!   MAX_NAME_LENGTH = 31
! 
!   def prepare(self):
!     self.trigWhen = []
!     self.trigBody = []
! 
! 
!   def number(self, object):
!     if object.precision == 0:
!       return "number(%s)" % object.length
!     else:
!       return "number(%s,%s)" % (object.length + object.precision, 
object.precision)
! 
!   def string(self, object):
!     return "varchar2(%s)" % object.length
! 
!   def date(self, object):
!     return "date"
! 
!   def time(self, object):
!     return "date"
! 
!   def timestamp(self, object):
!     return "date"
! 
!   def text(self, object):
!     return "long"
! 
!   def key(self, object):
!     return "number(%s)" % _PK_PRECISION
! 
! 
!   def createField(self, name, tablename, datatype, object):
!     rv = '%s %s' % (name, datatype)
! 
!     posttable = []
!     pretable = []
!     trigWhen = self.trigWhen
!     trigBody = self.trigBody
! 
!     if object.defaultwith == "serial":
! 
!       sq = tablename + '_' + name + '_seq'
!       if len(sq) > self.MAX_NAME_LENGTH:
!         sq = tablename + "_seq_"
!         sq += str(object._parent._children.index(object))
!       if len(sq) > self.MAX_NAME_LENGTH:
!         sq = tablename + "_" + str(id(object)) + '_seq'
!       if len(sq) > self.MAX_NAME_LENGTH:
!         sq = 'seq_' + id(self)
! 
!       trigWhen.append('(new.%s is null)' % object.name)
!       trigBody.append('     IF :new.%s IS NULL THEN\n' % (object.name) + \
!                       '        SELECT %s.nextval INTO :new.%s FROM dual;\n' % 
(sq, object.name) + \
!                       '     END IF;')
! 
!       pretable.append ('CREATE SEQUENCE %s MAXVALUE %s NOCYCLE' % (sq, 
'9'*_PK_PRECISION))
! 
!     elif object.defaultwith == "timestamp":
!       sysdate = object.type == 'date' and "TRUNC(sysdate)" or "sysdate"
!       trigWhen.append('(new.%s is null)' % object.name)
!       trigBody.append('     IF :new.%s IS NULL then\n' % (object.name) + \
!                       '        :new.%s := %s;\n' % (object.name, sysdate) + \
!                       '     END IF;')
! 
!     elif hasattr(self,'default') and len(self.default):
!       rv += ' DEFAULT %s' % self.default
! 
!     if not object.nullable:
!       rv += ' NOT NULL'
! 
!     # Field def, Post-Field Def, Pre-Table command, Post-Table command
!     return (rv,None,pretable or None,posttable or None)
! 
!   def createTable(self, name, fields, pretable=[], posttable=[]):
!     trigWhen = self.trigWhen
!     trigBody = self.trigBody
!     if len(trigBody):
!       if len(trigWhen):
!         when = "  WHEN ( %s )\n" % (string.join(trigWhen,' OR\n         '))
!       else:
!         when = ""
! 
!       posttable.append ('CREATE OR REPLACE TRIGGER t__%s__pre\n' % name + \
!                         '  BEFORE INSERT ON %s\n' % name + \
!                         '  FOR EACH ROW\n' + \
!                         when + \
!                         '  BEGIN\n' + \
!                         string.join(trigBody,'\n') + '\n' +\
!                         '  END;\n/\n')
! 
!     self.prepare()
! 
!     return BaseProcessor.createTable(self, name, fields, pretable, posttable)
  
Index: gnue/common/src/schema/scripter/processors/postgresql.py
diff -c gnue/common/src/schema/scripter/processors/postgresql.py:1.1 
gnue/common/src/schema/scripter/processors/postgresql.py:1.2
*** gnue/common/src/schema/scripter/processors/postgresql.py:1.1        Sun Nov 
10 17:06:34 2002
--- gnue/common/src/schema/scripter/processors/postgresql.py    Fri Dec  6 
01:25:17 2002
***************
*** 31,37 ****
  from base import BaseProcessor
  
  name = "PostgreSQL"
! description = "Oracle 7.x/8i/9i+"
  
  
  class Processor(BaseProcessor):
--- 31,37 ----
  from base import BaseProcessor
  
  name = "PostgreSQL"
! description = "PostgreSQL (6.x/7.x)"
  
  
  class Processor(BaseProcessor):




reply via email to

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