[SQL-CVS] r589 - trunk/SQLObject/sqlobject
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
|
From: <sub...@co...> - 2005-02-09 08:37:40
|
Author: ianb
Date: 2005-02-09 08:37:37 +0000 (Wed, 09 Feb 2005)
New Revision: 589
Modified:
trunk/SQLObject/sqlobject/main.py
Log:
Started putting information into the sqlmeta class:
* the table name
* the ID name
* the style
Maintaining backward compatibility.
Modified: trunk/SQLObject/sqlobject/main.py
===================================================================
--- trunk/SQLObject/sqlobject/main.py 2005-02-09 08:35:21 UTC (rev 588)
+++ trunk/SQLObject/sqlobject/main.py 2005-02-09 08:37:37 UTC (rev 589)
@@ -143,9 +143,58 @@
alongside every SQLObject instance.
"""
+ table = None
+ idName = None
+ style = None
+
+ __metaclass__ = declarative.DeclarativeMeta
+
+ # These attributes shouldn't be shared with superclasses:
+ _unshared_attributes = ['table']
+
+ def __classinit__(cls, new_attrs):
+ for attr in cls._unshared_attributes:
+ if not new_attrs.has_key(attr):
+ setattr(cls, attr, None)
+
def __init__(self, instance):
self.instance = instance
+ def setClass(cls, soClass):
+ cls.soClass = soClass
+ setClass = classmethod(setClass)
+
+ def finishClass(cls):
+ if not cls.style:
+ if cls.soClass._connection and cls.soClass._connection.style:
+ cls.style = cls.soClass._connection.style
+ else:
+ cls.style = styles.defaultStyle
+ if cls.table is None:
+ cls.table = cls.style.pythonClassToDBTable(cls.soClass.__name__)
+ if cls.idName is None:
+ cls.idName = cls.style.idForTable(cls.table)
+ finishClass = classmethod(finishClass)
+
+class _sqlmeta_attr(object):
+
+ def __init__(self, name):
+ self.name = name
+
+ def __get__(self, obj, type=None):
+ return getattr((type or obj).sqlmeta, self.name)
+
+
+# @@: This should become a public interface or documented or
+# something. Turning it on gives earlier warning about things
+# that will be deprecated (having this off we won't flood people
+# with warnings right away).
+strict_warnings = False
+
+def deprecated(message):
+ if strict_warnings:
+ warnings.warn(message, DeprecationWarning, stacklevel=1)
+
# SQLObject is the superclass for all SQLObject classes, of
# course. All the deeper magic is done in MetaSQLObject, and
# only lesser magic is done here. All the actual work is done
@@ -208,13 +257,20 @@
def __classinit__(cls, new_attrs):
+ # This is true if we're initializing the SQLObject class,
+ # instead of a subclass:
+ is_base = cls.__bases__ == (object,)
+
if (not new_attrs.has_key('sqlmeta')
- and not cls.__bases__ == (object,)):
+ and not is_base):
# We have to create our own subclass, usually.
# type(className, bases_tuple, attr_dict) creates a new
# subclass:
+ #cls.sqlmeta = cls.sqlmeta.clone()
cls.sqlmeta = type('sqlmeta', (cls.sqlmeta,), {})
- cls.sqlmeta.soClass = cls
+ cls.sqlmeta.setClass(cls)
+ cls.sqlmeta.finishClass()
+
implicitColumns = []
implicitJoins = []
@@ -236,10 +292,11 @@
delattr(cls, attr)
continue
- # We *don't* want to inherit _table, so we make sure it
- # is defined in this class (not a superclass)
- if not new_attrs.has_key('_table'):
- cls._table = None
+ if (new_attrs.has_key('_table') and not is_base):
+ deprecated("'_table' is deprecated; please set the 'table' "
+ "attribute in sqlmeta instead")
+ cls.sqlmeta.table = cls._table
+ del cls._table
if new_attrs.has_key('_connection'):
connection = new_attrs['_connection']
@@ -290,13 +347,11 @@
if connection or not hasattr(cls, '_connection'):
cls.setConnection(connection)
- # The style object tells how to map between Python
- # identifiers and Database identifiers:
- if not cls._style:
- if cls._connection and cls._connection.style:
- cls._style = cls._connection.style
- else:
- cls._style = styles.defaultStyle
+ if (new_attrs.has_key('_style') and not is_base):
+ deprecated("'_style' is deprecated; please set the 'style' "
+ "attribute in sqlmeta instead")
+ cls.sqlmeta.style = cls._style
+ del cls._style
# plainSetters are columns that haven't been overridden by the
# user, so we can contact the database directly to set them.
@@ -315,19 +370,12 @@
cls._SO_columnDict = {}
cls._SO_columns = []
- # If _table isn't given, use style default
- if not cls._table:
- cls._table = cls._style.pythonClassToDBTable(cls.__name__)
+ if (new_attrs.has_key('_idName') and not is_base):
+ deprecated("'_idName' is deprecated; please set the 'idName' "
+ "attribute in sqlmeta instead")
+ cls.sqlmeta.idName = cls._idName
+ del cls._idName
- # If _idName isn't given, use style default
- if not new_attrs.has_key('_idName'):
- cls._idName = cls._style.idForTable(cls._table)
-
- # We use the magic "q" attribute for accessing lazy
- # SQL where-clause generation. See the sql module for
- # more.
- cls.q = sqlbuilder.SQLObjectTable(cls)
-
# We have to check if there are columns in the inherited
# _columns where the attribute has been set to None in this
# class. If so, then we need to remove that column from
@@ -362,8 +410,18 @@
for idx in cls._indexes:
cls.addIndex(idx)
+ # We use the magic "q" attribute for accessing lazy
+ # SQL where-clause generation. See the sql module for
+ # more.
+ if not is_base:
+ cls.q = sqlbuilder.SQLObjectTable(cls)
+
classregistry.registry(cls._registry).addClass(cls)
+ _style = _sqlmeta_attr('style')
+ _table = _sqlmeta_attr('table')
+ _idName = _sqlmeta_attr('idName')
+
def get(cls, id, connection=None, selectResults=None):
assert id is not None, 'None is not a possible id for %s' % cls.__name
@@ -1329,7 +1387,7 @@
Return the accumulate result
"""
conn = self.ops.get('connection', self.sourceClass._connection)
- return conn.accumulateSelect(self,expression)
+ return conn.accumulateSelect(self, expression)
def count(self):
""" Counting elements of current select results """
|