|
From: <sub...@co...> - 2004-06-14 12:51:02
|
Author: ahmedmo
Date: 2004-06-14 04:48:23 -0400 (Mon, 14 Jun 2004)
New Revision: 145
Removed:
trunk/SQLObject/col.py
Log:
Removed file/folder
Deleted: trunk/SQLObject/col.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/col.py 2004-06-14 08:47:01 UTC (rev 144)
+++ trunk/SQLObject/col.py 2004-06-14 08:48:23 UTC (rev 145)
@@ -1,608 +0,0 @@
-"""
-Col
-"""
-
-import sqlbuilder
-import re
-# Sadly the name "constraints" conflicts with many of the function
-# arguments in this module, so we rename it:
-import constraints as consts
-from include import validators
-
-NoDefault =3D sqlbuilder.NoDefault
-True, False =3D 1=3D=3D1, 0=3D=3D1
- =20
-
-########################################
-## Columns
-########################################
-
-# Col is essentially a column definition, it doesn't have
-# much logic to it.
-class SOCol(object):
-
- def __init__(self,
- name,
- soClass,
- dbName=3DNone,
- default=3DNoDefault,
- foreignKey=3DNone,
- alternateID=3DFalse,
- alternateMethodName=3DNone,
- constraints=3DNone,
- notNull=3DNoDefault,
- notNone=3DNoDefault,
- unique=3DNoDefault,
- sqlType=3DNone,
- columnDef=3DNone,
- validator=3DNone,
- immutable=3DFalse,
- cascade=3DNone,
- lazy=3DFalse,
- noCache=3DFalse):
-
- # This isn't strictly true, since we *could* use backquotes or
- # " or something (database-specific) around column names, but
- # why would anyone *want* to use a name like that?
- # @@: I suppose we could actually add backquotes to the
- # dbName if we needed to...
- assert sqlbuilder.sqlIdentifier(name), 'Name must be SQL-safe (l=
etters, numbers, underscores): %s' \
- % repr(name)
- assert name !=3D 'id', 'The column name "id" is reserved for SQL=
Object use (and is implicitly created).'
- assert name, "You must provide a name for all columns"
-
- self.columnDef =3D columnDef
-
- self.immutable =3D immutable
-
- # cascade can be one of:
- # None: no constraint is generated
- # True: a CASCADE constraint is generated
- # False: a RESTRICT constraint is generated
- self.cascade =3D cascade
-
- if type(constraints) not in (type([]), type(())):
- constraints =3D [constraints]
- self.constraints =3D self.autoConstraints() + constraints
-
- self.notNone =3D False
- if notNull is not NoDefault:
- self.notNone =3D notNull
- assert notNone is NoDefault or \
- (not notNone) =3D=3D (not notNull), \
- "The notNull and notNone arguments are aliases, and m=
ust not conflict. You gave notNull=3D%r, notNone=3D%r" % (notNull, notNo=
ne)
- elif notNone is not NoDefault:
- self.notNone =3D notNone
- if self.notNone:
- self.constraints =3D [consts.notNull] + self.constraints
-
- self.name =3D name
- self.soClass =3D None
- self._default =3D default
- self.customSQLType =3D sqlType
-
- self.foreignKey =3D foreignKey
- if self.foreignKey:
- #assert self.name.upper().endswith('ID'), "All foreign key c=
olumns must end with 'ID' (%s)" % repr(self.name)
- if not self.name.upper().endswith('ID'):
- self.foreignName =3D self.name
- self.name =3D self.name + "ID"
- else:
- self.foreignName =3D self.name[:-2]
- else:
- self.foreignName =3D None
-
- # if they don't give us a specific database name for
- # the column, we separate the mixedCase into mixed_case
- # and assume that.
- if dbName is None:
- self.dbName =3D soClass._style.pythonAttrToDBColumn(self.nam=
e)
- else:
- self.dbName =3D dbName
-
- # alternateID means that this is a unique column that
- # can be used to identify rows
- self.alternateID =3D alternateID
- if self.alternateID and alternateMethodName is None:
- self.alternateMethodName =3D 'by' + self.name[0].capitalize(=
) + self.name[1:]
- else:
- self.alternateMethodName =3D alternateMethodName
-
- if unique is NoDefault:
- self.unique =3D alternateID
- else:
- self.unique =3D unique
-
- self.validator =3D validator
- self.noCache =3D noCache
- self.lazy =3D lazy
-
- def _set_validator(self, value):
- self._validator =3D value
- if self._validator:
- self.toPython =3D self._validator.toPython
- self.fromPython =3D self._validator.fromPython
- else:
- self.toPython =3D None
- self.fromPython =3D None
-
- def _get_validator(self):
- return self._validator
-
- validator =3D property(_get_validator, _set_validator)
-
- def autoConstraints(self):
- return []
-
- def _get_default(self):
- # A default can be a callback or a plain value,
- # here we resolve the callback
- if self._default is NoDefault:
- return NoDefault
- elif hasattr(self._default, '__sqlrepr__'):
- return self._default
- elif callable(self._default):
- return self._default()
- else:
- return self._default
- default =3D property(_get_default, None, None)
-
- def _get_joinName(self):
- assert self.name[-2:] =3D=3D 'ID'
- return self.name[:-2]
- joinName =3D property(_get_joinName, None, None)
-
- def __repr__(self):
- r =3D '<%s %s' % (self.__class__.__name__, self.name)
- if self.default is not NoDefault:
- r +=3D ' default=3D%s' % repr(self.default)
- if self.foreignKey:
- r +=3D ' connected to %s' % self.foreignKey
- if self.alternateID:
- r +=3D ' alternate ID'
- if self.notNone:
- r +=3D ' not null'
- return r + '>'
-
- def createSQL(self):
- return ' '.join([self._sqlType() + self._extraSQL()])
-
- def _extraSQL(self):
- result =3D []
- if self.notNone or self.alternateID:
- result.append('NOT NULL')
- if self.unique or self.alternateID:
- result.append('UNIQUE')
- return result
-
- def _sqlType(self):
- if self.customSQLType is None:
- raise ValueError, ("Col %s (%s) cannot be used for automatic=
"
- "schema creation (too abstract)" %
- (self.name, self.__class__))
- else:
- return self.customSQLType
-
- def _mysqlType(self):
- return self._sqlType()
-
- def _postgresType(self):
- return self._sqlType()
-
- def _sqliteType(self):
- # SQLite is naturally typeless, so as a fallback it uses
- # no type.
- try:
- return self._sqlType()
- except ValueError:
- return ''
-
- def _sybaseType(self):
- return self._sqlType()
-
- def _firebirdType(self):
- return self._sqlType()
- =20
- def _maxdbType(self):
- return self._sqlType()
-
- def mysqlCreateSQL(self):
- return ' '.join([self.dbName, self._mysqlType()] + self._extraSQ=
L())
-
- def postgresCreateSQL(self):
- return ' '.join([self.dbName, self._postgresType()] + self._extr=
aSQL())
-
- def sqliteCreateSQL(self):
- return ' '.join([self.dbName, self._sqliteType()] + self._extraS=
QL())
-
- def sybaseCreateSQL(self):
- return ' '.join([self.dbName, self._sybaseType()] + self._extraS=
QL())
-
- def firebirdCreateSQL(self):
- # Ian Sparks pointed out that fb is picky about the order
- # of the NOT NULL clause in a create statement. So, we handle
- # them differently for Enum columns.
- if not isinstance(self, SOEnumCol):
- return ' '.join([self.dbName, self._firebirdType()] + self._=
extraSQL())
- else:
- return ' '.join([self.dbName] + [self._firebirdType()[0]] + =
self._extraSQL() + [self._firebirdType()[1]])
-=09
- def maxdbCreateSQL(self):
- return ' '.join([self.dbName, self._maxdbType()] + self._extraSQL=
())
-
- def __get__(self, obj, type=3DNone):
- if obj is None:
- # class attribute, return the descriptor itself
- return self
- if obj.sqlmeta.obsolete:
- raise '@@: figure out the exception for a delete'
- if obj.sqlmeta.cacheColumns:
- columns =3D obj.sqlmeta._columnCache
- if columns is None:
- obj.sqlmeta.loadValues()
- try:
- return columns[name]
- except KeyError:
- return obj.sqlmeta.loadColumn(self)
- else:
- return obj.sqlmeta.loadColumn(self)
-
- def __set__(self, obj, value):
- if self.immutable:
- raise AttributeError("The column %s.%s is immutable" %
- (obj.__class__.__name__,
- self.name))
- obj.sqlmeta.setColumn(self, value)
-
- def __delete__(self, obj):
- raise AttributeError("I can't be deleted from %r" % obj)
-
-
-class Col(object):
-
- baseClass =3D SOCol
-
- def __init__(self, name=3DNone, **kw):
- kw['name'] =3D name
- kw['columnDef'] =3D self
- self.kw =3D kw
-
- def setName(self, value):
- assert self.kw['name'] is None, "You cannot change a name after =
it has already been set (from %s to %s)" % (self.kw['name'], value)
- self.kw['name'] =3D value
-
- def withClass(self, soClass):
- return self.baseClass(soClass=3DsoClass, **self.kw)
-
-class SOStringCol(SOCol):
-
- # 3-03 @@: What about BLOB?
-
- def __init__(self, **kw):
- self.length =3D popKey(kw, 'length')
- self.varchar =3D popKey(kw, 'varchar', 'auto')
- if not self.length:
- assert self.varchar =3D=3D 'auto' or not self.varchar, \
- "Without a length strings are treated as TEXT, not va=
rchar"
- self.varchar =3D False
- elif self.varchar =3D=3D 'auto':
- self.varchar =3D True
-
- SOCol.__init__(self, **kw)
-
- def autoConstraints(self):
- constraints =3D [consts.isString]
- if self.length is not None:
- constraints +=3D [consts.MaxLength(self.length)]
- return constraints
-
- def _sqlType(self):
- if not self.length:
- return 'TEXT'
- elif self.varchar:
- return 'VARCHAR(%i)' % self.length
- else:
- return 'CHAR(%i)' % self.length
-
- def _firebirdType(self):
- if not self.length:
- return 'BLOB SUB_TYPE TEXT'
- else:
- return self._sqlType()
- =20
- def _maxdbType(self):
- if not self.length:
- return 'LONG ASCII'
- else:
- return self._sqlType()
-
-class StringCol(Col):
- baseClass =3D SOStringCol
-
-class SOIntCol(SOCol):
-
- # 3-03 @@: support precision, maybe max and min directly
-
- def autoConstraints(self):
- return [consts.isInt]
-
- def _sqlType(self):
- return 'INT'
-
-class IntCol(Col):
- baseClass =3D SOIntCol
-
-class BoolValidator(validators.Validator):
-
- def fromPython(self, value, state):
- if value:
- return sqlbuilder.TRUE
- else:
- return sqlbuilder.FALSE
-
- def toPython(self, value, state):
- if not value or not int(value):
- return sqlbuilder.FALSE
- else:
- return sqlbuilder.TRUE
-
-class SOBoolCol(SOCol):
-
- def __init__(self, **kw):
- SOCol.__init__(self, **kw)
- self.validator =3D validators.All.join(BoolValidator(), self.val=
idator)
-
- def autoConstraints(self):
- return [consts.isBool]
-
- def _postgresType(self):
- return 'BOOL'
-
- def _mysqlType(self):
- return "TINYINT"
-
- def _sybaseType(self):
- return "BIT"
-
- def _firebirdType(self):
- return 'INT'
- =20
- def _maxdbType(self):
- return "BOOLEAN"
-
-class BoolCol(Col):
- baseClass =3D SOBoolCol
-
-class SOFloatCol(SOCol):
-
- # 3-03 @@: support precision (e.g., DECIMAL)
-
- def autoConstraints(self):
- return [consts.isFloat]
-
- def _sqlType(self):
- return 'FLOAT'
-
-class FloatCol(Col):
- baseClass =3D SOFloatCol
-
-class SOKeyCol(SOCol):
-
- # 3-03 @@: this should have a simplified constructor
- # Should provide foreign key information for other DBs.
-
- def _mysqlType(self):
- return 'INT'
-
- def _sqliteType(self):
- return 'INT'
-
- def _postgresType(self):
- return 'INT'
-
- def _sybaseType(self):
- return 'INT'
-
- def _firebirdType(self):
- return 'INT'
- =20
- def _maxdbType(self):
- return 'INT'
-
-class KeyCol(Col):
-
- baseClass =3D SOKeyCol
-
-class SOForeignKey(SOKeyCol):
-
- def __init__(self, **kw):
- foreignKey =3D kw['foreignKey']
- style =3D kw['soClass']._style
- if not kw.get('name'):
- kw['name'] =3D style.instanceAttrToIDAttr(style.pythonClassT=
oAttr(foreignKey))
- else:
- if not kw['name'].upper().endswith('ID'):
- kw['name'] =3D style.instanceAttrToIDAttr(kw['name'])
- SOKeyCol.__init__(self, **kw)
-
- def postgresCreateSQL(self):
- from main import findClass
- sql =3D SOKeyCol.postgresCreateSQL(self)
- if self.cascade is not None:
- other =3D findClass(self.foreignKey)
- tName =3D other._table
- idName =3D other._idName
- action =3D self.cascade and 'CASCADE' or 'RESTRICT'
- constraint =3D ('CONSTRAINT %(tName)s_exists '
- 'FOREIGN KEY(%(colName)s) '
- 'REFERENCES %(tName)s(%(idName)s) '
- 'ON DELETE %(action)s' %
- {'tName':tName,
- 'colName':self.dbName,
- 'idName':idName,
- 'action':action})
- sql =3D ', '.join([sql, constraint])
- return sql
-
- def sybaseCreateSQL(self):
- from SQLObject import findClass
- sql =3D SOKeyCol.sybaseCreateSQL(self)
- other =3D findClass(self.foreignKey)
- tName =3D other._table
- idName =3D other._idName
- reference =3D ('REFERENCES %(tName)s(%(idName)s) ' %
- {'tName':tName,
- 'idName':idName})
- sql =3D ' '.join([sql, reference])
- return sql
- =20
- def maxdbCreateSQL(self):
- from main import findClass
- other =3D findClass(self.foreignKey)
- fidName =3D self.dbName
- #I assume that foreign key name is identical to the id of the referen=
ce table =09
- sql =3D ' '.join([fidName, self._maxdbType()])
- tName =3D other._table
- idName =3D other._idName
- sql=3Dsql + ',' + '\n'=20
- sql=3Dsql + 'FOREIGN KEY (%s) REFERENCES %s(%s)'%(fidName,tName,idNam=
e)
- return sql
-
-class ForeignKey(KeyCol):
-
- baseClass =3D SOForeignKey
-
- def __init__(self, foreignKey=3DNone, **kw):
- KeyCol.__init__(self, foreignKey=3DforeignKey, **kw)
-
-class SOEnumCol(SOCol):
-
- def __init__(self, **kw):
- self.enumValues =3D popKey(kw, 'enumValues', None)
- assert self.enumValues is not None, \
- 'You must provide an enumValues keyword argument'
- SOCol.__init__(self, **kw)
-
- def autoConstraints(self):
- return [consts.isString, consts.InList(self.enumValues)]
-
- def _mysqlType(self):
- return "ENUM(%s)" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') fo=
r v in self.enumValues])
-
- def _postgresType(self):
- length =3D max(map(len, self.enumValues))
- enumValues =3D ', '.join([sqlbuilder.sqlrepr(v, 'postgres') for =
v in self.enumValues])
- checkConstraint =3D "CHECK (%s in (%s))" % (self.dbName, enumVal=
ues)
- return "VARCHAR(%i) %s" % (length, checkConstraint)
-
- def _sqliteType(self):
- return self._postgresType()
-
- def _sybaseType(self):
- return self._postgresType()
-
- def _firebirdType(self):
- length =3D max(map(len, self.enumValues))
- enumValues =3D ', '.join([sqlbuilder.sqlrepr(v, 'firebird') for =
v in self.enumValues])
- checkConstraint =3D "CHECK (%s in (%s))" % (self.dbName, enumVal=
ues)
- #NB. Return a tuple, not a string here
- return "VARCHAR(%i)" % (length), checkConstraint
-=20
- def _maxdbType(self):
- raise "Enum type is not supported"
-
-class EnumCol(Col):
- baseClass =3D SOEnumCol
-
-class SODateTimeCol(SOCol):
-
- # 3-03 @@: provide constraints; right now we let the database
- # do any parsing and checking. And DATE and TIME?
-
- def _mysqlType(self):
- return 'DATETIME'
-
- def _postgresType(self):
- return 'TIMESTAMP'
-
- def _sybaseType(self):
- return 'DATETIME'
-
- def _sqliteType(self):
- return 'TIMESTAMP'
-
- def _firebirdType(self):
- return 'TIMESTAMP'
- =20
- def _maxdbType(self):
- return 'TIMESTAMP'
-
-class DateTimeCol(Col):
- baseClass =3D SODateTimeCol
-
-class SODateCol(SOCol):
-
- # 3-03 @@: provide constraints; right now we let the database
- # do any parsing and checking. And DATE and TIME?
-
- def _mysqlType(self):
- return 'DATE'
-
- def _postgresType(self):
- return 'DATE'
-
- def _sybaseType(self):
- return self._postgresType()
-
- def _firebirdType(self):
- return 'DATE'
- =20
- def _maxdbType(self):
- return 'DATE'
-
-class DateCol(Col):
- baseClass =3D SODateCol
-
-class SODecimalCol(SOCol):
-
- def __init__(self, **kw):
- self.size =3D popKey(kw, 'size', NoDefault)
- assert self.size is not NoDefault, \
- "You must give a size argument"
- self.precision =3D popKey(kw, 'precision', NoDefault)
- assert self.precision is not NoDefault, \
- "You must give a precision argument"
- SOCol.__init__(self, **kw)
-
- def _sqlType(self):
- return 'DECIMAL(%i, %i)' % (self.size, self.precision)
-
-class DecimalCol(Col):
- baseClass =3D SODecimalCol
-
-class SOCurrencyCol(SODecimalCol):
-
- def __init__(self, **kw):
- pushKey(kw, 'size', 10)
- pushKey(kw, 'precision', 2)
- SODecimalCol.__init__(self, **kw)
-
-class CurrencyCol(DecimalCol):
- baseClass =3D SOCurrencyCol
-
-def popKey(kw, name, default=3DNone):
- if not kw.has_key(name):
- return default
- value =3D kw[name]
- del kw[name]
- return value
-
-def pushKey(kw, name, value):
- if not kw.has_key(name):
- kw[name] =3D value
-
-all =3D []
-for key, value in globals().items():
- if isinstance(value, type) and issubclass(value, Col):
- all.append(key)
-__all__ =3D all
|