[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gnue/common/src/dbdrivers _dbsig/DBdriver.py _p...
From: |
Jason Cater |
Subject: |
gnue/common/src/dbdrivers _dbsig/DBdriver.py _p... |
Date: |
Tue, 26 Feb 2002 18:07:27 -0500 |
CVSROOT: /cvsroot/gnue
Module name: gnue
Changes by: Jason Cater <address@hidden> 02/02/26 18:07:27
Modified files:
common/src/dbdrivers/_dbsig: DBdriver.py
common/src/dbdrivers/_pgsql: DBdriver.py
common/src/dbdrivers/cxoracle: DBdriver.py
Log message:
added code to escape single quotes within strings in SQL statements;
added ROWID support to Oracle drivers (for delete/update records)
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/dbdrivers/_dbsig/DBdriver.py.diff?tr1=1.36&tr2=1.37&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/dbdrivers/_pgsql/DBdriver.py.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/dbdrivers/cxoracle/DBdriver.py.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
Patches:
Index: gnue/common/src/dbdrivers/_dbsig/DBdriver.py
diff -c gnue/common/src/dbdrivers/_dbsig/DBdriver.py:1.36
gnue/common/src/dbdrivers/_dbsig/DBdriver.py:1.37
*** gnue/common/src/dbdrivers/_dbsig/DBdriver.py:1.36 Sun Feb 17 13:25:31 2002
--- gnue/common/src/dbdrivers/_dbsig/DBdriver.py Tue Feb 26 18:07:27 2002
***************
*** 3,28 ****
#
# This file is part of GNU Enterprise.
#
! # GNU Enterprise is free software; you can redistribute it
! # and/or modify it under the terms of the GNU General Public
! # License as published by the Free Software Foundation; either
# version 2, or (at your option) any later version.
#
! # GNU Enterprise is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
! # You should have received a copy of the GNU General Public
# License along with program; see the file COPYING. If not,
! # write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
# FILE:
# _dbsig/DBdriver.py
#
# DESCRIPTION:
! # Generic implementation of dbdriver using Python DB-SIG v2
# specification.
#
# NOTES:
--- 3,28 ----
#
# This file is part of GNU Enterprise.
#
! # GNU Enterprise is free software; you can redistribute it
! # and/or modify it under the terms of the GNU General Public
! # License as published by the Free Software Foundation; either
# version 2, or (at your option) any later version.
#
! # GNU Enterprise is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
! # You should have received a copy of the GNU General Public
# License along with program; see the file COPYING. If not,
! # write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
# FILE:
# _dbsig/DBdriver.py
#
# DESCRIPTION:
! # Generic implementation of dbdriver using Python DB-SIG v2
# specification.
#
# NOTES:
***************
*** 36,43 ****
from gnue.common import GDebug
import types
! class DBSIG_RecordSet(GDataObjects.RecordSet):
! def _postChanges(self):
if not self.isPending(): return
if self._deleteFlag:
statement = self._buildDeleteStatement()
--- 36,47 ----
from gnue.common import GDebug
import types
! class DBSIG_RecordSet(GDataObjects.RecordSet):
!
! def _escapeString(self, value):
! return string.replace(value,"'","%s'" %
self._parent._dataObject._escapeSingleQuote)
!
! def _postChanges(self):
if not self.isPending(): return
if self._deleteFlag:
statement = self._buildDeleteStatement()
***************
*** 48,60 ****
GDebug.printMesg(5, "_postChanges: statement=%s" % statement)
! try:
self._parent._update_cursor.execute(statement)
# Set _initialData to be the just-now posted values
! if not self._deleteFlag:
self._initialData = {}
! for key in self._fields.keys():
self._initialData[key] = self._fields[key]
except self._parent._dataObject._DatabaseError, err:
--- 52,64 ----
GDebug.printMesg(5, "_postChanges: statement=%s" % statement)
! try:
self._parent._update_cursor.execute(statement)
# Set _initialData to be the just-now posted values
! if not self._deleteFlag:
self._initialData = {}
! for key in self._fields.keys():
self._initialData[key] = self._fields[key]
except self._parent._dataObject._DatabaseError, err:
***************
*** 65,71 ****
self._deleteFlag = 0
return 1
!
# 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
--- 69,75 ----
self._deleteFlag = 0
return 1
!
# 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
***************
*** 73,81 ****
# drivers (i.e., these functions are not in the base RecordSet class)
def _buildDeleteStatement(self):
! if self._initialData.has_key(self._parent._primaryIdField):
! where = [self._parent._primaryIdFormat % \
! self._initialData[self._parent._primaryIdField] ]
else:
where = []
for field in self._initialData.keys():
--- 77,85 ----
# drivers (i.e., these functions are not in the base RecordSet class)
def _buildDeleteStatement(self):
! if self._initialData.has_key(self._parent._dataObject._primaryIdField):
! where = [self._parent._dataObject._primaryIdFormat % \
! self._initialData[self._parent._dataObject._primaryIdField] ]
else:
where = []
for field in self._initialData.keys():
***************
*** 83,95 ****
if self._initialData[field] == None:
where.append ("%s IS NULL" % field)
else:
! where.append ("%s='%s'" % (field, self._initialData[field]))
statement = "DELETE FROM %s WHERE %s" % \
(self._parent._dataObject.table, string.join(where,' AND ') )
return statement
! def _buildInsertStatement(self):
vals = []
fields = []
--- 87,99 ----
if self._initialData[field] == None:
where.append ("%s IS NULL" % field)
else:
! where.append ("%s='%s'" % (field,
self._escapeString(self._initialData[field])))
statement = "DELETE FROM %s WHERE %s" % \
(self._parent._dataObject.table, string.join(where,' AND ') )
return statement
! def _buildInsertStatement(self):
vals = []
fields = []
***************
*** 99,105 ****
if self._fields[field] == None or self._fields[field] == '':
vals.append ("NULL") # % (self._fields[field]))
else:
! vals.append ("'%s'" % (self._fields[field]))
return "INSERT INTO %s (%s) VALUES (%s)" % \
(self._parent._dataObject.table, string.join(fields,','), \
--- 103,109 ----
if self._fields[field] == None or self._fields[field] == '':
vals.append ("NULL") # % (self._fields[field]))
else:
! vals.append ("'%s'" % self._escapeString(self._fields[field]))
return "INSERT INTO %s (%s) VALUES (%s)" % \
(self._parent._dataObject.table, string.join(fields,','), \
***************
*** 108,132 ****
def _buildUpdateStatement(self):
updates = []
for field in self._modifiedFlags.keys():
! updates.append ("%s='%s'" % (field, self._fields[field]))
! if self._initialData.has_key(self._parent._primaryIdField):
! where = [self._parent._primaryIdFormat % \
! self._initialData[self._parent._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, self._initialData[field]))
return "UPDATE %s SET %s WHERE %s" % \
(self._parent._dataObject.table, string.join(updates,','), \
string.join(where,' AND ') )
! class DBSIG_ResultSet(GDataObjects.ResultSet):
def __init__(self, dataObject, cursor=None, \
defaultValues={}, masterRecordSet=None):
GDataObjects.ResultSet.__init__(
--- 112,136 ----
def _buildUpdateStatement(self):
updates = []
for field in self._modifiedFlags.keys():
! updates.append ("%s='%s'" % (field,
self._escapeString(self._fields[field])))
! if self._parent._dataObject._primaryIdField:
! where = [self._parent._dataObject._primaryIdFormat % \
! self._initialData[self._parent._dataObject._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,
self._escapeString(self._initialData[field])))
return "UPDATE %s SET %s WHERE %s" % \
(self._parent._dataObject.table, string.join(updates,','), \
string.join(where,' AND ') )
! class DBSIG_ResultSet(GDataObjects.ResultSet):
def __init__(self, dataObject, cursor=None, \
defaultValues={}, masterRecordSet=None):
GDataObjects.ResultSet.__init__(
***************
*** 141,155 ****
self._recordCount = cursor.rowcount or 0
- # If a DB driver supports a unique identifier for rows,
- # list it here. _primaryIdField is the field name (lower case)
- # that would appear in the recordset (note that this can be
- # a system generated format). If a primary id is supported,
- # _primaryIdFormat is the WHERE clause to be used. It will have
- # the string % (fieldvalue) format applied to it.
- self._primaryIdField = None
- self._primaryIdFormat = "__gnue__ = '%s'"
-
GDebug.printMesg(5, 'ResultSet created')
def _loadNextRecord(self):
--- 145,150 ----
***************
*** 193,199 ****
'div': (2, 999, '(%s)', '/' ),
'and': (1, 999, '(%s)', ' AND ' ),
'or': (2, 999, '(%s)', ' OR ' ),
! 'not': (1, 1, '(NOT %s)', None ),
'negate': (1, 1, '-%s', None ),
'eq': (2, 2, '(%s = %s)', None ),
'ne': (2, 2, '(%s != %s)', None ),
--- 188,194 ----
'div': (2, 999, '(%s)', '/' ),
'and': (1, 999, '(%s)', ' AND ' ),
'or': (2, 999, '(%s)', ' OR ' ),
! 'not': (1, 1, '(NOT %s)', None ),
'negate': (1, 1, '-%s', None ),
'eq': (2, 2, '(%s = %s)', None ),
'ne': (2, 2, '(%s != %s)', None ),
***************
*** 210,226 ****
--- 205,249 ----
GDebug.printMesg (1,"DB-SIG database driver backend initializing")
+ # This should be set to the Single Quote escape character
+ # (typically either "'" or "\"
+ self._escapeSingleQuote = "'"
self._resultSetClass = DBSIG_ResultSet
self._DatabaseError = None
self._strictQueryCount = strictQueryCount
+ # If a DB driver supports a unique identifier for rows,
+ # list it here. _primaryIdField is the field name (lower case)
+ # that would appear in the recordset (note that this can be
+ # a system generated format). If a primary id is supported,
+ # _primaryIdFormat is the WHERE clause to be used. It will have
+ # the string % (fieldvalue) format applied to it.
+ #
+ # See Oracle drivers for example
+ self._primaryIdField = None # Internal recordset field name
(lowercase!!!)
+ self._primaryIdSelect = "" # Select clause
+ self._primaryIdFormat = "__gnue__ = '%s'" # Where clause format
+
+ # Internal flag to avoid consistently doing the same check
+ # If this is set to 1 initially, then the
+ self._primaryIdChecked = 1 # Internal flag
+
# This should be over-ridden only if driver needs more than user/pass
def getLoginFields(self):
return [['_username', 'User Name',0],['_password', 'Password',1]]
+ # Used by drivers with a unique id (like rowid) (see Oracle for example)
+ def _checkForPrimaryId(self):
+ self._primaryIdChecked = 1
+
+
def _createResultSet(self, conditions={}, readOnly=0, masterRecordSet=None):
+
+ # Used by drivers with a unique id (like rowid)
+ if not self._primaryIdChecked: self._checkForPrimaryId()
+
try:
cursor = self._dataConnection.cursor()
***************
*** 233,238 ****
--- 256,262 ----
except self._DatabaseError, err:
raise GDataObjects.ConnectionError, err
+
rs = self._resultSetClass(self, cursor=cursor,
masterRecordSet=masterRecordSet)
if self._strictQueryCount:
rs._recordCount = recordCount
***************
*** 250,256 ****
def commit(self):
GDebug.printMesg (5,"DB-SIG database driver: commit()")
!
try:
self._dataConnection.commit()
except self._DatabaseError, value:
--- 274,280 ----
def commit(self):
GDebug.printMesg (5,"DB-SIG database driver: commit()")
!
try:
self._dataConnection.commit()
except self._DatabaseError, value:
***************
*** 312,318 ****
return "%s" % element.value
else:
return "'%s'" % element.value
! elif otype == 'param':
v = element.getValue()
return (v == None and "NULL") or ("'%s'" % element.getValue())
elif self.conditionElements.has_key(otype):
--- 336,342 ----
return "%s" % element.value
else:
return "'%s'" % element.value
! elif otype == 'param':
v = element.getValue()
return (v == None and "NULL") or ("'%s'" % element.getValue())
elif self.conditionElements.has_key(otype):
***************
*** 351,362 ****
def _buildQuery(self, conditions={}):
GDebug.printMesg(7,'Implicit Fields: %s' % self._fieldReferences)
if len(self._fieldReferences):
! q = "SELECT %s FROM %s%s" % \
! (string.join(self._fieldReferences.keys(),","), self.table,
self._conditionToSQL(conditions))
else:
! q = "SELECT * FROM %s%s" % (self.table,
self._conditionToSQL(conditions))
if hasattr(self,'order_by'):
q = "%s ORDER BY %s " % (q, self.order_by)
--- 375,391 ----
def _buildQuery(self, conditions={}):
GDebug.printMesg(7,'Implicit Fields: %s' % self._fieldReferences)
+ if self._primaryIdSelect:
+ pis = "%s," % self._primaryIdSelect
+ else:
+ pis = ""
if len(self._fieldReferences):
! q = "SELECT %s%s FROM %s%s" % \
! (pis, string.join(self._fieldReferences.keys(),","), self.table,
self._conditionToSQL(conditions))
else:
! q = "SELECT %s,* FROM %s%s" % (pis,self.table,
! self._conditionToSQL(conditions))
if hasattr(self,'order_by'):
q = "%s ORDER BY %s " % (q, self.order_by)
***************
*** 373,383 ****
return q
class DBSIG_DataObject_SQL:
! def _buildQuery(self, conditions={}):
# Obviously, this is in a pre-alpha state :)
return "select zipcode, city, state from zipcode order by zipcode desc"
! supportedDataObjects = {
'object': DBSIG_DataObject_Object,
'sql': DBSIG_DataObject_SQL
}
--- 402,412 ----
return q
class DBSIG_DataObject_SQL:
! def _buildQuery(self, conditions={}):
# Obviously, this is in a pre-alpha state :)
return "select zipcode, city, state from zipcode order by zipcode desc"
! supportedDataObjects = {
'object': DBSIG_DataObject_Object,
'sql': DBSIG_DataObject_SQL
}
Index: gnue/common/src/dbdrivers/_pgsql/DBdriver.py
diff -c gnue/common/src/dbdrivers/_pgsql/DBdriver.py:1.10
gnue/common/src/dbdrivers/_pgsql/DBdriver.py:1.11
*** gnue/common/src/dbdrivers/_pgsql/DBdriver.py:1.10 Mon Feb 11 22:29:05 2002
--- gnue/common/src/dbdrivers/_pgsql/DBdriver.py Tue Feb 26 18:07:27 2002
***************
*** 23,29 ****
#
# DESCRIPTION:
# A core Postgresql implementation of dbdriver the other
! # postgresql drivers can extend
#
# NOTES:
#
--- 23,29 ----
#
# DESCRIPTION:
# A core Postgresql implementation of dbdriver the other
! # postgresql drivers can extend
#
# NOTES:
#
***************
*** 51,56 ****
--- 51,57 ----
def __init__(self, pgdriver=None, pgresultset=None):
DBSIG_DataObject.__init__(self)
self._connectString = 'host=%s dbname=%s user=%s password=%s'
+ self._escapeSingleQuote = r'\'
if pgdriver:
self._pgdriver = pgdriver
self._DatabaseError = self._pgdriver.DatabaseError
***************
*** 77,89 ****
GDebug.printMesg(1,"Exception %s " % value)
raise GDataObjects.LoginError, value
! try:
encoding = connectData['encoding']
GDebug.printMesg(1,'Setting postgresql client_encoding to %s' %
encoding)
cursor = self._dataConnection.cursor()
cursor.execute("SET CLIENT_ENCODING TO '%s'" % encoding)
cursor.close()
! except KeyError:
pass
except self._DatabaseError:
try:
--- 78,90 ----
GDebug.printMesg(1,"Exception %s " % value)
raise GDataObjects.LoginError, value
! try:
encoding = connectData['encoding']
GDebug.printMesg(1,'Setting postgresql client_encoding to %s' %
encoding)
cursor = self._dataConnection.cursor()
cursor.execute("SET CLIENT_ENCODING TO '%s'" % encoding)
cursor.close()
! except KeyError:
pass
except self._DatabaseError:
try:
Index: gnue/common/src/dbdrivers/cxoracle/DBdriver.py
diff -c gnue/common/src/dbdrivers/cxoracle/DBdriver.py:1.8
gnue/common/src/dbdrivers/cxoracle/DBdriver.py:1.9
*** gnue/common/src/dbdrivers/cxoracle/DBdriver.py:1.8 Thu Jan 17 19:11:28 2002
--- gnue/common/src/dbdrivers/cxoracle/DBdriver.py Tue Feb 26 18:07:27 2002
***************
*** 65,70 ****
--- 65,72 ----
self._DatabaseError = SIG2api.DatabaseError
self._resultSetClass = Oracle_ResultSet
+ self._primaryIdChecked = 0
+
def connect(self, connectData={}):
GDebug.printMesg(1,"Oracle database driver initializing")
***************
*** 79,86 ****
self._postConnect()
-
-
class Oracle_DataObject_Object(Oracle_DataObject, \
DBSIG_DataObject_Object):
--- 81,86 ----
***************
*** 89,94 ****
--- 89,112 ----
def _buildQuery(self, conditions={}):
return DBSIG_DataObject_Object._buildQuery(self, conditions)
+
+ def _checkForPrimaryId(self):
+
+ self._primaryIdChecked = 1
+
+ try:
+ statement = "select rowidtochar(rowid) from %s where 1=2" % self.table
+ cursor = self._dataConnection.cursor()
+ cursor.execute(statement)
+ cursor.close()
+
+ self._primaryIdSelect = "ROWIDTOCHAR(ROWID) as GNUE__ROWID__"
+ self._primaryIdField = "gnue__rowid__" # Keep this lowercase!!!
+ self._primaryIdFormat = "ROWID = CHARTOROWID('%s')"
+ GDebug.printMesg(5,'View %s is using ROWID identifier' % self.table)
+
+ except self._DatabaseError:
+ GDebug.printMesg (5, 'View %s has no internal ROWID' % self.table)
class Oracle_DataObject_SQL(Oracle_DataObject, \
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- gnue/common/src/dbdrivers _dbsig/DBdriver.py _p...,
Jason Cater <=