[Zope-CVS] CVS: Products/Ape/lib/apelib/sql - classification.py:1.8.2.3 dbapi.py:1.11.2.4 interfaces.py:1.4.2.4 mysql.py:1.1.4.2 properties.py:1.11.2.3 sqlbase.py:1.13.2.4 structure.py:1.11.2.3 table.py:1.1.2.4

Shane Hathaway shane at zope.com
Wed Jul 21 02:07:34 EDT 2004


Update of /cvs-repository/Products/Ape/lib/apelib/sql
In directory cvs.zope.org:/tmp/cvs-serv25827/sql

Modified Files:
      Tag: sql-types-branch
	classification.py dbapi.py interfaces.py mysql.py 
	properties.py sqlbase.py structure.py table.py 
Log Message:
Fixed bugs in sql-types-branch.  The tests now pass.


=== Products/Ape/lib/apelib/sql/classification.py 1.8.2.2 => 1.8.2.3 ===
--- Products/Ape/lib/apelib/sql/classification.py:1.8.2.2	Tue Jul 20 22:25:58 2004
+++ Products/Ape/lib/apelib/sql/classification.py	Wed Jul 21 02:07:34 2004
@@ -46,11 +46,12 @@
         return classification, rec
 
     def store(self, event, classification):
+        conn = self.get_connection(event)
         table = self.get_table(event)
         row = (classification.get('class_name', ''),
                classification.get('mapper_name', ''))
         try:
             table.set_one(event.oid, self.column_names, row, event.is_new)
-        except conn.module.IntegrityError:
+        except conn.module.DatabaseError:
             raise OIDConflictError(event.oid)
         return row


=== Products/Ape/lib/apelib/sql/dbapi.py 1.11.2.3 => 1.11.2.4 ===
--- Products/Ape/lib/apelib/sql/dbapi.py:1.11.2.3	Wed Jul 21 00:55:47 2004
+++ Products/Ape/lib/apelib/sql/dbapi.py	Wed Jul 21 02:07:34 2004
@@ -22,7 +22,7 @@
 
 from apelib.core.interfaces import ITPCConnection
 from apelib.core.schemas import ColumnSchema
-from apelib.sql.interfaces import ISQLConnection
+from apelib.sql.interfaces import ISQLConnection, IRDBMSColumn
 from apelib.sql.table import SQLTable
 
 name_style_re = re.compile(':[A-Za-z0-9_-]+')
@@ -37,7 +37,6 @@
 
     # factories by column name take precedence over factories by column type.
     column_factories_by_name = {}  # { local col name -> column factory }
-    column_factories_by_type = {}  # { local type name -> column factory }
     column_name_translations = {}  # { local col name -> db col name }
     column_type_translations = {}  # { local type name -> db type name }
     module = None
@@ -66,23 +65,21 @@
 
     def define_table(self, name, schema):
         """Creates and returns an IRDBMSTable."""
-        t = SQLTable(self, self.prefix + name)
+        table = SQLTable(self, self.prefix + name)
         for c in schema.get_columns():
             factory = self.column_factories_by_name.get(c.name, None)
             if factory is None:
-                factory = self.column_factories_by_type.get(c.type, None)
-            if factory is None:
                 factory = RDBMSColumn
-            dbc = factory(c)
-            name = self.column_name_translations.get(c.name)
-            if name is not None:
-                dbc.name = name
-            type = self.column_name_translations.get(c.type)
-            if type is not None:
-                dbc.type = type
-            t.add_column(c.name, dbc)
-        self._tables[name] = t
-        return t
+            dbc = factory(self, c)
+            n = self.column_name_translations.get(c.name)
+            if n is not None:
+                dbc.name = n
+            t = self.column_type_translations.get(c.type)
+            if t is not None:
+                dbc.type = t
+            table.add_column(c.name, dbc)
+        self._tables[name] = table
+        return table
 
     def get_table(self, name):
         """Returns a previously defined IRDBMSTable."""
@@ -115,6 +112,11 @@
         """
         raise NotImplementedError("Abstract Method")
 
+    def clear_table(self, name):
+        """Removes all rows from a table.
+        """
+        self.execute('DELETE FROM %s' % (self.prefix + name))
+
     def execute(self, sql, kw=None, fetch=False):
         if self.connector is None:
             raise RuntimeError('Not connected')
@@ -256,15 +258,17 @@
     """Basic RDBMS column.  Does no type translation."""
     __implements__ = IRDBMSColumn
 
-    def __init__(self, column):
+    use_conversion = False
+
+    def __init__(self, connection, column):
         self.name = column.name
         self.type = column.type
         self.unique = column.unique
 
-    def to_db(self, connection, value):
+    def to_db(self, value):
         return value
 
-    def from_db(self, connection, value):
+    def from_db(self, value):
         return value
 
 
@@ -272,17 +276,14 @@
     """RDBMS column that stores string OIDs as integers."""
     __implements__ = IRDBMSColumn
 
-    def to_db(self, connection, value):
+    use_conversion = True
+
+    def to_db(self, value):
         return int(value)
 
-    def from_db(self, connection, value):
+    def from_db(self, value):
         return str(value)
 
 
 # Set up default column types.
 AbstractSQLConnection.column_factories_by_name['oid'] = OIDColumn
-
-
-# Names imported for backward compatibility only.
-from apelib.sql.postgresql import PostgreSQLConnection
-from apelib.sql.mysql import MySQLConnection


=== Products/Ape/lib/apelib/sql/interfaces.py 1.4.2.3 => 1.4.2.4 ===
--- Products/Ape/lib/apelib/sql/interfaces.py:1.4.2.3	Wed Jul 21 00:55:47 2004
+++ Products/Ape/lib/apelib/sql/interfaces.py	Wed Jul 21 02:07:34 2004
@@ -64,6 +64,14 @@
         Whether the value is before or after the increment is not specified.
         """
 
+    def clear_table(name):
+        """Removes all rows from a table.
+
+        This is not a method of IRDBMSTable because it is not
+        always possible to construct an IRDBMSTable while resetting
+        tables.
+        """
+
 
 class ISQLConnection (IRDBMSConnection):
     
@@ -116,6 +124,9 @@
 
 class IRDBMSColumn (IColumnSchema):
     """A column associated with a specific database."""
+
+    use_conversion = Attribute(
+        "use_conversion", "True if this column needs to convert values.")
 
     def to_db(value):
         """Converts a generic value to a database-specific value."""


=== Products/Ape/lib/apelib/sql/mysql.py 1.1.4.1 => 1.1.4.2 ===
--- Products/Ape/lib/apelib/sql/mysql.py:1.1.4.1	Wed Jul 21 00:55:47 2004
+++ Products/Ape/lib/apelib/sql/mysql.py	Wed Jul 21 02:07:34 2004
@@ -76,3 +76,4 @@
             table_name)
         rows = self.execute("SELECT LAST_INSERT_ID()", fetch=1)
         return rows[0][0]
+


=== Products/Ape/lib/apelib/sql/properties.py 1.11.2.2 => 1.11.2.3 ===
--- Products/Ape/lib/apelib/sql/properties.py:1.11.2.2	Tue Jul 20 22:25:58 2004
+++ Products/Ape/lib/apelib/sql/properties.py	Wed Jul 21 02:07:34 2004
@@ -77,7 +77,16 @@
         self.table_name = table_name
         self.schema = schema
         SQLGatewayBase.__init__(self, conn_name)
+        self.columns = schema.get_columns()
 
+    def init(self, event):
+        conn = self.get_connection(event)
+        all = RowSequenceSchema(
+            self.oid_columns + self.table_schema.get_columns())
+        table = conn.define_table(self.table_name, all)
+        if not conn.exists(self.table_name, 'table'):
+            table.create()
+        
     def load(self, event):
         table = self.get_table(event)
         recs = table.select(self.column_names, oid=event.oid)
@@ -152,8 +161,9 @@
         return None
 
     def init(self, event):
-        table = self.get_table(event)
-        if not conn.exists(table.name, 'table'):
+        conn = self.get_connection(event)
+        table = conn.define_table(self.table_name, self.table_schema)
+        if not conn.exists(self.table_name, 'table'):
             table.create()
         self.var_props.init(event)
         if event.clear_all:
@@ -209,13 +219,13 @@
         module_name = cn[:pos]
         class_name = cn[pos + 1:]
         schema = self.get_schema_for_class(module_name, class_name)
-        if not schema.get_columns():
+        if schema is None or not schema.get_columns():
             # No fixed properties exist for this class.
             self.fixed_props[cn] = None
             return None
 
         # Allocate a table name
-        conn = self.get_connection()
+        conn = self.get_connection(event)
         table = self.get_table(event)
         rows = table.select(('table_name',), class_name=cn)
         if rows:


=== Products/Ape/lib/apelib/sql/sqlbase.py 1.13.2.3 => 1.13.2.4 ===
--- Products/Ape/lib/apelib/sql/sqlbase.py:1.13.2.3	Wed Jul 21 00:55:47 2004
+++ Products/Ape/lib/apelib/sql/sqlbase.py	Wed Jul 21 02:07:34 2004
@@ -16,7 +16,8 @@
 $Id$
 """
 
-from apelib.core.interfaces import IGateway, IDatabaseInitializer
+from apelib.core.interfaces \
+     import IGateway, IDatabaseInitializer, IDatabaseInitEvent
 from apelib.core.schemas import ColumnSchema, RowSequenceSchema
 from interfaces import IRDBMSConnection
 
@@ -36,7 +37,7 @@
         self.conn_name = conn_name
         if self.table_schema is None:
             if self.schema is not None:
-                self.table_schema = schema
+                self.table_schema = self.schema
             else:
                 self.table_schema = RowSequenceSchema()
         self.column_names = [f.name for f in self.table_schema.get_columns()]
@@ -54,10 +55,11 @@
     def init(self, event):
         conn = self.get_connection(event)
         assert IRDBMSConnection.isImplementedBy(conn)
-        all = RowSequenceSchema(self.oid_columns + self.table_schema.get_columns())
+        all = RowSequenceSchema(
+            self.oid_columns + self.table_schema.get_columns())
         table = conn.define_table(self.table_name, all)
         if conn.exists(self.table_name, 'table'):
-            if event.clear_all:
+            if IDatabaseInitEvent.isImplementedBy(event) and event.clear_all:
                 table.delete_rows()
         else:
             table.create()


=== Products/Ape/lib/apelib/sql/structure.py 1.11.2.2 => 1.11.2.3 ===
--- Products/Ape/lib/apelib/sql/structure.py:1.11.2.2	Tue Jul 20 22:25:58 2004
+++ Products/Ape/lib/apelib/sql/structure.py	Wed Jul 21 02:07:34 2004
@@ -35,12 +35,13 @@
         firstcol = self.column_names[:1]
         items = table.select(firstcol, oid=event.oid)
         if items:
-            state = items[0][0]
+            state = str(items[0][0])
         else:
             state = ''
         return state, state
 
     def store(self, event, state):
+        conn = self.get_connection(event)
         table = self.get_table(event)
         firstcol = self.column_names[:1]
         data = (conn.module.Binary(state),)
@@ -64,7 +65,7 @@
 
     def load(self, event):
         table = self.get_table(event)
-        rows = table.select(self.columns, oid=event.oid)
+        rows = table.select(self.column_names, oid=event.oid)
         res = []
         h = []
         for name, child_oid in rows:
@@ -139,7 +140,7 @@
 
     def load(self, event):
         table = self.get_table(event)
-        items = table.select(self.columns, oid=event.oid)
+        items = table.select(self.column_names, oid=event.oid)
         if items:
             state = long(items[0][0])
         else:
@@ -150,7 +151,7 @@
         state = long(state)
         table = self.get_table(event)
         data = (state,)
-        table.set_one(event.oid, self.columns, data, event.is_new)
+        table.set_one(event.oid, self.column_names, data, event.is_new)
         return state
 
 


=== Products/Ape/lib/apelib/sql/table.py 1.1.2.3 => 1.1.2.4 ===
--- Products/Ape/lib/apelib/sql/table.py:1.1.2.3	Wed Jul 21 00:55:47 2004
+++ Products/Ape/lib/apelib/sql/table.py	Wed Jul 21 02:07:34 2004
@@ -47,7 +47,7 @@
         return ' AND '.join(clauses)
 
     def generate_select(self, filter_col_names, result_col_names):
-        result_names = [self.columns[col].name for col in col_names]
+        result_names = [self.columns[col].name for col in result_col_names]
         sql = 'SELECT %s FROM %s' % (', '.join(result_names), self.name)
         where = self.generate_conditions(filter_col_names)
         if where:
@@ -97,14 +97,23 @@
             f[col_name] = self.columns[col_name].to_db(value)
         sql = self.cache(self.generate_select, filter.keys(), result_col_names)
         db_res = self.execute(sql, f, fetch=1)
-        # Convert the result to standard types.
-        res = []
-        dbcols = []
+        # Convert the results to standard types.
+        conversions = []
         for n in range(len(result_col_names)):
-            dbcols.append((n, self.columns[result_col_names[n]].from_db))
-        for row in db_res:
-            r = [from_db(row[n]) for (n, from_db) in dbcols]
-            res.append(tuple(r))
+            col = self.columns[result_col_names[n]]
+            if col.use_conversion:
+                conversions.append((n, col.from_db))
+        if conversions:
+            # Convert specific columns.
+            res = []
+            for row in db_res:
+                r = list(row)
+                for n, from_db in conversions:
+                    r[n] = from_db(r[n])
+                res.append(tuple(r))
+        else:
+            # No conversion needed.
+            res = db_res
         return res
 
     def insert(self, col_names, row):
@@ -196,10 +205,11 @@
         """Creates the table.
         """
         pkeys = []
+        col_decls = []
         for c in self.column_order:
             col = self.columns[c]
             constraints = ''
-            if unique:
+            if col.unique:
                 constraints = ' NOT NULL'
                 pkeys.append(col.name)
             col_decls.append(



More information about the Zope-CVS mailing list