|
[Webware-checkins] CVS: Webware/MiddleKit/Design MSSQLSQLGenerator.py,1.20,1.21 SQLGenerator.py,1.56,1.57
From: Chuck Esterbrook <echuck@us...> - 2004-05-26 19:37
|
Update of /cvsroot/webware/Webware/MiddleKit/Design
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7559/Design
Modified Files:
MSSQLSQLGenerator.py SQLGenerator.py
Log Message:
MS SQL Server gives indexes and constraints incomprehensible names AND when constraints are violated, gives only the name (not the fields and values of the violation). sigh. So MK now gives explicit, understandable names to all such indexes and constraints.
Index: MSSQLSQLGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/MSSQLSQLGenerator.py,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** MSSQLSQLGenerator.py 3 Apr 2004 04:05:42 -0000 1.20
--- MSSQLSQLGenerator.py 26 May 2004 19:37:44 -0000 1.21
***************
*** 5,8 ****
--- 5,20 ----
+ def cleanConstraintName(name):
+ assert name
+ name = name.replace('[', '')
+ name = name.replace(']', '')
+ assert '[' not in name, name
+ assert ',' not in name, name
+ if len(name)>128:
+ raise Exception("name is %i chars long, but MS SQL Server only supports 128. this case is no currently handled. name=%r" % (
+ len(name), name))
+ return name
+
+
class MSSQLSQLGenerator(SQLGenerator):
***************
*** 142,147 ****
Returns a one liner that becomes part of the CREATE statement for creating the primary key of the table. SQL generators often override this mix-in method to customize the creation of the primary key for their SQL variant. This method should use self.sqlIdName() and often ljust()s it by self.maxNameWidth().
'''
! z = ' %s int primary key not null identity(1, 1),\n' % self.sqlSerialColumnName().ljust(self.maxNameWidth())
! return z
def sqlTableName(self):
--- 154,160 ----
Returns a one liner that becomes part of the CREATE statement for creating the primary key of the table. SQL generators often override this mix-in method to customize the creation of the primary key for their SQL variant. This method should use self.sqlIdName() and often ljust()s it by self.maxNameWidth().
'''
! constraintName = cleanConstraintName('PK__%s__%s' % (self.sqlTableName(), self.sqlSerialColumnName()))
! return ' %s int constraint [%s] primary key not null identity(1, 1),\n' % (
! self.sqlSerialColumnName().ljust(self.maxNameWidth()), constraintName)
def sqlTableName(self):
***************
*** 156,161 ****
if attr.boolForKey('isIndexed') and attr.hasSQLColumn():
unique = self.boolForKey('isUnique') and ' unique' or ''
! indexName = '%s_%s_index' % (self.name(), attr.name())
! wr('create%s index %s on %s(%s);\n' % (
unique, indexName, self.sqlTableName(), attr.sqlColumnName()))
wr('\n')
--- 169,174 ----
if attr.boolForKey('isIndexed') and attr.hasSQLColumn():
unique = self.boolForKey('isUnique') and ' unique' or ''
! indexName = cleanConstraintName('IX__%s__%s' % (self.name(), attr.name()))
! wr('create%s index [%s] on %s(%s);\n' % (
unique, indexName, self.sqlTableName(), attr.sqlColumnName()))
wr('\n')
***************
*** 185,188 ****
--- 198,209 ----
return '[' + self._sqlColumnName + ']'
+ def uniqueSQL(self):
+ """
+ Returns the SQL to use within a column definition to make it unique.
+ """
+ if not self.boolForKey('isUnique'):
+ return ''
+ return ' constraint [UQ__%s__%s] unique' % (self.klass().name(), self.name())
+
class DateTimeAttr:
***************
*** 209,212 ****
--- 230,244 ----
+ class EnumAttr:
+
+ def sqlType(self):
+ if self.usesExternalSQLEnums():
+ tableName, valueColName, nameColName = self.externalEnumsSQLNames()
+ constraintName = cleanConstraintName('FK__%s__%s__%s__%s' % (
+ self.containingKlass.sqlTableName(), self.sqlName(), tableName, valueColName))
+ return 'int constraint [%s] references %s(%s)' % (constraintName, tableName, valueColName)
+ else:
+ return self.nativeEnumSQLType()
+
class LongAttr:
***************
*** 241,245 ****
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']
--- 273,277 ----
if self.setting('UseBigIntObjRefColumns', False):
if self.get('Ref', None):
! return 'bigint constraint %s foreign key references %(Type)s(%(Type)sId) ' % self
else:
return 'bigint /* relates to %s */ ' % self['Type']
***************
*** 247,250 ****
--- 279,297 ----
return 'int'
+ def classIdReferences(self):
+ classIdName = self.sqlName().split(',')[0]
+ constraintName = cleanConstraintName('FK__%s__%s___MKClassIds__id' % (self.containingKlass.sqlTableName(), classIdName))
+ return ' constraint [%s] references _MKClassIds' % constraintName
+
+ def objIdReferences(self):
+ targetKlass = self.targetKlass()
+ objIdName = self.sqlName().split(',')[1]
+ constraintName = 'FK__%s__%s__%s__%s' % (
+ self.containingKlass.sqlTableName(), objIdName, targetKlass.sqlTableName(), targetKlass.sqlSerialColumnName())
+ constraintName = cleanConstraintName(constraintName)
+ return ' constraint [%s] references %s(%s) ' % (
+ constraintName, targetKlass.sqlTableName(), targetKlass.sqlSerialColumnName())
+
+
class ListAttr:
Index: SQLGenerator.py
===================================================================
RCS file: /cvsroot/webware/Webware/MiddleKit/Design/SQLGenerator.py,v
retrieving revision 1.56
retrieving revision 1.57
diff -C2 -d -r1.56 -r1.57
*** SQLGenerator.py 3 Apr 2004 04:05:42 -0000 1.56
--- SQLGenerator.py 26 May 2004 19:37:44 -0000 1.57
***************
*** 396,399 ****
--- 396,400 ----
nonSQLAttrs = []
for attr in self.allAttrs():
+ attr.containingKlass = self # as opposed to the declaring klass of the attr
if attr.hasSQLColumn():
sqlAttrs.append(attr)
***************
*** 413,416 ****
--- 414,420 ----
self.writeIndexSQLDefsAfterTable(wr)
wr('\n\n')
+ # cleanup
+ for attr in self.allAttrs():
+ attr.containingKlass = None
def primaryKeySQLDef(self, generator):
***************
*** 481,484 ****
--- 485,492 ----
def writeCreateSQL(self, generator, out):
+ """
+ The klass argument is the containing klass of the attribute which can be different than
+ the declaring klass.
+ """
try:
if self.hasSQLColumn():
***************
*** 514,519 ****
else:
defaultSQL = ''
! uniqueSQL = self.boolForKey('isUnique') and ' unique' or ''
! out.write('\t%s %s%s%s%s' % (name, self.sqlTypeOrOverride(), uniqueSQL, notNullSQL, defaultSQL))
def writeAuxiliaryCreateTable(self, generator, out):
--- 522,526 ----
else:
defaultSQL = ''
! out.write('\t%s %s%s%s%s' % (name, self.sqlTypeOrOverride(), self.uniqueSQL(), notNullSQL, defaultSQL))
def writeAuxiliaryCreateTable(self, generator, out):
***************
*** 563,566 ****
--- 570,579 ----
return self._sqlColumnName
+ def uniqueSQL(self):
+ """
+ Returns the SQL to use within a column definition to make it unique.
+ """
+ return self.boolForKey('isUnique') and ' unique' or ''
+
class BoolAttr:
***************
*** 718,730 ****
classIdDefault = ' default %s' % self.targetKlass().id()
# ^ this makes the table a little to easier to work with in some cases (you can often just insert the obj id)
- targetKlass = self.targetKlass()
if self.get('Ref', None) or \
! (self.setting('GenerateSQLReferencesForObjRefsToSingleClasses', False) and len(targetKlass.subklasses())==0):
! objIdRef = ' references %s(%s) ' % (targetKlass.sqlTableName(), targetKlass.sqlSerialColumnName())
else:
objIdRef = ''
! out.write('\t%s %s%s%s references _MKClassIds, /* %s */ \n' % (classIdName, self.sqlTypeOrOverride(), notNull, classIdDefault, self.targetClassName()))
out.write('\t%s %s%s%s' % (objIdName, self.sqlTypeOrOverride(), notNull, objIdRef))
def sqlForNone(self):
if self.setting('UseBigIntObjRefColumns', False):
--- 731,749 ----
classIdDefault = ' default %s' % self.targetKlass().id()
# ^ this makes the table a little to easier to work with in some cases (you can often just insert the obj id)
if self.get('Ref', None) or \
! (self.setting('GenerateSQLReferencesForObjRefsToSingleClasses', False) and len(self.targetKlass().subklasses())==0):
! objIdRef = self.objIdReferences()
else:
objIdRef = ''
! out.write('\t%s %s%s%s%s, /* %s */ \n' % (classIdName, self.sqlTypeOrOverride(), notNull, classIdDefault, self.classIdReferences(), self.targetClassName()))
out.write('\t%s %s%s%s' % (objIdName, self.sqlTypeOrOverride(), notNull, objIdRef))
+ def classIdReferences(self):
+ return ' references _MKClassIds'
+
+ def objIdReferences(self):
+ targetKlass = self.targetKlass()
+ return ' references %s(%s) ' % (targetKlass.sqlTableName(), targetKlass.sqlSerialColumnName())
+
def sqlForNone(self):
if self.setting('UseBigIntObjRefColumns', False):
|
| Thread | Author | Date |
|---|---|---|
| [Webware-checkins] CVS: Webware/MiddleKit/Design MSSQLSQLGenerator.py,1.20,1.21 SQLGenerator.py,1.56,1.57 | Chuck Esterbrook <echuck@us...> |