commit-gnue
[Top][All Lists]
Advanced

[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, \



reply via email to

[Prev in Thread] Current Thread [Next in Thread]