Update of /cvsroot/webware/Webware/MiddleKit/Design
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9690/MiddleKit/Design
Modified Files:
PostgreSQLSQLGenerator.py SQLGenerator.py
Log Message:
Checked in improved PostgreSQL support. Use sequences for generating object serial
numbers.
Index: PostgreSQLSQLGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/PostgreSQLSQLGenerator.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** PostgreSQLSQLGenerator.py 7 Mar 2003 17:38:37 -0000 1.2
--- PostgreSQLSQLGenerator.py 27 Aug 2004 01:16:17 -0000 1.3
***************
*** 1,4 ****
from SQLGenerator import SQLGenerator
!
class PostgreSQLSQLGenerator(SQLGenerator):
--- 1,6 ----
from SQLGenerator import SQLGenerator
! from SQLGenerator import PrimaryKey as PrimaryKeyBase
! from MiscUtils.MixIn import MixIn
! import psycopg as dbi # psycopg adapter; apt-get install python2.2-psycopg
class PostgreSQLSQLGenerator(SQLGenerator):
***************
*** 7,11 ****
return 1
!
class Klasses:
--- 9,20 ----
return 1
! class Model:
! def writePostSamplesSQL(self, generator, output):
! # after inserting the samples, update the sequences with the highest
! # serial numbers we've seen for each class.
! for klass in self._allKlassesInOrder:
! if hasattr(klass, '_maxSerialNum') and klass._maxSerialNum > 0:
! output.write("select setval('%s', %d);" % ( klass.seqName(), klass._maxSerialNum))
!
class Klasses:
***************
*** 39,59 ****
class Klass:
def primaryKeySQLDef(self, generator):
! return '\t%s serial not null primary key,\n' % self.sqlIdName()
! ## AFAIK not supported
! #class EnumAttr:
! #
! # def sqlType(self):
! # enums = ['"%s"' % enum for enum in self.enums()]
! # enums = ', '.join(enums)
! # enums = 'enum(%s)' % enums
! # return enums
! #
! # def sampleValue(self, value):
! # assert value in self._enums, 'value = %r, enums = %r' % (value, self._enums)
! # return repr(value)
--- 48,89 ----
class Klass:
+ def writeCreateSQL(self, generator, out):
+ # create the sequences explicitly, just to be sure
+ wr = out.write
+ if not self.isAbstract():
+ wr('create sequence %s start 1 minvalue 1;\n\n' % self.seqName())
+ Klass.mixInSuperWriteCreateSQL(self, generator, out)
+ self.writePgSQLIndexDefs(wr)
+
+ def seqName(self):
+ return '%s_%s_seq' % (self.sqlTableName(), self.sqlSerialColumnName())
+
+ def writeIndexSQLDefs(self, wr):
+ # in postgres, indices must be created with 'create index' commands
+ pass
+
+ def writePgSQLIndexDefs(self, wr):
+ for attr in self.allAttrs():
+ if attr.get('isIndexed', 0) and attr.hasSQLColumn():
+ wr('create index %s_%s_index on %s (%s);\n' % (self.sqlTableName(), attr.sqlName(), self.sqlTableName(), attr.sqlName()))
+ wr('\n')
+
+
def primaryKeySQLDef(self, generator):
! return "\t%s integer not null primary key default nextval('%s'),\n" % (self.sqlSerialColumnName(), self.seqName())
! ## Enums are not supported directly by postgres, but we can emulate them
! ## using simple char columns.
! class EnumAttr:
!
! def sqlType(self):
! lengths = map( lambda value: len(value), self.enums())
! return 'varchar(%d)' % max(lengths)
!
! def sampleValue(self, value):
! assert value in self._enums, 'value = %r, enums = %r' % (value, self._enums)
! return repr(value)
***************
*** 74,77 ****
--- 104,134 ----
return 'varchar(%s)' % max
+ def sampleValue(self, value):
+ if value is None:
+ value = 'NULL'
+ else:
+ value = "%s" % dbi.QuotedString(value)
+ return value
+
+ class BoolAttr:
+
+ def sampleValue(self, value):
+ value = value.upper()
+ if value=='FALSE' or value=='NO':
+ value = 'TRUE'
+ elif value=='TRUE' or value=='YES':
+ value = 'FALSE'
+ else:
+ try:
+ value = int(value)
+ if value == 0:
+ value = 'FALSE'
+ elif value ==1:
+ value = 'TRUE'
+ except:
+ pass
+ assert value in ['TRUE','FALSE'], "'%s' is not a valid default for boolean column '%s'" % (value, self.name())
+ return value
+
class ObjRefAttr:
***************
*** 80,81 ****
--- 137,149 ----
# @@ 2001-02-04 ce: Is this standard SQL? If so, it can be moved up.
return 'bigint /* %s */' % self['Type']
+
+ class PrimaryKey:
+ def sampleValue(self,value):
+ # keep track of the highest serial number for each klass,
+ # so that we can update the database sequences
+ if int(value) > self._klass._maxSerialNum:
+ self._klass._maxSerialNum = int(value)
+ return value
+
+ # PrimaryKey is not a core class, so we have to mix this in manually.
+ MixIn(PrimaryKeyBase, PrimaryKey)
Index: SQLGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/SQLGenerator.py,v
retrieving revision 1.58
retrieving revision 1.59
diff -C2 -d -r1.58 -r1.59
*** SQLGenerator.py 25 Aug 2004 15:45:22 -0000 1.58
--- SQLGenerator.py 27 Aug 2004 01:16:17 -0000 1.59
***************
*** 139,142 ****
--- 139,144 ----
for line in samples:
file.write(line)
+
+ self.writePostSamplesSQL(generator, file)
file.close()
***************
*** 235,238 ****
--- 237,243 ----
return 1
+ def writePostSamplesSQL(self, generator, output):
+ pass
+
class Klasses:
***************
*** 873,876 ****
--- 878,887 ----
self._props = {'isDerived': 0}
+ # this stuff is for PostgreSQLSQLGenerator, but it is awkward
+ # to keep it there.
+ self._klass = klass
+ if not hasattr(klass, '_maxSerialNum'):
+ klass._maxSerialNum = 0
+
def name(self):
return self._name
|