[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r7168 - in trunk/gnue-common/src/datasources/drivers: Base DBSIG2
From: |
reinhard |
Subject: |
[gnue] r7168 - in trunk/gnue-common/src/datasources/drivers: Base DBSIG2 |
Date: |
Fri, 11 Mar 2005 10:55:34 -0600 (CST) |
Author: reinhard
Date: 2005-03-11 10:55:32 -0600 (Fri, 11 Mar 2005)
New Revision: 7168
Modified:
trunk/gnue-common/src/datasources/drivers/Base/Connection.py
trunk/gnue-common/src/datasources/drivers/Base/RecordSet.py
trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py
trunk/gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py
Log:
Moved the actual code to insert, update, and delete data in the backend from
RecordSet to Connection. This will allow for writing to the database without
having to build a ResultSet first, which will speed up AppServer quite a bit.
Modified: trunk/gnue-common/src/datasources/drivers/Base/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/Connection.py
2005-03-11 13:36:58 UTC (rev 7167)
+++ trunk/gnue-common/src/datasources/drivers/Base/Connection.py
2005-03-11 16:55:32 UTC (rev 7168)
@@ -119,6 +119,60 @@
gLeave (8)
# ---------------------------------------------------------------------------
+ # Insert a new record in the backend
+ # ---------------------------------------------------------------------------
+
+ def insert (self, table, newfields, recno):
+ """
+ Insert a new record in the backend.
+
+ @param table: Table name.
+ @param newfields: Fieldname/Value dictionary of data to insert.
+ @param recno: Record number to be used in error messages.
+ """
+
+ gEnter (8)
+ self._insert (table, newfields, recno)
+ gLeave (8)
+
+ # ---------------------------------------------------------------------------
+ # Update an existing record in the backend
+ # ---------------------------------------------------------------------------
+
+ def update (self, table, oldfields, newfields, recno):
+ """
+ Update an existing record in the backend.
+
+ @param table: Table name.
+ @param oldfields: Fieldname/Value dictionary of fields to find the existing
+ record (aka where-clause)
+ @param newfields: Fieldname/Value dictionary of data to change.
+ @param recno: Record number to be used in error messages.
+ """
+
+ gEnter (8)
+ self._update (table, oldfields, newfields, recno)
+ gLeave (8)
+
+ # ---------------------------------------------------------------------------
+ # Delete a record from the backend
+ # ---------------------------------------------------------------------------
+
+ def delete (self, table, oldfields, recno):
+ """
+ Delete a record from the backend.
+
+ @param table: Table name.
+ @param oldfields: Fieldname/Value dictionary of fields to find the existing
+ record (aka where-clause)
+ @param recno: Record number to be used in error messages.
+ """
+
+ gEnter (8)
+ self._delete (table, oldfields, recno)
+ gLeave (8)
+
+ # ---------------------------------------------------------------------------
# Commit pending changes in the backend
# ---------------------------------------------------------------------------
Modified: trunk/gnue-common/src/datasources/drivers/Base/RecordSet.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/RecordSet.py 2005-03-11
13:36:58 UTC (rev 7167)
+++ trunk/gnue-common/src/datasources/drivers/Base/RecordSet.py 2005-03-11
16:55:32 UTC (rev 7168)
@@ -165,16 +165,7 @@
fn = field.lower ()
return self._modifiedFlags.has_key (fn)
- # ---------------------------------------------------------------------------
- def modifiedFields (self):
- """
- Return a list of all fields that have local modifications.
-
- @return: The list of field names
- """
- return self._modifiedFlags.keys ()
-
# ---------------------------------------------------------------------------
# Mark record as deleted
# ---------------------------------------------------------------------------
@@ -259,6 +250,25 @@
# ---------------------------------------------------------------------------
+ # Fields to be used in WHERE clauses for UPDATE and DELETE.
+ # ---------------------------------------------------------------------------
+
+ def __wherefields (self):
+
+ do = self._parent._dataObject
+
+ # Do we have a primary key?
+ if self._initialData.has_key (do._primaryIdField):
+ return {do._primaryIdField: self._initialData [do._primaryIdField]}
+ else:
+ result = {}
+ for field in self._initialData.keys ():
+ if self._parent.isFieldBound (field):
+ result [field] = self._initialData [field]
+ return result
+
+
+ # ---------------------------------------------------------------------------
# Post changes to database
# ---------------------------------------------------------------------------
@@ -297,6 +307,21 @@
self.post(recordNumber)
return
+ #
+ # Check for empty primary key and set with the sequence value if so
+ #
+ if self.isInserted():
+ do = self._parent._dataObject
+ if hasattr(do,'primarykey') and hasattr(do,'primarykeyseq'):
+ if do.primarykey and do.primarykeyseq and ',' not in do.primarykey and
\
+ hasattr(do._connection,'getsequence') and \
+ self.getField(do.primarykey) is None:
+ try:
+
self.setField(do.primarykey,do._connection.getsequence(do.primarykeyseq))
+ except do._connection._DatabaseError:
+ raise exceptions.InvalidDatasourceDefintion, \
+ errors.getException () [2]
+
if self.isPending():
gDebug (8, 'Posting datasource %s' % self._parent._dataObject.name)
self._postChanges (recordNumber)
@@ -384,33 +409,22 @@
elif self._insertFlag or self._updateFlag:
modifiedFields = {}
for field in self._modifiedFlags.keys ():
- modifiedFields [field] = self._fields [field]
+ if self._parent.isFieldBound (field):
+ modifiedFields [field] = self._fields [field]
if self._insertFlag:
self._postInsert (modifiedFields)
else:
self._postUpdate (modifiedFields)
+ # The record is now "clean" again
+ self._insertFlag = False
+ self._updateFlag = False
self._modifiedFlags = {}
+ self._initialData = self._fields.copy ()
- self._deleteFlag = False
- self._insertFlag = False
- self._updateFlag = False
-
# ---------------------------------------------------------------------------
- def _postDelete (self):
- """
- Post a deletion to the backend. Descendants should override this function
- (or the general _postChanges function).
-
- _postDelete is guaranteed to be only called for records that pend a
- deletion.
- """
- pass
-
- # ---------------------------------------------------------------------------
-
def _postInsert (self, fields):
"""
Post an insert to the backend. Descendants should override this function
@@ -422,7 +436,9 @@
@param fields: a dictionary with field names as keys and field values as
values.
"""
- pass
+ do = self._parent._dataObject
+ # FIXME: recno is missing
+ do._connection.insert (do.table, fields, 0)
# ---------------------------------------------------------------------------
@@ -437,4 +453,20 @@
@param fields: a dictionary with field names as keys and field values as
values.
"""
- pass
+ do = self._parent._dataObject
+ # FIXME: recno is missing
+ do._connection.update (do.table, self.__wherefields (), fields, 0)
+
+ # ---------------------------------------------------------------------------
+
+ def _postDelete (self):
+ """
+ Post a deletion to the backend. Descendants should override this function
+ (or the general _postChanges function).
+
+ _postDelete is guaranteed to be only called for records that pend a
+ deletion.
+ """
+ do = self._parent._dataObject
+ # FIXME: recno is missing
+ do._connection.delete (do.table, self.__wherefields (), 0)
Modified: trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py
2005-03-11 13:36:58 UTC (rev 7167)
+++ trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py
2005-03-11 16:55:32 UTC (rev 7168)
@@ -80,6 +80,7 @@
# FIXME: Should be private
self.native = None
+
# ---------------------------------------------------------------------------
# Convert type into what the DBSIG2 driver wants as parameter
# ---------------------------------------------------------------------------
@@ -344,6 +345,42 @@
# ---------------------------------------------------------------------------
+ # Build WHERE-Clause based on a dictionary of fieldname/value pairs
+ # ---------------------------------------------------------------------------
+
+ def __where (self, oldfields):
+
+ where = []
+ parameters = {}
+ for (field, value) in oldfields.items ():
+ if value is None:
+ where.append ("%s IS NULL" % field)
+ else:
+ key = 'old_' + field
+ where.append ("%s=%%(%s)s" % (field, key))
+ parameters [key] = value
+
+ return (string.join (where, ' AND '), parameters)
+
+
+ # ---------------------------------------------------------------------------
+ # Execute an insert, update, or delete statement
+ # ---------------------------------------------------------------------------
+
+ def __execute (self, statement, parameters, recno):
+
+ try:
+ self.sql (statement, parameters)
+ except self._driver.DatabaseError:
+ if recno:
+ raise Exceptions.ConnectionError, \
+ "\nERROR POSTING RECORD # %s\n\n%s" % (recno,
+ errors.getException () [2])
+ else:
+ raise Exceptions.ConnectionError, errors.getException () [2]
+
+
+ # ---------------------------------------------------------------------------
# This method has to be overwritten by descendants
# ---------------------------------------------------------------------------
@@ -376,6 +413,43 @@
# ---------------------------------------------------------------------------
+ def _insert (self, table, newfields, recno):
+ fields = []
+ values = []
+ parameters = {}
+ for (field, value) in newfields.items ():
+ key = 'new_' + field
+ fields.append (field)
+ values.append ('%%(%s)s' % key)
+ parameters [key] = value
+ statement = "INSERT INTO %s (%s) VALUES (%s)" % (table,
+ string.join (fields,', '),
+ string.join (values,', '))
+ self.__execute (statement, parameters, recno)
+
+ # ---------------------------------------------------------------------------
+
+ def _update (self, table, oldfields, newfields, recno):
+ (where, parameters) = self.__where (oldfields)
+ updates = []
+ for (field, value) in newfields.items ():
+ key = 'new_' + field
+ updates.append ("%s=%%(%s)s" % (field, key))
+ parameters [key] = value
+ statement = "UPDATE %s SET %s WHERE %s" % (table,
+ string.join (updates, ', '),
+ where)
+ self.__execute (statement, parameters, recno)
+
+ # ---------------------------------------------------------------------------
+
+ def _delete (self, table, oldfields, recno):
+ (where, parameters) = self.__where (oldfields)
+ statement = 'DELETE FROM %s WHERE %s' % (table, where)
+ self.__execute (statement, parameters, recno)
+
+ # ---------------------------------------------------------------------------
+
def _commit (self):
try:
self.native.commit ()
Modified: trunk/gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py
2005-03-11 13:36:58 UTC (rev 7167)
+++ trunk/gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py
2005-03-11 16:55:32 UTC (rev 7168)
@@ -37,187 +37,6 @@
#
class RecordSet(Base.RecordSet):
- def _postChanges(self, recordNumber=None):
- do = self._parent._dataObject
- if not self.isPending(): return
-
- if self._deleteFlag:
- s = self._buildDeleteStatement()
- elif self._insertFlag:
- #
- # Check for empty primary key and set with the sequence value if so
- #
- if hasattr(do,'primarykey') and hasattr(do,'primarykeyseq'):
- if do.primarykey and do.primarykeyseq and ',' not in do.primarykey and
\
- hasattr(do._connection,'getsequence') and \
- self.getField(do.primarykey) is None:
- try:
-
self.setField(do.primarykey,do._connection.getsequence(do.primarykeyseq))
- except do._connection._DatabaseError:
- raise exceptions.InvalidDatasourceDefintion, \
- errors.getException () [2]
- s = self._buildInsertStatement()
- elif self._updateFlag:
- s = self._buildUpdateStatement()
-
- else:
- # The record does not has a direct modification, so isPending () returns
- # True because a detail-record has pending changes
- return
-
- if isinstance (s, types.TupleType):
- # when useParameters is not set
- (statement, parameters) = s
- else:
- # when useParameters is set
- (statement, parameters) = (s, None)
-
- gDebug (8, "_postChanges: statement=%s" % statement)
-
- try:
- do._connection.sql (statement, parameters)
-
- # Set _initialData to be the just-now posted values
- if not self._deleteFlag:
- self._initialData = {}
- self._initialData.update(self._fields)
-
- except do._connection._DatabaseError, err:
- if recordNumber:
- raise Exceptions.ConnectionError, "\nERROR POSTING RECORD # %s\n\n%s"
% (recordNumber,errors.getException () [2])
- else:
- raise Exceptions.ConnectionError, errors.getException () [2]
-
- self._updateFlag = False
- self._insertFlag = False
- self._deleteFlag = False
-
- return True
-
-
- # If a vendor can do any of these more efficiently (i.e., use a known
- # PRIMARY KEY or ROWID, then override these methods. Otherwise, leave
- # as default. Note that these functions are specific to DB-SIG based
- # drivers (i.e., these functions are not in the base RecordSet class)
-
- # This function is only used with "useParameters" set in gnue.conf
- def _where (self):
- do = self._parent._dataObject
- if self._initialData.has_key(do._primaryIdField):
- where = [do._primaryIdFormat % \
- self._initialData [do._primaryIdField]]
- parameters = {}
- else:
- where = []
- parameters = {}
- for field in self._initialData.keys ():
- if self._parent.isFieldBound (field):
- if self._initialData [field] == None:
- where.append ("%s IS NULL" % field)
- else:
- key = 'old_' + field
- where.append ("%s=%%(%s)s" % (field, key))
- parameters [key] = self._initialData [field]
-
- return (join (where, ' AND '), parameters)
-
- def _buildDeleteStatement(self):
- do = self._parent._dataObject
- if gConfig ('useParameters'):
- (where, parameters) = self._where ()
- statement = 'DELETE FROM %s WHERE %s' % \
- (do.table, where)
- return (statement, parameters)
- else:
- if self._initialData.has_key(do._primaryIdField):
- where = [do._primaryIdFormat % \
- self._initialData[do._primaryIdField] ]
- else:
- where = []
- for field in self._initialData.keys():
- if self._parent.isFieldBound(field):
- if self._initialData[field] == None:
- where.append ("%s IS NULL" % field)
- else:
- where.append ("%s=%s" % (field,
- do._toSqlString(self._initialData[field])))
-
- statement = "DELETE FROM %s WHERE %s" % \
- (do.table, join(where,' AND ') )
- return statement
-
- def _buildInsertStatement(self):
- do = self._parent._dataObject
- if gConfig ('useParameters'):
- fields = []
- values = []
- parameters = {}
-
- for field in self._modifiedFlags.keys ():
- if self._parent.isFieldBound (field):
- key = 'new_' + field
- fields.append (field)
- values.append ('%%(%s)s' % key)
- parameters [key] = self._fields [field]
-
- statement = "INSERT INTO %s (%s) VALUES (%s)" % \
- (do.table,
- join (fields,', '),
- join (values,', '))
-
- return (statement, parameters)
- else:
- vals = []
- fields = []
-
- for field in self._modifiedFlags.keys():
- if self._parent.isFieldBound(field):
- fields.append (field)
- if self._fields[field] == None or self._fields[field] == '':
- vals.append ("NULL") # % (self._fields[field]))
- else:
- vals.append (do._toSqlString(self._fields[field]))
-
- return "INSERT INTO %s (%s) VALUES (%s)" % \
- (do.table, join(fields,','), \
- join(vals,',') )
-
- def _buildUpdateStatement(self):
- do = self._parent._dataObject
- if gConfig ('useParameters'):
- (where, parameters) = self._where ()
- updates = []
- for field in self._modifiedFlags.keys():
- key = 'new_' + field
- updates.append ("%s=%%(%s)s" % (field, key))
- parameters[key] = self._fields [field]
-
- statement = "UPDATE %s SET %s WHERE %s" % \
- (do.table,
- join(updates, ', '),
- where)
- return (statement, parameters)
- else:
- updates = []
- for field in self._modifiedFlags.keys():
- updates.append ("%s=%s" % (field,
- do._toSqlString(self._fields[field])))
-
- if do._primaryIdField:
- where = [do._primaryIdFormat % \
- self._initialData[do._primaryIdField] ]
- else:
- where = []
- for field in self._initialData.keys():
- if self._initialData[field] == None:
- where.append ("%s IS NULL" % field)
- else:
- where.append ("%s=%s" % (field,
do._toSqlString(self._initialData[field])))
-
- return "UPDATE %s SET %s WHERE %s" % \
- (do.table, join(updates,','), \
- join(where,' AND ') )
-
def _requery(self):
"""
Requery a posted record to capture any changes made by the database
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r7168 - in trunk/gnue-common/src/datasources/drivers: Base DBSIG2,
reinhard <=