Update of /cvsroot/webware/Webware/MiddleKit/Design
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18927/Design
Modified Files:
MSSQLSQLGenerator.py MySQLSQLGenerator.py PythonGenerator.py
SQLGenerator.py SQLPythonGenerator.py
Log Message:
- split obj ref SQL columns in two (class id and obj id)
- merge SQLGenerater.config into Settings.config
- see release notes for details
Index: MSSQLSQLGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/MSSQLSQLGenerator.py,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** MSSQLSQLGenerator.py 16 Feb 2004 22:14:52 -0000 1.15
--- MSSQLSQLGenerator.py 24 Feb 2004 02:04:13 -0000 1.16
***************
*** 85,89 ****
create table _MKClassIds (
! id bigint not null primary key,
name varchar(100)
)\ngo
--- 85,89 ----
create table _MKClassIds (
! id int not null primary key,
name varchar(100)
)\ngo
***************
*** 91,96 ****
wr('delete from _MKClassIds\n\n')
for klass in self._klasses:
! wr('insert into _MKClassIds (id, name) values\n')
! wr("\t(%s, '%s');\n" % (klass.id(), klass.name()))
wr('\ngo\n\n')
--- 91,96 ----
wr('delete from _MKClassIds\n\n')
for klass in self._klasses:
! wr('insert into _MKClassIds (id, name) values ')
! wr("(%s, '%s');\n" % (klass.id(), klass.name()))
wr('\ngo\n\n')
***************
*** 143,147 ****
# wr("print 'Creating table %s'\n" % name)
# wr('create table [%s] (\n' % name)
! # wr(' %s bigint primary key not null IDENTITY (1, 1),\n' % ljust(sqlIdName, self.maxNameWidth()))
# for attr in self.allAttrs():
--- 143,147 ----
# wr("print 'Creating table %s'\n" % name)
# wr('create table [%s] (\n' % name)
! # wr(' %s int primary key not null IDENTITY (1, 1),\n' % ljust(sqlIdName, self.maxNameWidth()))
# for attr in self.allAttrs():
***************
*** 167,171 ****
# print("print 'Creating table %s'\n" % name)
# print('create table [%s] (\n' % name)
! z = ' %s bigint primary key not null IDENTITY (1, 1),\n' % self.sqlIdName().ljust(self.maxNameWidth())
# print(z)
return z
--- 167,171 ----
# print("print 'Creating table %s'\n" % name)
# print('create table [%s] (\n' % name)
! z = ' %s int primary key not null IDENTITY (1, 1),\n' % self.sqlIdName().ljust(self.maxNameWidth())
# print(z)
return z
***************
*** 268,276 ****
def sqlType(self):
! if self.get('Ref',None):
! return 'bigint foreign key references %(Type)s(%(Type)sID) ' % self
else:
! return 'bigint /* relates to %s */ ' % self['Type']
!
--- 268,278 ----
def sqlType(self):
! if self.setting('UseBigIntObjRefColumns', False):
! if self.get('Ref', None):
! return 'bigint foreign key references %(Type)s(%(Type)sId) ' % self
! else:
! return 'bigint /* relates to %s */ ' % self['Type']
else:
! return 'int'
***************
*** 284,295 ****
def sqlType(self):
! return 'decimal(16,8)'
! # @@ 2001-04-26 dr: this (16,8) should be doable through your model
! # you should use the decimal attribute and max/numDecimalPlaces
! # float is supported for mySQL test compatibility
def sampleValue(self, value):
float(value) # raises exception if value is invalid
return value
-
-
--- 286,294 ----
def sqlType(self):
! return 'float'
! # return 'decimal(16,8)'
! # ^ use the decimal type instead
def sampleValue(self, value):
float(value) # raises exception if value is invalid
return value
Index: MySQLSQLGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/MySQLSQLGenerator.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** MySQLSQLGenerator.py 16 Feb 2004 22:14:52 -0000 1.11
--- MySQLSQLGenerator.py 24 Feb 2004 02:04:13 -0000 1.12
***************
*** 71,74 ****
def sqlType(self):
! # @@ 2001-02-04 ce: Is this standard SQL? If so, it can be moved up.
! return 'bigint unsigned /* %s */' % self['Type']
--- 71,76 ----
def sqlType(self):
! if self.setting('UseBigIntObjRefColumns', False):
! return 'bigint unsigned /* %s */' % self['Type']
! else:
! return 'int unsigned'
Index: PythonGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/PythonGenerator.py,v
retrieving revision 1.29
retrieving revision 1.30
diff -C2 -d -r1.29 -r1.30
*** PythonGenerator.py 16 Feb 2004 22:14:52 -0000 1.29
--- PythonGenerator.py 24 Feb 2004 02:04:13 -0000 1.30
***************
*** 16,24 ****
class PythonGenerator(CodeGenerator):
- def defaultConfig(self):
- return {
- 'DestDir': 'GeneratedPy',
- }
-
def generate(self, dirname):
self.requireDir(dirname)
--- 16,19 ----
Index: SQLGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/SQLGenerator.py,v
retrieving revision 1.39
retrieving revision 1.40
diff -C2 -d -r1.39 -r1.40
*** SQLGenerator.py 16 Feb 2004 22:42:13 -0000 1.39
--- SQLGenerator.py 24 Feb 2004 02:04:13 -0000 1.40
***************
*** 51,71 ****
return self.model().sqlDatabaseName()
- def configFilename(self):
- filename = self.model().filename()
- if filename is not None:
- filename = os.path.join(filename, 'SQLGenerator.config')
- return filename
-
- def defaultConfig(self):
- config = CodeGenerator.defaultConfig(self)
- config.update({
- 'PreSQL': '',
- 'PostSQL': '',
- 'DropStatements': 'database', # database, tables
- 'ExternalEnumsTableName': None, # '%(ClassName)s%(AttrName)sEnum'
- 'ExternalEnumsColumnName': 'name', # could use %(ClassName)s and %(AttrName)s
- })
- return config
-
def generate(self, dirname):
self.requireDir(dirname)
--- 51,54 ----
***************
*** 180,205 ****
except IndexError:
raise SampleError( linenum, "Couldn't find value for attribute '%s'" % attr.name() )
! value = value.strip()
! #print '>> (%s, %s)' % (value, attr)
! if value=='':
! value = attr.get('Default', None)
! if value is None:
! value = 'NULL'
! else:
! value = attr.sampleValue(value)
! elif value.lower()=='none':
! value = 'NULL'
! else:
! value = attr.sampleValue(value)
! # print 'Attr: %s, Value: %s' % (attr,value)
! value = str(value)
! if 0:
! if not isinstance(value, StringTypes):
! print 'attr:', attr
! print 'value:', value
! print 'type of value:', type(value)
! assert isinstance(value, StringTypes), value
! assert value # value cannot be blank
! values[i] = value
i += 1
#print
--- 163,168 ----
except IndexError:
raise SampleError( linenum, "Couldn't find value for attribute '%s'" % attr.name() )
! values[i] = attr.sqlForSampleInput(value)
! assert len(values[i])>0, repr(values[i]) # SQL value cannot be blank
i += 1
#print
***************
*** 326,332 ****
# assign the class ids up-front, so that we can resolve forward object references
self.assignClassIds(generator)
for klass in self._model._allKlassesInOrder:
klass.writeCreateSQL(self._sqlGenerator, out)
- self.writeClassIdsSQL(generator, out)
def writeClassIdsSQL(self, generator, out):
--- 289,295 ----
# assign the class ids up-front, so that we can resolve forward object references
self.assignClassIds(generator)
+ self.writeClassIdsSQL(generator, out)
for klass in self._model._allKlassesInOrder:
klass.writeCreateSQL(self._sqlGenerator, out)
def writeClassIdsSQL(self, generator, out):
***************
*** 465,493 ****
return not self.get('isDerived', 0)
! def sampleValue(self, value):
! """ Returns a string suitable for a SQL insert statement including any necessary SQL syntax. Subclasses should override to perform type checking and handle any special capabilities.
! The invoker of this method already strips preceding and trailing whitespace, as well detects blanks as NULLs.
! """
! # @@ 2001-02-20 ce: restructure this
! # sqlValue() instead of sampleValue()
! # w.s. stripping, blanks as default value, none as NULL
! # make _sqlValue()
! return value
def writeCreateSQL(self, generator, out):
try:
if self.hasSQLColumn():
! name = self.sqlName().ljust(self.maxNameWidth())
! if self.isRequired():
! notNullSQL = ' not null'
! else:
! notNullSQL = self.sqlNullSpec()
! if generator.sqlSupportsDefaultValues():
! defaultSQL = self.createDefaultSQL()
! if defaultSQL:
! defaultSQL = ' ' + defaultSQL
! else:
! defaultSQL = ''
! out.write('\t%s %s%s%s' % (name, self.sqlType(), notNullSQL, defaultSQL))
else:
out.write('\t/* %(Name)s %(Type)s - not a SQL column */' % self)
--- 428,450 ----
return not self.get('isDerived', 0)
! def sqlForSampleInput(self, input):
! input = input.strip()
! if input=='':
! input = self.get('Default', '')
! if input in (None, 'None', 'none'):
! return self.sqlForNone()
! else:
! return str(self.sqlForNonNoneSampleInput(input))
!
! def sqlForNone(self):
! return 'NULL'
!
! def sqlForNonNoneSampleInput(self, input):
! return input
def writeCreateSQL(self, generator, out):
try:
if self.hasSQLColumn():
! self.writeRealCreateSQLColumn(generator, out)
else:
out.write('\t/* %(Name)s %(Type)s - not a SQL column */' % self)
***************
*** 504,507 ****
--- 461,478 ----
raise
+ def writeRealCreateSQLColumn(self, generator, out):
+ name = self.sqlName().ljust(self.maxNameWidth())
+ if self.isRequired():
+ notNullSQL = ' not null'
+ else:
+ notNullSQL = self.sqlNullSpec()
+ if generator.sqlSupportsDefaultValues():
+ defaultSQL = self.createDefaultSQL()
+ if defaultSQL:
+ defaultSQL = ' ' + defaultSQL
+ else:
+ defaultSQL = ''
+ out.write('\t%s %s%s%s' % (name, self.sqlType(), notNullSQL, defaultSQL))
+
def writeAuxiliaryCreateTable(self, generator, out):
# most attribute types have no such beast
***************
*** 517,521 ****
if default.lower()=='none': # kind of redundant
default = None
! return 'default ' + str(self.sampleValue(default))
else:
return ''
--- 488,492 ----
if default.lower()=='none': # kind of redundant
default = None
! return 'default ' + str(self.sqlForSampleInput(default))
else:
return ''
***************
*** 528,534 ****
def sqlColumnName(self):
! """ Returns the SQL column name corresponding to this attribute, consisting of self.name() + self.sqlTypeSuffix(). """
if not self._sqlColumnName:
! self._sqlColumnName = self.name() # + self.sqlTypeSuffix()
return self._sqlColumnName
--- 499,509 ----
def sqlColumnName(self):
! """
! Returns the SQL column name corresponding to this attribute
! which simply defaults to the attribute's name. Subclasses may
! override to customize.
! """
if not self._sqlColumnName:
! self._sqlColumnName = self.name()
return self._sqlColumnName
***************
*** 540,546 ****
return 'bool'
! def sampleValue(self, value):
try:
! value = value.upper()
except:
pass
--- 515,521 ----
return 'bool'
! def sqlForNonNoneSampleInput(self, input):
try:
! value = input.upper()
except:
pass
***************
*** 558,564 ****
return 'int'
! def sampleValue(self, value):
! if not isinstance(value, int):
! value = str(value)
if value.endswith('.0'):
# numeric values from Excel-based models are always float
--- 533,539 ----
return 'int'
! def sqlForNonNoneSampleInput(self, input):
! if not isinstance(input, int):
! value = str(input)
if value.endswith('.0'):
# numeric values from Excel-based models are always float
***************
*** 574,580 ****
return 'bigint'
! def sampleValue(self, value):
! long(value) # raises exception if value is invalid
! return value
--- 549,555 ----
return 'bigint'
! def sqlForNonNoneSampleInput(self, input):
! long(input) # raises exception if value is invalid
! return input
***************
*** 583,592 ****
def sqlType(self):
return 'double precision'
- # @@ 2001-02-04 ce: this (8,8) stuff is bad,]
- # but haven't come up with solution yet
! def sampleValue(self, value):
! float(value) # raises exception if value is invalid
! return value
--- 558,565 ----
def sqlType(self):
return 'double precision'
! def sqlForNonNoneSampleInput(self, input):
! float(input) # raises exception if value is invalid
! return input
***************
*** 609,614 ****
return 'decimal(%s,%s)' % (precision, scale)
! def sampleValue(self, value):
! return value
--- 582,587 ----
return 'decimal(%s,%s)' % (precision, scale)
! def sqlForNonNoneSampleInput(self, input):
! return input
***************
*** 623,627 ****
raise AbstractError, self.__class__
! def sampleValue(self, value):
if value=="''":
value = ''
--- 596,601 ----
raise AbstractError, self.__class__
! def sqlForNonNoneSampleInput(self, input):
! value = input
if value=="''":
value = ''
***************
*** 645,650 ****
return self['Type'] # e.g., date, time and datetime
! def sampleValue(self, value):
! return repr(value)
--- 619,624 ----
return self['Type'] # e.g., date, time and datetime
! def sqlForNonNoneSampleInput(self, input):
! return repr(input)
***************
*** 652,664 ****
def sqlName(self):
! return self.name() + 'Id'
! # @@ 2001-02-04 ce: Is this standard SQL?
! #def sqlType(self):
! # return 'bigint unsigned /* %s */' % self['Type']
! def sampleValue(self, value):
! """ Obj ref sample data format is "Class.serialNum", such as "Thing.3". If the Class and period are missing, then the obj ref's type is assumed. """
! parts = value.split('.')
if len(parts)==2:
className = parts[0]
--- 626,682 ----
def sqlName(self):
! if self.setting('UseBigIntObjRefColumns', False):
! return self.name() + 'Id' # old way: one 64 bit column
! else:
! # new way: 2 int columns for class id and obj id
! name = self.name()
! classIdName, objIdName = self.setting('ObjRefSuffixes')
! classIdName = name + classIdName
! objIdName = name + objIdName
! return '%s,%s' % (classIdName, objIdName)
! def writeRealCreateSQLColumn(self, generator, out):
! if self.setting('UseBigIntObjRefColumns', False):
! # the old technique of having both the class id and the obj id in one 64 bit reference
! name = self.sqlName().ljust(self.maxNameWidth())
! if self.get('Ref', None):
! refs = ' references %(Type)s(%(Type)sId)' % self
! else:
! refs = ''
! if self.isRequired():
! notNull = ' not null'
! else:
! notNull = self.sqlNullSpec()
! out.write('\t%s %s%s%s' % (name, self.sqlType(), refs, notNull))
! else:
! # the new technique uses one column for each part of the obj ref: class id and obj id
! classIdName = self.name()+self.setting('ObjRefSuffixes')[0]
! classIdName = classIdName.ljust(self.maxNameWidth())
! objIdName = self.name()+self.setting('ObjRefSuffixes')[1]
! objIdName = objIdName.ljust(self.maxNameWidth())
! if self.isRequired():
! notNull = ' not null'
! else:
! notNull = self.sqlNullSpec()
! if self.get('Ref', None):
! objIdRef = ' references %(Type)s(%(Type)sId) ' % self
! else:
! objIdRef = ''
! out.write('\t%s %s%s references _MKClassIds,\n' % (classIdName, self.sqlType(), notNull))
! out.write('\t%s %s%s%s' % (objIdName, self.sqlType(), notNull, objIdRef))
! def sqlForNone(self):
! if self.setting('UseBigIntObjRefColumns', False):
! return 'NULL'
! else:
! return 'NULL,NULL'
!
! def sqlForNonNoneSampleInput(self, input):
! """
! Obj ref sample data format is "Class.serialNum", such as
! "Thing.3". If the Class and period are missing, then the obj
! ref's type is assumed.
! """
! parts = input.split('.')
if len(parts)==2:
className = parts[0]
***************
*** 666,675 ****
else:
className = self.className()
! objSerialNum = value
! # @@ 2000-11-24 ce: check that we're pointing to a legal class
klass = self.klass().klasses()._model.klass(className)
klassId = klass.id()
! objRef = objRefJoin(klassId, objSerialNum)
! return str(objRef)
--- 684,695 ----
else:
className = self.className()
! objSerialNum = input
klass = self.klass().klasses()._model.klass(className)
klassId = klass.id()
! if self.setting('UseBigIntObjRefColumns', False):
! objRef = objRefJoin(klassId, objSerialNum)
! return str(objRef)
! else:
! return '%s,%s' % (klassId, objSerialNum)
***************
*** 682,688 ****
return 0
! def sampleValue(self, value):
! # @@ 2000-11-24 ce: need specific extension?
! # @@ 2001-02-04 ce: ^^^ what does that mean???
raise Exception, 'Lists are implicit. They cannot have sample values.'
--- 702,706 ----
return 0
! def sqlForSampleInput(self, input):
raise Exception, 'Lists are implicit. They cannot have sample values.'
***************
*** 701,710 ****
return 'varchar(%s)' % maxLen
! def sampleValue(self, value):
if self.setting('ExternalEnumsTableName', None):
! return self.intValueForString(value)
else:
! assert value in self._enums, 'value = %r, enums = %r' % (value, self._enums)
! return repr(value)
def externalEnumsTableAndColumnName(self):
--- 719,728 ----
return 'varchar(%s)' % maxLen
! def sqlForNonNoneSampleInput(self, input):
if self.setting('ExternalEnumsTableName', None):
! return self.intValueForString(input)
else:
! assert input in self._enums, 'input=%r, enums=%r' % (input, self._enums)
! return repr(input)
def externalEnumsTableAndColumnName(self):
***************
*** 755,758 ****
return self._props.get(key,default)
! def sampleValue(self,value):
! return value
--- 773,776 ----
return self._props.get(key,default)
! def sqlForNonNoneSampleInput(self, input):
! return input
Index: SQLPythonGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/SQLPythonGenerator.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** SQLPythonGenerator.py 5 Nov 2002 07:39:28 -0000 1.3
--- SQLPythonGenerator.py 24 Feb 2004 02:04:13 -0000 1.4
***************
*** 36,40 ****
def writePyGet(self, out, names):
! out.write('''
def %(pyGetName)s(self):
if self._%(name)s is None:
--- 36,41 ----
def writePyGet(self, out, names):
! if self.setting('UseBigIntObjRefColumns', False):
! out.write('''
def %(pyGetName)s(self):
if self._%(name)s is None:
***************
*** 43,44 ****
--- 44,55 ----
return self._%(name)s
''' % names)
+ else:
+ classIdSuffix, objIdSuffix = self.setting('ObjRefSuffixes')
+ names.update(locals())
+ out.write('''
+ def %(pyGetName)s(self):
+ if self._%(name)s is None:
+ from %(package)s%(targetClassName)s import %(targetClassName)s
+ self._%(name)s = self._mk_store.fetchObjectsOfClass(%(targetClassName)s, clauses='where %(lowerSourceClassName)s%(classIdSuffix)s=%%i and %(lowerSourceClassName)s%(objIdSuffix)s=%%i' %% (self.klass().id(), self.serialNum()))
+ return self._%(name)s
+ ''' % names)
|