[Zope-CVS] CVS: Products/Ape/lib/apelib/sql - classification.py:1.3 dbapi.py:1.2 keygen.py:1.5 properties.py:1.3 querygen.py:1.3 security.py:1.3 sqlbase.py:1.5 structure.py:1.4

Shane Hathaway shane@zope.com
Sun, 18 May 2003 00:17:01 -0400


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

Modified Files:
	classification.py dbapi.py keygen.py properties.py querygen.py 
	security.py sqlbase.py structure.py 
Log Message:
Made the standard SQL gateways static rather than dependent on a
particular database connection.  This is another step toward
simplifying the configuration of mappers.  The change involved the
following:

- Refactored the query generator to generate only one query at a
time.  Gateways no longer use it directly.  Instead, they ask the
database connection to generate a query.  The database connection
caches the generated query.

- Added a setUp method to gateways.  The setUp method can check the
interface of the connection and/or create tables.

- Consolidated the set up procedure for SQL gateways into setUp().

- Added an argument to the execute() method of SQLGatewayBase so it
can find the connection.

- Arranged for ApeStorage to call gateway.setUp().



=== Products/Ape/lib/apelib/sql/classification.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/sql/classification.py:1.2	Fri Apr 11 02:17:49 2003
+++ Products/Ape/lib/apelib/sql/classification.py	Sun May 18 00:16:29 2003
@@ -37,7 +37,7 @@
 
     def load(self, event):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         classification = {}
         if items:
             rec = items[0]
@@ -51,15 +51,15 @@
 
     def store(self, event, classification):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         mt = classification.get('meta_type', '')
         cn = classification.get('class_name', '')
         kw = {'key': key, 'meta_type': mt, 'class_name': cn}
         if items:
             # update.
-            self.execute('update', **kw)
+            self.execute(event, 'update', **kw)
         else:
             # insert.
-            self.execute('insert', **kw)
+            self.execute(event, 'insert', **kw)
         return (mt, cn)
 


=== Products/Ape/lib/apelib/sql/dbapi.py 1.1 => 1.2 ===
--- Products/Ape/lib/apelib/sql/dbapi.py:1.1	Sat Apr 12 16:56:26 2003
+++ Products/Ape/lib/apelib/sql/dbapi.py	Sun May 18 00:16:29 2003
@@ -52,31 +52,30 @@
         if isinstance(params, StringType):
             params = (params,)
         self.params = params
-
-    def makeQueryGenerator(self, table_name, column_defs):
-        return makeQueryGenerator(self.module_name, table_name, column_defs)
+        self.query_gens = {}      # { (table, columns) -> QueryGenerator }
+        self.query_cache = {}     # { (table, columns, operation) -> query }
 
     def isConnected(self):
-        return (self.db is not None)
+        return self.db is not None
 
-    def addConnectCallback(self, f):
-        self.connect_callbacks.append(f)
+    # ISQLConnection implementation
 
-    def connect(self):
-        if self.kwparams:
-            self.db = self.module.connect(*self.params, **self.kwparams)
-        else:
-            self.db = self.module.connect(*self.params)
-        self.cursor = self.db.cursor()
-        for f in self.connect_callbacks:
-            f()
-        self.connect_callbacks = []
-
-    def sortKey(self):
-        return repr(self)
-
-    def getName(self):
-        return repr(self)
+    def getQuery(self, table_name, column_defs, operation):
+        query = self.query_cache.get((table_name, column_defs, operation))
+        if query is not None:
+            return query
+        gen = self.query_gens.get((table_name, column_defs))
+        if gen is None:
+            if self.prefix:
+                real_table_name = '%s_%s' % (self.prefix, table_name)
+            else:
+                real_table_name = table_name
+            gen = makeQueryGenerator(
+                self.module_name, real_table_name, column_defs)
+            self.query_gens[(table_name, column_defs)] = gen
+        query = gen.generate(operation)
+        self.query_cache[(table_name, column_defs, operation)] = query
+        return query
 
     def execute(self, query, fetch=0, cursor=None, **kw):
         if cursor is None:
@@ -104,6 +103,24 @@
 
     def asBinary(self, data):
         return self.module.Binary(data)
+
+    # ITPCConnection implementation
+
+    def connect(self):
+        if self.kwparams:
+            self.db = self.module.connect(*self.params, **self.kwparams)
+        else:
+            self.db = self.module.connect(*self.params)
+        self.cursor = self.db.cursor()
+        for f in self.connect_callbacks:
+            f()
+        self.connect_callbacks = []
+
+    def sortKey(self):
+        return repr(self)
+
+    def getName(self):
+        return repr(self)
 
     def begin(self):
         pass


=== Products/Ape/lib/apelib/sql/keygen.py 1.4 => 1.5 ===
--- Products/Ape/lib/apelib/sql/keygen.py:1.4	Tue Apr 29 18:11:50 2003
+++ Products/Ape/lib/apelib/sql/keygen.py	Sun May 18 00:16:29 2003
@@ -27,24 +27,23 @@
     __implements__ = IKeychainGenerator
 
     table_base_name = 'key_seq'
+    column_defs = ()
 
-    def setUpQueries(self):
-        gen = self.conn.makeQueryGenerator(self.table, ())
-        self.queries = gen.generateAllForSequence()
-
-    def setUpTables(self):
-        conn = self.conn
+    def setUp(self, event, clear_all=0):
+        conn = event.getConnection(self.conn_name)
         first_time = 0
         try:
-            rows = self.execute('check', 1)
+            rows = self.execute(event, 'sequence_check', 1)
             if len(rows) == 0:
                 first_time = 1
         except conn.error:
             conn.db.rollback()
-            self.execute('create')
+            self.execute(event, 'sequence_create')
             first_time = 1
-        if first_time and self.queries.get('insert'):
-            self.execute('insert')
+        if first_time:
+            self.execute(event, 'sequence_insert')
+        if clear_all:
+            self.execute(event, 'sequence_clear')
         conn.db.commit()
 
     def makeKeychain(self, event, name, stored):
@@ -55,8 +54,7 @@
             # Request that the other side do the work (for ZEO)
             n = event.getKeyedObjectSystem().newKey()
         else:
-            if self.queries.get('update'):
-                self.execute('update')
-            n = self.execute('read', 1)[0][0]
+            self.execute(event, 'sequence_update')
+            n = self.execute(event, 'sequence_read', 1)[0][0]
         return event.getKeychain()[:-1] + (long(n),)
 


=== Products/Ape/lib/apelib/sql/properties.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/sql/properties.py:1.2	Fri Apr 11 02:17:49 2003
+++ Products/Ape/lib/apelib/sql/properties.py	Sun May 18 00:16:29 2003
@@ -42,37 +42,38 @@
 
     def load(self, event):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         items.sort()
         return items, tuple(items)
 
     def store(self, event, state):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         state_dict = {}
         for row in state:
             id = row[0]
             state_dict[id] = row
         items_dict = {}
+        conn = event.getConnection(self.conn_name)
         for old_row in items:
             id = old_row[0]
             items_dict[id] = old_row
             state_row = state_dict.get(id)
             if state_row is None:
                 # Remove a property
-                self.execute('delete', key=key, id=id)
+                self.execute(event, 'delete', key=key, id=id)
             elif old_row != state_row:
                 # Update a property
                 id, t, v = state_row
-                data = self.conn.asBinary(v)
-                self.execute('update',
+                data = conn.asBinary(v)
+                self.execute(event, 'update',
                              key=key, id=id, type=t, data=data)
         for row in state:
             if not items_dict.has_key(row[0]):
                 # Add a property
                 id, t, v = row
-                data = self.conn.asBinary(v)
-                self.execute('insert',
+                data = conn.asBinary(v)
+                self.execute(event, 'insert',
                              key=key, id=id, type=t, data=data)
         state = list(state)
         state.sort()


=== Products/Ape/lib/apelib/sql/querygen.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/sql/querygen.py:1.2	Sat Apr 12 16:56:26 2003
+++ Products/Ape/lib/apelib/sql/querygen.py	Sun May 18 00:16:29 2003
@@ -23,10 +23,11 @@
         raise KeyError("Factory name %s conflicts" % repr(name))
     query_generator_factories[name] = f
 
-def makeQueryGenerator(name, table_name, column_defs):
-    f = query_generator_factories.get(name)
+def makeQueryGenerator(module_name, table_name, column_defs):
+    f = query_generator_factories.get(module_name)
     if f is None:
-        raise KeyError("No query generator registered for %s" % repr(name))
+        raise KeyError(
+            "No query generator registered for %s" % repr(module_name))
     return f(table_name, column_defs)
 
 
@@ -57,27 +58,19 @@
         return self.column_type_translations[column_type]
 
 
-    def generateAll(self):
-        res = {
-            'check':  self.generateCheck(),
-            'create': self.generateCreate(),
-            'read':   self.generateRead(),
-            'update': self.generateUpdate(),
-            'insert': self.generateInsert(),
-            'delete': self.generateDelete(),
-            'clear':  self.generateClear(),
-            }
-        return res
+    def generate(self, operation):
+        m = getattr(self, 'gen_' + operation)
+        return m()
 
 
-    def generateCheck(self):
+    def gen_check(self):
         kc = self.translateName(self.key_column[0])
         # This is meant to raise an error if the table is missing.
         # Returns nothing if the table exists.
         return 'SELECT %s FROM %s WHERE 0 = 1' % (kc, self.table_name)
 
 
-    def generateCreate(self):
+    def gen_create(self):
         cols = []
         for name, typ, u in self.column_defs:
             trans_name = self.translateName(name)
@@ -86,19 +79,32 @@
         return "CREATE TABLE %s (%s)" % (self.table_name, ', '.join(cols))
 
 
-    def generateRead(self, key_column_name=None):
+    def gen_read(self):
         cols = []
         for name, typ, u in self.column_defs[1:]:
             trans_name = self.translateName(name)
             cols.append(trans_name)
-        if key_column_name is None:
-            key_column_name = self.key_column[0]
+        key_column_name = self.key_column[0]
         trans_kc = self.translateName(key_column_name)
         return 'SELECT %s FROM %s WHERE %s = %%(%s)s' % (
             ', '.join(cols), self.table_name, trans_kc, key_column_name)
 
 
-    def generateUpdate(self):
+    def gen_simple_search(self):
+        cols = []
+        where_clauses = []
+        for name, typ, unique in self.column_defs[1:]:
+            trans_name = self.translateName(name)
+            cols.append(trans_name)
+            if unique:
+                # use this column to choose a record
+                clause = "%s = %%(%s)s" % (trans_name, name)
+                where_clauses.append(clause)
+        return 'SELECT %s FROM %s WHERE %s' % (
+            ', '.join(cols), self.table_name, ' and '.join(where_clauses))
+
+
+    def gen_update(self):
         update_cols = []
         where_clauses = []
         for name, typ, unique in self.column_defs:
@@ -115,7 +121,7 @@
             ' and '.join(where_clauses))
 
 
-    def generateInsert(self):
+    def gen_insert(self):
         colnames = []
         colfmts = []
         for name, typ, unique in self.column_defs:
@@ -126,7 +132,7 @@
             self.table_name, ', '.join(colnames), ', '.join(colfmts))
         
 
-    def generateDelete(self):
+    def gen_delete(self):
         where_clauses = []
         for name, typ, unique in self.column_defs:
             if unique:
@@ -137,20 +143,10 @@
             self.table_name, ' and '.join(where_clauses))
 
 
-    def generateClear(self):
+    def gen_clear(self):
         return 'DELETE FROM %s' % self.table_name
 
 
-    def generateAllForSequence(self):
-        table_name = self.table_name
-        res = {
-            'check':  "SELECT last_value FROM %s" % table_name,
-            'create': "CREATE SEQUENCE %s" % table_name,
-            'read':   "SELECT nextval('%s')" % table_name,
-            'clear':  "SELECT setval('%s', 1)" % table_name,
-            }
-        return res
-
 
 class PostgreSQLQueryGenerator (AbstractQueryGenerator):
 
@@ -163,9 +159,28 @@
 
     column_name_translations = {}
 
+    def gen_sequence_check(self):
+        return "SELECT last_value FROM %s" % self.table_name
+
+    def gen_sequence_create(self):
+        return "CREATE SEQUENCE %s" % self.table_name
+
+    def gen_sequence_insert(self):
+        return ""  # Do nothing
+
+    def gen_sequence_read(self):
+        return "SELECT nextval('%s')" % self.table_name
+
+    def gen_sequence_update(self):
+        return ""  # Do nothing
+
+    def gen_sequence_clear(self):
+        return "SELECT setval('%s', 1)" % self.table_name
+
 addFactory('psycopg', PostgreSQLQueryGenerator)
 
 
+
 class MySQLQueryGenerator (AbstractQueryGenerator):
 
     column_type_translations = {
@@ -179,18 +194,24 @@
         'key': 'objkey',
         }
 
-    def generateAllForSequence(self):
-        table_name = self.table_name
-        res = {
-            'check':  "SELECT last_value FROM %s" % table_name,
-            'create': "CREATE TABLE %s (last_value int)" % table_name,
-            'insert': "INSERT INTO %s VALUES (0)" % table_name,
-            'update': ("UPDATE %s SET last_value=LAST_INSERT_ID(last_value+1)"
-                       % table_name),
-            'read':   "SELECT LAST_INSERT_ID()",
-            'clear':  "UPDATE %s SET last_value=0" % table_name,
-            }
-        return res
+    def gen_sequence_check(self):
+        return "SELECT last_value FROM %s" % self.table_name
+
+    def gen_sequence_create(self):
+        return "CREATE TABLE %s (last_value int)" % self.table_name
+
+    def gen_sequence_insert(self):
+        return "INSERT INTO %s VALUES (0)" % self.table_name
+
+    def gen_sequence_read(self):
+        return "SELECT LAST_INSERT_ID()"
+
+    def gen_sequence_update(self):
+        return ("UPDATE %s SET last_value=LAST_INSERT_ID(last_value+1)"
+                % self.table_name)
+
+    def gen_sequence_clear(self):
+        return "UPDATE %s SET last_value=0" % self.table_name
 
 addFactory('MySQLdb', MySQLQueryGenerator)
 


=== Products/Ape/lib/apelib/sql/security.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/sql/security.py:1.2	Fri Apr 11 02:17:49 2003
+++ Products/Ape/lib/apelib/sql/security.py	Sun May 18 00:16:29 2003
@@ -36,21 +36,21 @@
 
     def load(self, event):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         items.sort()
         return items, tuple(items)
 
     def store(self, event, state):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         items.sort()
         state = list(state)
         state.sort()
         if state != items:
-            self.execute('delete', key=key)
+            self.execute(event, 'delete', key=key)
             for row in state:
                 self.execute(
-                    'insert', key=key, declaration_type=row[0],
+                    event, 'insert', key=key, declaration_type=row[0],
                     role=row[1], permission=row[2], username=row[3])
         return tuple(state)
 
@@ -67,66 +67,55 @@
     schema.addField('roles', 'string:list')
     schema.addField('domains', 'string:list')
 
-    table_base_name = 'users'
+    table_defs = {
+        'users':        (('id', 'string', 1),
+                         ('password', 'string', 0),),
+        'user_roles':   (('id', 'string', 1),
+                         ('role', 'string', 0),),
+        'user_domains': (('id', 'string', 1),
+                         ('domain', 'string', 0),),
+        }
 
-    def setUpTableNames(self):
-        SQLGatewayBase.setUpTableNames(self)
-        self.roles_table = self.conn.prefix + '_user_roles'
-        self.domains_table = self.conn.prefix + '_user_domains'
 
-
-    def setUpQueries(self):
-        query_groups = {}
-        column_defs = [('id', 'string', 1),
-                       ('password', 'string', 0),]
-        gen = self.conn.makeQueryGenerator(self.table, column_defs)
-        query_groups['users'] = gen.generateAll()
-
-        column_defs = [('id', 'string', 1),
-                       ('role', 'string', 0),]
-        gen = self.conn.makeQueryGenerator(self.roles_table, column_defs)
-        query_groups['roles'] = gen.generateAll()
-
-        column_defs = [('id', 'string', 1),
-                       ('domain', 'string', 0),]
-        gen = self.conn.makeQueryGenerator(self.domains_table, column_defs)
-        query_groups['domains'] = gen.generateAll()
-
-        self.query_groups = query_groups
-
-
-    def setUpTables(self):
-        conn = self.conn
+    def setUp(self, event, clear_all=0):
+        conn = event.getConnection(self.conn_name)
         try:
-            self.execute('users', 'check')
+            self.execute(event, 'users', 'check')
         except conn.error:
             conn.db.rollback()
-            self.execute('users', 'create')
-            self.execute('roles', 'create')
-            self.execute('domains', 'create')
+            self.execute(event, 'users', 'create')
+            self.execute(event, 'user_roles', 'create')
+            self.execute(event, 'user_domains', 'create')
             conn.db.commit()
+        else:
+            if clear_all:
+                self.execute(event, 'users', 'clear')
+                self.execute(event, 'user_roles', 'clear')
+                self.execute(event, 'user_domains', 'clear')
+
+
+    def execute(self, event, table, operation, *args, **kw):
+        conn = event.getConnection(self.conn_name)
+        query = conn.getQuery(
+            table, self.table_defs[table], operation)
+        if query == '':
+            # No query needed for this operation
+            return
+        return conn.execute(query, *args, **kw)
 
-    def execute(self, table, query_name, *args, **kw):
-        query = self.query_groups[table][query_name]
-        return self.conn.execute(query, *args, **kw)
-
-    def clear(self):
-        self.execute('users', 'clear')
-        self.execute('roles', 'clear')
-        self.execute('domains', 'clear')
 
     def load(self, event):
         key = event.getKeychain()[-1]
-        rows = self.execute('users', 'read', 1, key=key)
+        rows = self.execute(event, 'users', 'read', 1, key=key)
         data = {}
         for id, password in rows:
             data[id] = (password, [], [])
-        rows = self.execute('roles', 'read', 1, key=key)
+        rows = self.execute(event, 'user_roles', 'read', 1, key=key)
         for id, role in rows:
             row = data.get(id)
             if row is not None:
                 row[1].append(role)
-        rows = self.execute('domains', 'read', 1, key=key)
+        rows = self.execute(event, 'user_domains', 'read', 1, key=key)
         for id, domain in rows:
             row = data.get(id)
             if row is not None:
@@ -156,9 +145,9 @@
             new_row = new_dict.get(id)
             if new_row is None:
                 # Remove this row.
-                self.execute('users', 'delete', key=key, id=id)
-                self.execute('roles', 'delete', key=key, id=id)
-                self.execute('domains', 'delete', key=key, id=id)
+                self.execute(event, 'users', 'delete', key=key, id=id)
+                self.execute(event, 'user_roles', 'delete', key=key, id=id)
+                self.execute(event, 'user_domains', 'delete', key=key, id=id)
             elif new_row == old_row:
                 # Don't need to update this row.
                 del new_dict[id]
@@ -171,30 +160,30 @@
                 old_id, old_password, old_roles, old_domains = old_row
                 if old_password != password:
                     # Update the password.
-                    self.execute('users', 'update', key=key, id=id,
-                                 password=password)
+                    self.execute(event, 'users', 'update',
+                                 key=key, id=id, password=password)
             else:
                 # Insert a new record.
-                self.execute('users', 'insert', key=key, id=id,
-                             password=password)
+                self.execute(event, 'users', 'insert',
+                             key=key, id=id, password=password)
                 old_roles = ()
                 old_domains = ()
 
             # Update the role list.
             if tuple(roles) != tuple(old_roles):
-                self.execute('roles', 'delete', key=key, id=id)
+                self.execute(event, 'user_roles', 'delete', key=key, id=id)
                 for role in roles:
                     assert role
-                    self.execute('roles', 'insert', key=key, id=id,
-                                 role=role)
+                    self.execute(event, 'user_roles', 'insert',
+                                 key=key, id=id, role=role)
 
             # Update the domain list.
             if tuple(domains) != tuple(old_domains):
-                self.execute('domains', 'delete', key=key, id=id)
+                self.execute(event, 'user_domains', 'delete', key=key, id=id)
                 for domain in domains:
                     assert domain
-                    self.execute('domains', 'insert', key=key, id=id,
-                                 domain=domain)
+                    self.execute(event, 'user_domains', 'insert',
+                                 key=key, id=id, domain=domain)
                 
         state = list(state)
         state.sort()


=== Products/Ape/lib/apelib/sql/sqlbase.py 1.4 => 1.5 ===
--- Products/Ape/lib/apelib/sql/sqlbase.py:1.4	Sat May 17 20:47:01 2003
+++ Products/Ape/lib/apelib/sql/sqlbase.py	Sun May 18 00:16:29 2003
@@ -23,45 +23,34 @@
     schema = None       # override
     column_defs = None  # optional override
 
-    def __init__(self, conn):
-        self.conn = conn
-        self.setUpTableNames()
-        self.setUpQueries()
-        if conn.isConnected():
-            self.setUpTables()
-        else:
-            conn.addConnectCallback(self.setUpTables)
+    def __init__(self, conn_name='db'):
+        self.conn_name = conn_name
+        if self.column_defs is None:
+            schema = self.getSchema()
+            if schema is not None:
+                self.column_defs = schema.getColumnDefs()
 
     def getSchema(self):
         return self.schema
 
-    def getColumnDefs(self):
-        defs = self.column_defs
-        if defs is None:
-            defs = self.getSchema().getColumnDefs()
-        return defs
-
-    def setUpTableNames(self):
-        self.table = self.conn.prefix + '_' + self.table_base_name
-
-    def setUpQueries(self):
-        column_defs = self.getColumnDefs()
-        gen = self.conn.makeQueryGenerator(self.table, column_defs)
-        self.queries = gen.generateAll()
-
-    def setUpTables(self):
-        conn = self.conn
+    def setUp(self, event, clear_all=0):
+        conn = event.getConnection(self.conn_name)
         try:
-            self.execute('check')
+            self.execute(event, 'check')
         except conn.error:
             conn.db.rollback()
-            self.execute('create')
+            self.execute(event, 'create')
             conn.db.commit()
+        else:
+            if clear_all:
+                self.execute(event, 'clear')
 
-    def execute(self, query_name, *args, **kw):
-        query = self.queries[query_name]
-        return self.conn.execute(query, *args, **kw)
-
-    def clear(self):
-        self.execute('clear')
+    def execute(self, event, operation, *args, **kw):
+        conn = event.getConnection(self.conn_name)
+        query = conn.getQuery(
+            self.table_base_name, self.column_defs, operation)
+        if query == '':
+            # No query needed for this operation
+            return
+        return conn.execute(query, *args, **kw)
 


=== Products/Ape/lib/apelib/sql/structure.py 1.3 => 1.4 ===
--- Products/Ape/lib/apelib/sql/structure.py:1.3	Tue Apr 29 18:11:50 2003
+++ Products/Ape/lib/apelib/sql/structure.py	Sun May 18 00:16:29 2003
@@ -36,7 +36,7 @@
 
     def load(self, event):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         if items:
             state = items[0][0]
         else:
@@ -45,15 +45,16 @@
 
     def store(self, event, state):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         col_name = self.column_defs[0][0]
-        kw = {'key': key, col_name: self.conn.asBinary(state)}
+        conn = event.getConnection(self.conn_name)
+        kw = {'key': key, col_name: conn.asBinary(state)}
         if items:
             # update.
-            self.execute('update', **kw)
+            self.execute(event, 'update', **kw)
         else:
             # insert.
-            self.execute('insert', **kw)
+            self.execute(event, 'insert', **kw)
         return state
 
 
@@ -77,7 +78,7 @@
         keychain = event.getKeychain()
         key = long(keychain[-1])
         prefix = keychain[:-1]
-        rows = self.execute('read', 1, key=key)
+        rows = self.execute(event, 'read', 1, key=key)
         rows.sort()
         res = [(row[0], prefix + (long(row[1]),)) for row in rows]
         return res, tuple(res)
@@ -90,14 +91,14 @@
         for name, child_keychain in state:
             state_dict[name] = 1
 
-        rows = self.execute('read', 1, key=key)
+        rows = self.execute(event, 'read', 1, key=key)
         db_dict = {}
         for name, child_key in rows:
             if state_dict.has_key(name):
                 db_dict[name] = child_key
             else:
                 # Remove this item from the database.
-                self.execute('delete', key=key, name=name)
+                self.execute(event, 'delete', key=key, name=name)
 
         state = list(state)
         state.sort()
@@ -110,18 +111,18 @@
             if db_dict.has_key(name):
                 if db_dict[name] != child_key:
                     # Change this item to point to a different OID.
-                    self.execute('update', **kw)
+                    self.execute(event, 'update', **kw)
             else:
                 # Add this item to the database.
-                self.execute('insert', **kw)
+                self.execute(event, 'insert', **kw)
         return tuple(state)
 
 
 class SQLItemId (SQLGatewayBase):
     """SQL item ID gateway.
 
-    Piggybacks SQLFolderItems and makes the assumption that the item
-    is stored in only one place.
+    Piggybacks SQLFolderItems for setUp and store.
+    Makes the assumption that the item is stored in only one place.
     """
 
     __implements__ = IGateway
@@ -130,30 +131,20 @@
 
     table_base_name = 'folder_items'
 
-    def setUpQueries(self):
-        column_defs = (('name', 'string', 0),)
-        gen = self.conn.makeQueryGenerator(self.table, column_defs)
-        self.queries = {
-            'read': gen.generateRead(key_column_name='child_key'),
-            }
+    column_defs = (('child_key', 'int', 1),
+                   ('name', 'string', 0),)
 
-    def setUpTables(self):
-        # No action necessary
-        pass
-
-    def clear(self):
-        # Don't clear anything
+    def setUp(self, event, clear_all=0):
         pass
 
     def load(self, event):
         key = long(event.getKey())
-        rows = self.execute('read', 1, child_key=key)
+        rows = self.execute(event, 'simple_search', 1, child_key=key)
         assert len(rows) >= 1
-        name = rows[0][0]  # Other names will be ignored
+        name = rows[0][1]  # Accept only the first result
         return name, None
 
     def store(self, event, state):
-        # Assume that SQLFolderItems stored or will store the name.
         return None
 
 
@@ -184,7 +175,7 @@
 
     def load(self, event):
         key = long(event.getKey())
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         if items:
             state = long(items[0][0])
         else:
@@ -194,13 +185,13 @@
     def store(self, event, state):
         key = long(event.getKey())
         state = long(state)
-        items = self.execute('read', 1, key=key)
+        items = self.execute(event, 'read', 1, key=key)
         kw = {'key': key, 'mtime': state}
         if items:
             # update.
-            self.execute('update', **kw)
+            self.execute(event, 'update', **kw)
         else:
             # insert.
-            self.execute('insert', **kw)
+            self.execute(event, 'insert', **kw)
         return state