[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
CVSROOT: /cvsroot/gnue
From: |
Jason Cater |
Subject: |
CVSROOT: /cvsroot/gnue |
Date: |
Tue, 18 Nov 2003 21:07:10 -0500 |
Module name: gnue-common
Branch: datasource-cleanup
Changes by: Jason Cater <address@hidden> 03/11/18 21:07:09
Reply-to: address@hidden
CVSROOT: /cvsroot/gnue
Module name: gnue-common
Branch: datasource-cleanup
Changes by: Jason Cater <address@hidden> 03/11/18 21:07:09
Modified files:
src/datasources: GConnections.py GDataObjects.py
src/datasources/drivers/Base: __init__.py
src/datasources/drivers/DBSIG2: Connection.py DataObject.py
RecordSet.py ResultSet.py
src/datasources/drivers/adodbapi/adodbapi: Connection.py
src/datasources/drivers/appserver/appserver: Connection.py
DataObject.py
RecordSet.py
ResultSet.py
src/datasources/drivers/db2/db2: Connection.py
src/datasources/drivers/dbf/dbf: Connection.py
src/datasources/drivers/gadfly/gadfly: Connection.py
src/datasources/drivers/informix/informix: Connection.py
src/datasources/drivers/ingres/ingres: Connection.py
src/datasources/drivers/mysql/mysql: Connection.py
src/datasources/drivers/oracle/Base: Connection.py
src/datasources/drivers/postgresql/Base: Connection.py
DataObject.py
src/datasources/drivers/postgresql/pypgsql: Driver.py
src/datasources/drivers/sapdb/sapdb: Connection.py
src/datasources/drivers/sqlite/sqlite: Connection.py
src/datasources/drivers/sqlrelay/sqlrelay: Connection.py
src/datasources/drivers/sybase/sybase: Connection.py
Added files:
src/datasources: Exceptions.py
src/datasources/drivers/Base: Connection.py DataObject.py
RecordSet.py ResultSet.py
Removed files:
src/datasources/drivers/DBSIG2: Driver.py
Log message:
got the datasource changes working with gnue-forms
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/Exceptions.py?only_with_tag=datasource-cleanup&rev=1.1.2.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/GConnections.py.diff?only_with_tag=datasource-cleanup&tr1=1.52.2.3&tr2=1.52.2.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/GDataObjects.py.diff?only_with_tag=datasource-cleanup&tr1=1.72.2.2&tr2=1.72.2.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/Base/Connection.py?only_with_tag=datasource-cleanup&rev=1.1.2.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/Base/DataObject.py?only_with_tag=datasource-cleanup&rev=1.1.2.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/Base/RecordSet.py?only_with_tag=datasource-cleanup&rev=1.1.2.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/Base/ResultSet.py?only_with_tag=datasource-cleanup&rev=1.1.2.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/Base/__init__.py.diff?only_with_tag=datasource-cleanup&tr1=1.1&tr2=1.1.2.1&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/DBSIG2/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/DBSIG2/DataObject.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.3&tr2=1.1.2.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/DBSIG2/ResultSet.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.2&tr2=1.1.2.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/adodbapi/adodbapi/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.3&tr2=1.1.2.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.2&tr2=1.1.2.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.2&tr2=1.1.2.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/appserver/appserver/ResultSet.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/db2/db2/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/dbf/dbf/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/gadfly/gadfly/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/informix/informix/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.2&tr2=1.1.2.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/ingres/ingres/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/mysql/mysql/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.2&tr2=1.1.2.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/oracle/Base/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/postgresql/Base/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.3&tr2=1.1.2.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/postgresql/Base/DataObject.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/postgresql/pypgsql/Driver.py.diff?only_with_tag=datasource-cleanup&tr1=1.35.2.2&tr2=1.35.2.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/sapdb/sapdb/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/sqlrelay/sqlrelay/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/datasources/drivers/sybase/sybase/Connection.py.diff?only_with_tag=datasource-cleanup&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
Patches:
Index: gnue-common/src/datasources/Exceptions.py
diff -c /dev/null gnue-common/src/datasources/Exceptions.py:1.1.2.1
*** /dev/null Tue Nov 18 21:07:09 2003
--- gnue-common/src/datasources/Exceptions.py Tue Nov 18 21:07:06 2003
***************
*** 0 ****
--- 1,80 ----
+ #
+ # 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.
+ #
+ # Copyright 2000-2003 Free Software Foundation
+ #
+ # FILE:
+ # GDataObjects.py
+ #
+ # DESCRIPTION:
+ # This is a temporary backwards compatability file.
+ # Should be removed at some point.
+ #
+ # NOTES:
+ #
+
+ class Error(StandardError):
+ # Base exception
+ pass
+
+ class LoginError(Error):
+ # Raised when invalid login user/pass was provided
+ # Client should attempt to get better information and
+ # try again
+ pass
+
+ class ConnectError(Error):
+ # Raised when connection data is invalid (e.g., host not found, etc).
+ # Client should probably not attempt to relogin. Exit gracefully
+ # with a reason.
+ pass
+
+ class ProviderNotSupportedError(Error):
+ # Raised when a datasource type is requested that the dbdriver
+ # does not support (e.g., not all dbdrivers support raw sql mode.)
+ pass
+
+ class ObjectTypeNotAvailableError(Error):
+ # Raised when a datasource type is requested that the dbdriver
+ # does not support (e.g., not all dbdrivers support raw sql mode.)
+ pass
+
+ class ReadOnlyError(Error):
+ # Raised when an attempt is made to update a read-only data object.
+ pass
+
+ class MasterDetailFieldMismatch(Error):
+ # Raised when a the number of master fields doesn't match the
+ # number of detail fields. (e.g., masterlink="id,subid"
+ # and detaillink="id" would be a problem; must be 1:1)
+ pass
+
+ class ConnectionError(Error):
+ # Generic error reading from the database connection
+ pass
+
+ class DataTypeNotAvailable(Error):
+ # Raised when a datatype is not supported by an database
+ # during writing a schema definition to the database
+ pass
+
+ class NoWriteSchemaSupport(Error):
+ # Raised when a database adapter doesn't support
+ # writing Schema to datasource
+ pass
+
Index: gnue-common/src/datasources/GConnections.py
diff -c gnue-common/src/datasources/GConnections.py:1.52.2.3
gnue-common/src/datasources/GConnections.py:1.52.2.4
*** gnue-common/src/datasources/GConnections.py:1.52.2.3 Tue Nov 18
19:01:05 2003
--- gnue-common/src/datasources/GConnections.py Tue Nov 18 21:07:06 2003
***************
*** 33,39 ****
from ConfigParser import *
import sys, string, copy, netrc
from gnue.common.apps import GDebug
! from gnue.common.datasources import GDataObjects
from gnue.common.datasources import GLoginHandler
from gnue.common.datasources.drivers import DRIVERS as ALLDRIVERS
from gnue.common.utils.FileUtils import openResource, dyn_import
--- 33,39 ----
from ConfigParser import *
import sys, string, copy, netrc
from gnue.common.apps import GDebug
! from gnue.common.datasources import Exceptions
from gnue.common.datasources import GLoginHandler
from gnue.common.datasources.drivers import DRIVERS as ALLDRIVERS
from gnue.common.utils.FileUtils import openResource, dyn_import
***************
*** 56,62 ****
# in an unreadable format.
pass
! LoginError = GDataObjects.LoginError
class GConnections:
--- 56,62 ----
# in an unreadable format.
pass
! LoginError = Exceptions.LoginError
class GConnections:
***************
*** 185,191 ****
def getConnection(self, connection_name):
- print "getConnection: %s" % (connection_name)
connection_name = connection_name.lower()
--- 185,190 ----
***************
*** 201,208 ****
# their own transactions, etc.
connection_base = connection_name.split(':')[0]
- print "connection_base=%s" % connection_base
-
# This will throw a GConnections.NotFoundError if an unknown
# connection name is specified. The calling method should
# catch this exception and handle it properly (exit w/message)
--- 200,205 ----
***************
*** 218,231 ****
basedriver = driver
extradriver = ""
- print "basedriver: %s; extradriver=%s" % (basedriver, extradriver)
-
path = []
dbdriver = None
basemodule = _find_base_driver(basedriver, ALLDRIVERS)
- print "basemodule=%s" % basemodule
GDebug.printMesg(1,'Using %s as base driver for %s' % (basemodule,
driver))
if basemodule:
--- 215,225 ----
***************
*** 233,239 ****
if not dbdriver:
tmsg = _("No database driver found for provider type '%s'") % driver
! raise GDataObjects.ProviderNotSupportedError, tmsg
conn = dbdriver.Connection(self, connection_name, parameters)
--- 227,233 ----
if not dbdriver:
tmsg = _("No database driver found for provider type '%s'") % driver
! raise Exceptions.ProviderNotSupportedError, tmsg
conn = dbdriver.Connection(self, connection_name, parameters)
***************
*** 247,266 ****
#
def getDataObject(self, connection_name, connection_type):
- print "getDataObject: %s %s" % (connection_name, connection_type)
-
# This will throw a GConnections.NotFoundError if an unknown
# connection name is specified. The calling method should
# catch this exception and handle it properly (exit w/message)
connection = self.getConnection(connection_name)
try:
! dd = connection._supportedDataObjects[connection_type](connection)
GDebug.printMesg (1,'Attaching to %s (%s)' % (dd.__class__.__name__,
connection_type))
return dd
except KeyError:
tmsg = _("DB Driver '%s' does not support source type '%s'") %
(connection, connection_type)
! raise GDataObjects.ObjectTypeNotAvailableError, tmsg
--- 241,258 ----
#
def getDataObject(self, connection_name, connection_type):
# This will throw a GConnections.NotFoundError if an unknown
# connection name is specified. The calling method should
# catch this exception and handle it properly (exit w/message)
connection = self.getConnection(connection_name)
try:
! dd = connection.supportedDataObjects[connection_type](connection)
GDebug.printMesg (1,'Attaching to %s (%s)' % (dd.__class__.__name__,
connection_type))
return dd
except KeyError:
tmsg = _("DB Driver '%s' does not support source type '%s'") %
(connection, connection_type)
! raise Exceptions.ObjectTypeNotAvailableError, tmsg
***************
*** 277,283 ****
#
def requestConnection(self, dataObject):
! print "requestConnection: %s" % dataObject
# Support for multiple open connections
# to same database.
--- 269,276 ----
#
def requestConnection(self, dataObject):
! print """TODO: once this branch makes it into CVS head,
! eliminate the GConnections.requestConnection logic!"""
# Support for multiple open connections
# to same database.
***************
*** 286,291 ****
--- 279,285 ----
# their own transactions, etc.
self.loginToConnection(dataObject._connection)
+ dataObject.connect()
def loginToConnection(self, connection):
***************
*** 293,299 ****
connection_name = connection.name
connection_base = connection_name.split(':')[0]
- print "loginToConnection: %s" % connection
try:
connected = connection.__connected
except AttributeError:
--- 287,292 ----
***************
*** 387,393 ****
attempts = 0
self._loginHandler.destroyLoginDialog()
! except GDataObjects.LoginError, error:
# Oops, they must have entered an invalid user/password.
# Those silly users.
# user: Hey! Who are you calling silly?!!!
--- 380,386 ----
attempts = 0
self._loginHandler.destroyLoginDialog()
! except Exceptions.LoginError, error:
# Oops, they must have entered an invalid user/password.
# Those silly users.
# user: Hey! Who are you calling silly?!!!
***************
*** 400,412 ****
# Four times is plenty...
#self._loginHandler.destroyLoginDialog()
tmsg = _("Unable to log in after 4 attempts.\n\nError: %s") %
error
! raise GDataObjects.LoginError, tmsg
except GLoginHandler.UserCanceledLogin:
# Guess they changed their minds. Treat as a login error.
self._loginHandler.destroyLoginDialog()
tmsg = _("User canceled the login request.")
! raise GDataObjects.LoginError, tmsg
connection.__connected = 1
--- 393,405 ----
# Four times is plenty...
#self._loginHandler.destroyLoginDialog()
tmsg = _("Unable to log in after 4 attempts.\n\nError: %s") %
error
! raise Exceptions.LoginError, tmsg
except GLoginHandler.UserCanceledLogin:
# Guess they changed their minds. Treat as a login error.
self._loginHandler.destroyLoginDialog()
tmsg = _("User canceled the login request.")
! raise Exceptions.LoginError, tmsg
connection.__connected = 1
Index: gnue-common/src/datasources/GDataObjects.py
diff -c gnue-common/src/datasources/GDataObjects.py:1.72.2.2
gnue-common/src/datasources/GDataObjects.py:1.72.2.3
*** gnue-common/src/datasources/GDataObjects.py:1.72.2.2 Fri Oct 10
08:18:48 2003
--- gnue-common/src/datasources/GDataObjects.py Tue Nov 18 21:07:06 2003
***************
*** 22,774 ****
# GDataObjects.py
#
# DESCRIPTION:
! # Class
#
# NOTES:
#
! # HISTORY:
#
! from gnue.common.apps import GDebug
! from gnue.common.datasources import GConditions
! import string
!
! postingRecordset = None
!
! class Error(StandardError):
! # Base exception
! pass
!
! class LoginError(Error):
! # Raised when invalid login user/pass was provided
! # Client should attempt to get better information and
! # try again
! pass
!
! class ConnectError(Error):
! # Raised when connection data is invalid (e.g., host not found, etc).
! # Client should probably not attempt to relogin. Exit gracefully
! # with a reason.
! pass
!
! class ProviderNotSupportedError(Error):
! # Raised when a datasource type is requested that the dbdriver
! # does not support (e.g., not all dbdrivers support raw sql mode.)
! pass
!
! class ObjectTypeNotAvailableError(Error):
! # Raised when a datasource type is requested that the dbdriver
! # does not support (e.g., not all dbdrivers support raw sql mode.)
! pass
!
! class ReadOnlyError(Error):
! # Raised when an attempt is made to update a read-only data object.
! pass
!
! class MasterDetailFieldMismatch(Error):
! # Raised when a the number of master fields doesn't match the
! # number of detail fields. (e.g., masterlink="id,subid"
! # and detaillink="id" would be a problem; must be 1:1)
! pass
!
! class ConnectionError(Error):
! # Generic error reading from the database connection
! pass
!
! class DataTypeNotAvailable(Error):
! # Raised when a datatype is not supported by an database
! # during writing a schema definition to the database
! pass
!
! class NoWriteSchemaSupport(Error):
! # Raised when a database adapter doesn't support
! # writing Schema to datasource
! pass
!
!
!
! ###########################################################
! #
! #
! #
! ###########################################################
! class DataObject:
!
! def __init__(self, connection):
! self._connection = connection
!
! self.masterlink = ""
! self.detaillink = ""
!
! self._masterfields = []
! self._detailfields = []
! self._staticCondition = None
!
! self._masterObject = None
! self._detailObjects = []
! self._dataConnection = None
! self._resultSetClass = ResultSet
! self._fieldReferences = {} # Set by GDataSource; lists all fields
! # a client explicitly references
!
! self._unboundFieldReferences = {} # Contains names of all unbound
! # field references
!
! self._defaultValues = {}
!
! self._unicodeMode = 0 # if set to true, datasources will unicode
! # strings instead of strings in local encoding
! # and if non unicode strings are passed to the
! # db driver a warning is raised (in 0.6.0 an
! # exception will be raised)
!
! # TODO: This is to keep old code from breaking.
! # TODO: 0.5.1 was last version to support
! # TODO triggerExtensions (functionality is now
! # TODO: encapsulated in Connection objects.
! self.triggerExtensions = connection
!
! # Do we have a master datasource?
! def hasMaster(self):
! return self._masterObject != None
!
! # Do not over-ride by vendor code
! def createResultSet(self, conditions={}, readOnly=0, masterRecordSet=None,
sql=""):
! return self._createResultSet(
! GConditions.combineConditions(conditions, self._staticCondition),
! readOnly=readOnly, masterRecordSet=masterRecordSet, sql=sql)
!
! # Designed to be replaced by vendor-specific code
! def _createResultSet(self, conditions={}, readOnly=0, masterRecordSet=None,
\
! sql=""):
! pass
!
! # Do not over-ride by vendor code
! def getQueryString(self,conditions={},forDetailSQL=None,additionalSQL=""):
! return self._buildQuery(conditions,forDetailSQL,additionalSQL)
!
! def createEmptyResultSet(self, readOnly=0, masterRecordSet=None):
! return self._createEmptyResultSet(readOnly, masterRecordSet)
!
! # Designed to be replaced by vendor-specific code
! def _createEmptyResultSet(self, readOnly=0, masterRecordSet=None):
! cond = GConditions.GCondition()
! ceq = GConditions.GCeq(cond)
! GConditions.GCConst(ceq,1,"number")
! GConditions.GCConst(ceq,0,"number")
! return self.createResultSet(conditions=cond, readOnly=readOnly,
! masterRecordSet=masterRecordSet)
!
!
! # Add a detail data object. This dataobject will create a new resultset
! # everytime this dataobject changes (new record, etc). The optional
! # handler will be called after the detail dataobject is notified. The
! # client application may wish to add a handler to know when the detail
! # has been requeried. handler is a method that takes two arguments:
! # the master ResultSet and the detail ResultSet
! def addDetailDataObject(self, dataObject, handler=None, **params):
!
! dataObject.__dict__.update(params)
!
! GDebug.printMesg (1,"Adding a master/detail relationship to DataObject")
! dataObject._masterObject = self
! dataObject._masterfields = string.split(hasattr(dataObject,'masterlink')
and \
! string.lower(dataObject.masterlink) or "",
',')
! dataObject._detailfields = string.split(hasattr(dataObject,'detaillink')
and \
! string.lower(dataObject.detaillink) or "",
',')
!
! if len(dataObject._masterfields) != len(dataObject._detailfields):
! tmsg = _("master=%s; detail=%s") % (dataObject._masterfields,
dataObject._detailfields)
! raise MasterDetailFieldMismatch, tmsg
!
! # Make sure "master" fields will be in our future query
! for field in dataObject._masterfields:
! self._fieldReferences[string.strip(field)] = ""
!
! for field in dataObject._detailfields:
! dataObject._fieldReferences[string.strip(field)] = ""
!
! self._detailObjects.append ([dataObject, handler])
!
!
! #
! # Connect to database from a GConnection object
! #
! def connect(self):
! self._dataConnection = self._connection.native
! self._postConnect()
!
! def commit(self):
! pass
!
! def rollback(self):
! pass
!
!
! #
! # Schema (metadata) functions
! #
!
! # TODO: DEPRECATED!!!!!
! def getSchemaTypes(self):
! print "WARNING: Your app is calling GDataObject.getSchemaTypes()"
! return self._connection.schema.types[:]
!
! # TODO: DEPRECATED!!!!!
! def getSchemaList(self, type=None):
! print "WARNING: Your app is calling GDataObject.getSchemaList()"
! return self._connection.schema.find(type=type)
!
! # TODO: DEPRECATED!!!!!
! def getSchemaByName(self, name, type=None):
! print "WARNING: Your app is calling GDataObject.getSchemaByName()"
! return self._connection.schema.findfirst(name=name, type=type)
!
!
!
!
! # Called when new record master in master/detail is queried
! def _masterRecordChanged(self, master):
! GDebug.printMesg (5, 'Master Record Changed')
! criteria = {}
!
! # If a detail result set has already been created for a particular
! # master record set, then just return/reuse this old set (after all,
! # it may contain uncommitted changes)
! if (not master.current._cachedDetailResultSets.has_key(self)) or \
! ( not int(gConfig('CacheDetailRecords')) and \
! not master.current._cachedDetailResultSets[self].isPending() ):
! doQuery = None
! for i in range(0, len(self._masterfields)):
! GDebug.printMesg(10,"Adding criteria")
! criteria[string.strip(self._detailfields[i])] = \
! master.current.getField(string.strip(self._masterfields[i]))
!
! #If all are set to None then this will prevent the details
! #from being queried. This happens are startup with blank master
! #datasources.
! doQuery = doQuery or
master.current.getField(string.strip(self._masterfields[i]))
!
! GDebug.printMesg(10,master.current.getField(self._masterfields[i]))
! if doQuery:
! master.current.addDetailResultSet(self.createResultSet(\
! conditions=criteria, masterRecordSet=master.current))
! else:
! master.current.addDetailResultSet(self.createEmptyResultSet())
! ## master.current._cachedDetailResultSets[self] = \
! ## self.createResultSet(conditions=criteria,
masterRecordSet=master.current)
! return master.current._cachedDetailResultSets[self]
!
!
! ###########################################################
! #
! #
! #
! ###########################################################
! class ResultSet:
!
! def __init__(self, dataObject,
cursor=None,defaultValues={},masterRecordSet=None):
! self._dataObject = dataObject
! self._recordSetClass = RecordSet
! self._cursor = cursor
! self._cachedRecords = []
! self._currentRecord = -1
! self._masterRecordSet = masterRecordSet
! self._readonly = 0
! self._recordCount = 0
! self._postingRecord = None
!
! self._defaultValues = {}
! self._defaultValues.update(defaultValues)
!
! self.current = None
!
! if masterRecordSet:
! masterRecordSet.addDetailResultSet(self)
!
! # Since we are overriding __len__
! def __nonzero__(self):
! return 1
!
! # Return the # of records
! def __len__(self):
! return self.getRecordCount()
!
! def __getitem__(self, index):
! rs = self.getRecord(index)
! if not rs:
! raise IndexError
! else:
! return rs
!
!
! # Returns whether this result set is read only or not
! def isReadOnly(self):
! return self._readonly
!
!
! # Returns 1=At first record, 0=Not first record
! def isFirstRecord(self):
! return (self._currentRecord == 0)
!
!
! # Returns 1=At last record, 0=Not last record
! def isLastRecord(self):
! if self._currentRecord < len(self._cachedRecords) - 1 or \
! self._cacheNextRecord():
! return 0
! else:
! return 1
!
!
! # returns -1=No records in memory, #=Current record #
! def getRecordNumber(self):
! return self._currentRecord
!
!
! # returns # of records currently loaded
! def getCacheCount(self):
! return len(self._cachedRecords)
!
! # returns # of records the
! def getRecordCount(self):
! return self._recordCount > 0 and self._recordCount or
self.getCacheCount()
!
! # Get a specific record (0=based)
! def getRecord(self, record):
! while (record + 1 > len(self._cachedRecords)) and self._cacheNextRecord():
! pass
!
! if record + 1 > len(self._cachedRecords):
! return None
! else:
! return self._cachedRecords[record]
!
!
! # move to record #, returns 1=New record loaded, 0=invalid #
! def setRecord(self, record):
!
! while (record > len(self._cachedRecords) -1) and self._cacheNextRecord():
! pass
!
! if record >= len(self._cachedRecords):
! return None
! else:
! self._currentRecord = record
! self.current = self._cachedRecords[self._currentRecord]
! self.notifyDetailObjects()
! return self.current
!
! # returns 1=New record loaded, 0=No more records
! def nextRecord(self):
! if self._currentRecord + 1 == len(self._cachedRecords):
! if not self._cacheNextRecord():
! return None
!
! self._currentRecord += 1
! self.current = self._cachedRecords[self._currentRecord]
! self.notifyDetailObjects()
! return self.current
!
!
! # returns 1=New record loaded, 0=At first record
! def prevRecord(self):
! if self._currentRecord < 1:
! return None
! else:
! self._currentRecord -= 1
! self.current = self._cachedRecords[self._currentRecord]
! self.notifyDetailObjects()
! return self.current
!
!
! # returns 1=at first record, 0=No records loaded
! def firstRecord(self):
! if self._currentRecord < 0:
! if not self._cacheNextRecord():
! return None
!
! self._currentRecord = 0
! self.current = self._cachedRecords[0]
! self.notifyDetailObjects()
! return self.current
!
!
!
! # returns 1=at last record, 0=No records loaded
! def lastRecord(self):
! if self._currentRecord == -1:
! return None
! else:
! while self._cacheNextRecord():
! pass
! self._currentRecord = len(self._cachedRecords) - 1
! self.current = self._cachedRecords[self._currentRecord]
! self.notifyDetailObjects()
! return self.current
!
!
!
! # Insert a blank record after the current record
! def insertRecord(self):
! if self.isReadOnly():
! # Provide better feedback??
! tmsg = _("Attempted to insert into a read only datasource")
! raise ReadOnlyError, tmsg
! else:
! GDebug.printMesg(7,'Inserting a blank record')
! self._currentRecord += 1
! self._cachedRecords.insert(self._currentRecord,
self._createEmptyRecord())
! self._recordCount += 1
! self.current = self._cachedRecords[self._currentRecord]
!
! # Set any dataobject-wide default values
! for field in self._dataObject._defaultValues.keys():
! self.current.setField(field, self._dataObject._defaultValues[field],0)
!
! # Set any resultset specific values
! for field in self._defaultValues.keys():
! self.current.setField(field, self._defaultValues[field],0)
!
! # Pull any primary keys from a master record set
! if self._masterRecordSet != None and hasattr(self._dataObject,
'_masterfields'):
! i = 0
! for field in self._dataObject._masterfields:
!
self.current.setField(self._dataObject._detailfields[i],self._masterRecordSet.getField(field),0)
! i += 1
!
! self.notifyDetailObjects()
! return self.current
!
!
! # Returns 1=DataObject, or a detail resultset, has uncommitted changes
! def isPending(self):
! for rec in (self._cachedRecords):
! if rec.isPending():
! return 1
! else:
! for detail in rec._cachedDetailResultSets.values():
! if detail.isPending():
! return 1
! return 0
!
!
! # Returns 1=DataObject has uncommitted changes
! def isRecordPending(self):
! return self.current.isPending()
!
!
! def getPostingRecordset(self):
! global postingRecordset
! print postingRecordset
! return postingRecordset
!
! # Post changes to the database
! def post(self, foreign_keys={}):
! global postingRecordset
! # post our changes
! self._update_cursor = self._dataObject._dataConnection.cursor()
!
! recordPosition = 0
! while recordPosition < len(self._cachedRecords):
! self._postingRecord = self._cachedRecords[recordPosition]
! postingRecordset = self._postingRecord
! delete = self._postingRecord._emptyFlag or
self._postingRecord._deleteFlag
! if not delete:
! # Flip the flag for 'default' values to true so that hidden
! # default fields are included in insert statements
! if self._postingRecord.isPending():
! for field in self._dataObject._defaultValues.keys():
! self._postingRecord._modifiedFlags[field] = 1
!
! for field in foreign_keys.keys():
! self._postingRecord._fields[field] = foreign_keys[field]
! # Some DBs will throw an exception if you update a Primary Key
! # (even if you are updating to the same value)
! if self._postingRecord._insertFlag:
! self._postingRecord._modifiedFlags[field] = 1
!
! recordPosition += 1
! else:
! # Adjust the current record if a preceding record
! # or the current record is deleted
! if recordPosition <= self._currentRecord:
! self._currentRecord -= 1
! self._cachedRecords.pop(recordPosition)
! self._recordCount -= 1
!
! self._postingRecord.post()
!
! # Move to record 0 if all preceding records were deleted
! # (or set to -1 if all records were deleted)
! if self._currentRecord < 0:
! if len(self._cachedRecords):
! self._currentRecord = 0
! else:
! self._currentRecord = -1
! # TODO: I don't think we need this anymore
! # if self._currentRecord >= self._recordCount:
! # self._currentRecord = self._recordCount - 1
!
! def notifyDetailObjects(self):
! GDebug.printMesg(5,'Master record changed; Notifying Detail Objects')
! for detail in self._dataObject._detailObjects:
! if detail[1]:
! detail[1].masterResultSetChanged(self,
! detail[0]._masterRecordChanged(self))
!
!
! # Returns 1=Field is bound to a database field
! def isFieldBound(self, fieldName):
! if self._dataObject._fieldReferences.has_key(fieldName):
! return 1
! else:
! #TODO: the string.lower() line should never be called but is left
! #TODO: here untill the code is cleaned up
! return
self._dataObject._fieldReferences.has_key(string.lower(fieldName))
!
!
! # Load cacheCount number of new records
! def _cacheNextRecord(self):
! rs = self._loadNextRecord()
! if rs:
! self._dataObject._dataSource._onRecordLoaded(self._cachedRecords[-1])
! return rs
!
!
!
! ###
! ### Methods below should be overridden by Vendor Specific functions
! ### (_createEmptyRecord may not need to be overridden in all cases)
! ###
!
! # Load cacheCount number of new records
! def _loadNextRecord(self):
! return 0
!
! # Create an empty recordset
! def _createEmptyRecord(self):
! return self._recordSetClass(self)
!
! # Iterator support (Python 2.2+)
! def __iter__(self):
! return _ResultSetIter(self)
!
!
! ###########################################################
! #
! #
! #
! ###########################################################
! class RecordSet:
!
! def __init__(self, parent, initialData={}, dbIdentifier=None,
defaultData={}):
! self._detailObjects = []
! self._dbIdentifier = dbIdentifier
! self._deleteFlag = 0
! self._updateFlag = 0
! self._parent = parent
! self._modifiedFlags = {} # If field name is present as a key,
! # then field has been modified
!
! self._cachedDetailResultSets = {}
!
! self._initialData = initialData
!
! if self._initialData and len(self._initialData):
! self._insertFlag = 0
! self._emptyFlag = 0
! self._fields = {}
! self._fields.update(initialData)
! else:
! self._insertFlag = 1
! self._emptyFlag = 1
! self._fields = {}
! self._fields.update(defaultData)
!
! def __setitem__(self, attr, val):
! self.setField(attr, val)
!
! def __getitem__(self, attr):
! return self.getField(attr)
!
! # Returns 1=Record has uncommitted changes
! def isPending(self):
!
! # The _insertFlag and _deleteFlag takes care of records that
! # were inserted, but then deleted before a save (i.e., nothing to do)
! if self._emptyFlag or self._insertFlag and self._deleteFlag:
! return 0
! else:
! return self._insertFlag or self._deleteFlag or self._updateFlag
!
!
! # Returns 1=Record is pending a deletion
! def isDeleted(self):
! if self._emptyFlag:
! return 0
! else:
! return self._deleteFlag and not self._insertFlag
!
!
! # Returns 1=Record is pending an update
! def isModified(self):
! if self._emptyFlag or self._insertFlag:
! return 0
! else:
! return self._updateFlag
!
!
! # Returns 1=Record is pending an insertion
! def isInserted(self):
! if self._emptyFlag:
! return 0
! else:
! return self._insertFlag and not self._deleteFlag
!
!
! # Returns 1=Record is empty (inserted, but no data set)
! def isEmpty(self):
! return self._emptyFlag
!
!
! # Returns current value of "field"
! def getField(self, field):
! try:
! return self._fields[field]
! except KeyError:
! try:
!
! # TODO: When we're confident that
! # TODO: all field names are lowercase,
! # TODO: then this can be removed.
!
! return self._fields[string.lower(field)]
! except KeyError:
! # If a field value has yet to be set
! # (either from a query or via a setField),
! # then _fields will not contain a key
! # for the requested field even though
! # the field name may still be valid.
! return None
!
!
! # Sets current value of "field"
! # If trackMod is set to 0 then the modification flag isn't raised
! def setField(self, field, value, trackMod = 1):
! # If this field is bound to a datasource and the datasource is read only,
! # generate an error.
! if self._parent.isFieldBound(field) and self._parent.isReadOnly():
! # Provide better feedback??
! tmsg = _("Attempted to modify read only field '%s'") % field
! raise ReadOnlyError, tmsg
! else:
! fn = string.lower(field)
! self._fields[fn] = value
! if trackMod == 1:
! if self._parent.isFieldBound(field):
! self._emptyFlag = 0
! self._updateFlag = 1
! self._modifiedFlags[fn] = 1
!
! try:
! self._parent._dataObject._dataSource._onModification(self)
! except AttributeError:
! pass
! return value
!
! # Batch mode of above setField method
! # If trackMod is set to 0 then the modification flag isn't raised
! def setFields(self, updateDict, trackMod = 1):
! # If this field is bound to a datasource and the datasource is read only,
! # generate an error.
! for field in updateDict.keys():
! self.setField(field, updateDict[field], trackMod)
!
!
! # Returns 1=Field has been modified
! def isFieldModified(self, fieldName):
! if self._modifiedFlags.has_key (fieldName):
! return 1
! else:
! #TODO: the string.lower() line should never be called but is left here
! #TODO: until the code is clean
! return self._modifiedFlags.has_key (string.lower(fieldName))
!
!
! # Mark the current record as deleted
! def delete(self):
! if self._parent.isReadOnly():
! # Provide better feedback??
! tmsg = _("Attempted to delete from a read only datasource")
! raise ReadOnlyError, tmsg
! else:
! self._deleteFlag = 1
!
!
! # Posts changes to database
! def post(self):
! # Should a post() to a read only datasource cause a ReadOnlyError?
! # It does no harm to attempt to post since nothing will be posted,
! # But does this allow sloppy programming?
!
! GDebug.printMesg(5,'Preparing to post datasource %s' %
self._parent._dataObject.name)
!
! # Save the initial status so we know if any triggers changed us
! status = (self._insertFlag, self._deleteFlag, self._updateFlag)
!
! # Call the hooks for commit-level hooks
! if not self._emptyFlag and
hasattr(self._parent._dataObject,'_dataSource'):
!
! if self._insertFlag and not self._deleteFlag:
! self._parent._dataObject._dataSource._beforeCommitInsert(self)
! elif self._deleteFlag and not self._insertFlag:
! self._parent._dataObject._dataSource._beforeCommitDelete(self)
! elif self._updateFlag:
! self._parent._dataObject._dataSource._beforeCommitUpdate(self)
!
! #
! # If the record status changed while we were doing the triggers,
! # start from the beginning and run the triggers again.
! #
! if status != (self._insertFlag, self._deleteFlag, self._updateFlag):
! self.post()
! return
!
!
! if self.isPending():
! GDebug.printMesg(5,'Posting datasource %s' %
self._parent._dataObject.name)
!
! if self.isPending():
! self._postChanges()
!
!
! # Post all detail records
! for child in (self._cachedDetailResultSets.keys()):
! c = self._cachedDetailResultSets[child]._dataObject
! # Set the primary key for any new child records
! fk = {}
! for i in range(len(c._masterfields)):
! fk[c._detailfields[i]] = self.getField(c._masterfields[i])
!
! self._cachedDetailResultSets[child].post(foreign_keys=fk)
!
!
! # Sets the ResultSet associated with this master record
! def addDetailResultSet(self, resultSet):
! self._cachedDetailResultSets[resultSet._dataObject] = resultSet
!
!
! ###
! ### Methods below should be over-written by Vendor Specific functions
! ###
!
! # Post any changes to database
! def _postChanges(self):
! return 1
# Used to store schema data
class Schema:
def __init__(self, attrs={}, getChildSchema=None):
self.name = ''
--- 22,42 ----
# GDataObjects.py
#
# DESCRIPTION:
! # This is a temporary backwards compatability file.
! # Should be removed at some point.
#
# NOTES:
#
! # TODO: Generate warnings whenever anything in this file is accessed.
#
! from Exceptions import *
! from drivers.Base import *
# Used to store schema data
+ # TODO: Is this used anywhere??
+ import string
class Schema:
def __init__(self, attrs={}, getChildSchema=None):
self.name = ''
***************
*** 789,823 ****
return ()
-
- # A simple resultset iterator
- # Lets you use ResultSets as:
- #
- # for record in myResultSet:
- # blah
- #
- # NOTE: Python 2.2+ (but it won't get called in
- # Python 2.1 or below, so not a problem)
- #
- class _ResultSetIter:
- def __init__(self, resultset):
- self.resultset = resultset
- self.used = 0
- self.done = 0
-
- def __iter__(self):
- return self
-
- def next(self):
- if self.done:
- raise StopIteration
- if self.used:
- rs = self.resultset.firstRecord()
- else:
- rs = self.resultset.nextRecord()
-
- if not rs:
- raise StopIteration
- else:
- return rs
--- 57,60 ----
Index: gnue-common/src/datasources/drivers/Base/Connection.py
diff -c /dev/null gnue-common/src/datasources/drivers/Base/Connection.py:1.1.2.1
*** /dev/null Tue Nov 18 21:07:09 2003
--- gnue-common/src/datasources/drivers/Base/Connection.py Tue Nov 18
21:07:07 2003
***************
*** 0 ****
--- 1,71 ----
+ #
+ # 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.
+ #
+ # Copyright 2000-2003 Free Software Foundation
+ #
+ # FILE:
+ # Connection.py
+ #
+ # DESCRIPTION:
+ #
+ # NOTES:
+ #
+
+ __all__ = ['Connection']
+
+
+ # System Init:
+ # +-- GConnections initializes
+ # +-- GParser initializes:
+ # +-- GDataSource loaded
+ # +-- GDataSources Intialized
+ # +-- GConnection.getDataObject()
+ # +--
+ #
+ class Connection:
+ def __init__(self, connections, name, parameters):
+ self.manager = connections
+ self.parameters = parameters
+ self.name = name
+
+ # Text encoding used by the database.
+ # (Not all databases support this concept)
+ try:
+ self._encoding = parameters['encoding']
+ except KeyError:
+ try:
+ self._encoding = gConfig('textEncoding')
+ except KeyError:
+ # TODO: Is this a safe default?
+ self._encoding = 'iso8859-1'
+
+
+ # Commit changes to the database
+ def commit(self):
+ pass
+
+ # Rollback changes to the database
+ def rollback(self):
+ pass
+
+ # Close the connection to the database backend
+ def close(self):
+ pass
+
+ def connect(self, connectData):
+ pass
\ No newline at end of file
Index: gnue-common/src/datasources/drivers/Base/DataObject.py
diff -c /dev/null gnue-common/src/datasources/drivers/Base/DataObject.py:1.1.2.1
*** /dev/null Tue Nov 18 21:07:09 2003
--- gnue-common/src/datasources/drivers/Base/DataObject.py Tue Nov 18
21:07:07 2003
***************
*** 0 ****
--- 1,209 ----
+ #
+ # 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.
+ #
+ # Copyright 2000-2003 Free Software Foundation
+ #
+ # FILE:
+ # DataObject.py
+ #
+ # DESCRIPTION:
+ #
+ # NOTES:
+ #
+
+ __all__ = ['DataObject']
+
+ from ResultSet import ResultSet
+
+ from gnue.common.apps import GDebug
+ from gnue.common.datasources import GConditions, Exceptions
+ import string
+
+ from ResultSet import ResultSet
+
+ ###########################################################
+ #
+ #
+ #
+ ###########################################################
+ class DataObject:
+
+ _resultSetClass = ResultSet
+
+ def __init__(self, connection):
+ self._connection = connection
+
+ self.masterlink = ""
+ self.detaillink = ""
+
+ self._masterfields = []
+ self._detailfields = []
+ self._staticCondition = None
+
+ self._masterObject = None
+ self._detailObjects = []
+ self._dataConnection = None
+ self._fieldReferences = {} # Set by GDataSource; lists all fields
+ # a client explicitly references
+
+ self._unboundFieldReferences = {} # Contains names of all unbound
+ # field references
+
+ self._defaultValues = {}
+
+ self._unicodeMode = 0 # if set to true, datasources will unicode
+ # strings instead of strings in local encoding
+ # and if non unicode strings are passed to the
+ # db driver a warning is raised (in 0.6.0 an
+ # exception will be raised)
+
+ # TODO: This is to keep old code from breaking.
+ # TODO: 0.5.1 was last version to support
+ # TODO triggerExtensions (functionality is now
+ # TODO: encapsulated in Connection objects.
+ self.triggerExtensions = connection
+
+ # Do we have a master datasource?
+ def hasMaster(self):
+ return self._masterObject != None
+
+ # Do not over-ride by vendor code
+ def createResultSet(self, conditions={}, readOnly=0, masterRecordSet=None,
sql=""):
+ return self._createResultSet(
+ GConditions.combineConditions(conditions, self._staticCondition),
+ readOnly=readOnly, masterRecordSet=masterRecordSet, sql=sql)
+
+ # Designed to be replaced by vendor-specific code
+ def _createResultSet(self, conditions={}, readOnly=0, masterRecordSet=None,
\
+ sql=""):
+ pass
+
+ # Do not over-ride by vendor code
+ def getQueryString(self,conditions={},forDetailSQL=None,additionalSQL=""):
+ return self._buildQuery(conditions,forDetailSQL,additionalSQL)
+
+ def createEmptyResultSet(self, readOnly=0, masterRecordSet=None):
+ return self._createEmptyResultSet(readOnly, masterRecordSet)
+
+ # Designed to be replaced by vendor-specific code
+ def _createEmptyResultSet(self, readOnly=0, masterRecordSet=None):
+ cond = GConditions.GCondition()
+ ceq = GConditions.GCeq(cond)
+ GConditions.GCConst(ceq,1,"number")
+ GConditions.GCConst(ceq,0,"number")
+ return self.createResultSet(conditions=cond, readOnly=readOnly,
+ masterRecordSet=masterRecordSet)
+
+
+ # Add a detail data object. This dataobject will create a new resultset
+ # everytime this dataobject changes (new record, etc). The optional
+ # handler will be called after the detail dataobject is notified. The
+ # client application may wish to add a handler to know when the detail
+ # has been requeried. handler is a method that takes two arguments:
+ # the master ResultSet and the detail ResultSet
+ def addDetailDataObject(self, dataObject, handler=None, **params):
+
+ dataObject.__dict__.update(params)
+
+ GDebug.printMesg (1,"Adding a master/detail relationship to DataObject")
+ dataObject._masterObject = self
+ dataObject._masterfields = string.split(hasattr(dataObject,'masterlink')
and \
+ string.lower(dataObject.masterlink) or "",
',')
+ dataObject._detailfields = string.split(hasattr(dataObject,'detaillink')
and \
+ string.lower(dataObject.detaillink) or "",
',')
+
+ if len(dataObject._masterfields) != len(dataObject._detailfields):
+ tmsg = _("master=%s; detail=%s") % (dataObject._masterfields,
dataObject._detailfields)
+ raise Exceptions.MasterDetailFieldMismatch, tmsg
+
+ # Make sure "master" fields will be in our future query
+ for field in dataObject._masterfields:
+ self._fieldReferences[string.strip(field)] = ""
+
+ for field in dataObject._detailfields:
+ dataObject._fieldReferences[string.strip(field)] = ""
+
+ self._detailObjects.append ([dataObject, handler])
+
+ #
+ # Connect to database from a GConnection object
+ #
+ def connect(self):
+ self._dataConnection = self._connection.native
+
+ def commit(self):
+ pass
+
+ def rollback(self):
+ pass
+
+
+ #
+ # Schema (metadata) functions
+ #
+
+ # TODO: DEPRECATED!!!!!
+ def getSchemaTypes(self):
+ print "WARNING: Your app is calling GDataObject.getSchemaTypes()"
+ return self._connection.schema.types[:]
+
+ # TODO: DEPRECATED!!!!!
+ def getSchemaList(self, type=None):
+ print "WARNING: Your app is calling GDataObject.getSchemaList()"
+ return self._connection.schema.find(type=type)
+
+ # TODO: DEPRECATED!!!!!
+ def getSchemaByName(self, name, type=None):
+ print "WARNING: Your app is calling GDataObject.getSchemaByName()"
+ return self._connection.schema.findfirst(name=name, type=type)
+
+
+
+
+ # Called when new record master in master/detail is queried
+ def _masterRecordChanged(self, master):
+ GDebug.printMesg (5, 'Master Record Changed')
+ criteria = {}
+
+ # If a detail result set has already been created for a particular
+ # master record set, then just return/reuse this old set (after all,
+ # it may contain uncommitted changes)
+ if (not master.current._cachedDetailResultSets.has_key(self)) or \
+ ( not int(gConfig('CacheDetailRecords')) and \
+ not master.current._cachedDetailResultSets[self].isPending() ):
+ doQuery = None
+ for i in range(0, len(self._masterfields)):
+ GDebug.printMesg(10,"Adding criteria")
+ criteria[string.strip(self._detailfields[i])] = \
+ master.current.getField(string.strip(self._masterfields[i]))
+
+ #If all are set to None then this will prevent the details
+ #from being queried. This happens are startup with blank master
+ #datasources.
+ doQuery = doQuery or
master.current.getField(string.strip(self._masterfields[i]))
+
+ GDebug.printMesg(10,master.current.getField(self._masterfields[i]))
+ if doQuery:
+ master.current.addDetailResultSet(self.createResultSet(\
+ conditions=criteria, masterRecordSet=master.current))
+ else:
+ master.current.addDetailResultSet(self.createEmptyResultSet())
+ ## master.current._cachedDetailResultSets[self] = \
+ ## self.createResultSet(conditions=criteria,
masterRecordSet=master.current)
+ return master.current._cachedDetailResultSets[self]
+
Index: gnue-common/src/datasources/drivers/Base/RecordSet.py
diff -c /dev/null gnue-common/src/datasources/drivers/Base/RecordSet.py:1.1.2.1
*** /dev/null Tue Nov 18 21:07:09 2003
--- gnue-common/src/datasources/drivers/Base/RecordSet.py Tue Nov 18
21:07:07 2003
***************
*** 0 ****
--- 1,246 ----
+ #
+ # 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.
+ #
+ # Copyright 2000-2003 Free Software Foundation
+ #
+ # FILE:
+ # GConnection.py
+ #
+ # DESCRIPTION:
+ #
+ # NOTES:
+ #
+
+ __all__ = ['RecordSet']
+
+ from gnue.common.apps import GDebug
+ from gnue.common.datasources import GConditions, Exceptions
+ import string
+
+ ###########################################################
+ #
+ #
+ #
+ ###########################################################
+ class RecordSet:
+
+ def __init__(self, parent, initialData={}, dbIdentifier=None,
defaultData={}):
+ self._detailObjects = []
+ self._dbIdentifier = dbIdentifier
+ self._deleteFlag = 0
+ self._updateFlag = 0
+ self._parent = parent
+ self._modifiedFlags = {} # If field name is present as a key,
+ # then field has been modified
+
+ self._cachedDetailResultSets = {}
+
+ self._initialData = initialData
+
+ if self._initialData and len(self._initialData):
+ self._insertFlag = 0
+ self._emptyFlag = 0
+ self._fields = {}
+ self._fields.update(initialData)
+ else:
+ self._insertFlag = 1
+ self._emptyFlag = 1
+ self._fields = {}
+ self._fields.update(defaultData)
+
+ def __setitem__(self, attr, val):
+ self.setField(attr, val)
+
+ def __getitem__(self, attr):
+ return self.getField(attr)
+
+ # Returns 1=Record has uncommitted changes
+ def isPending(self):
+
+ # The _insertFlag and _deleteFlag takes care of records that
+ # were inserted, but then deleted before a save (i.e., nothing to do)
+ if self._emptyFlag or self._insertFlag and self._deleteFlag:
+ return 0
+ else:
+ return self._insertFlag or self._deleteFlag or self._updateFlag
+
+
+ # Returns 1=Record is pending a deletion
+ def isDeleted(self):
+ if self._emptyFlag:
+ return 0
+ else:
+ return self._deleteFlag and not self._insertFlag
+
+
+ # Returns 1=Record is pending an update
+ def isModified(self):
+ if self._emptyFlag or self._insertFlag:
+ return 0
+ else:
+ return self._updateFlag
+
+
+ # Returns 1=Record is pending an insertion
+ def isInserted(self):
+ if self._emptyFlag:
+ return 0
+ else:
+ return self._insertFlag and not self._deleteFlag
+
+
+ # Returns 1=Record is empty (inserted, but no data set)
+ def isEmpty(self):
+ return self._emptyFlag
+
+
+ # Returns current value of "field"
+ def getField(self, field):
+ try:
+ return self._fields[field]
+ except KeyError:
+ try:
+
+ # TODO: When we're confident that
+ # TODO: all field names are lowercase,
+ # TODO: then this can be removed.
+
+ return self._fields[string.lower(field)]
+ except KeyError:
+ # If a field value has yet to be set
+ # (either from a query or via a setField),
+ # then _fields will not contain a key
+ # for the requested field even though
+ # the field name may still be valid.
+ return None
+
+
+ # Sets current value of "field"
+ # If trackMod is set to 0 then the modification flag isn't raised
+ def setField(self, field, value, trackMod = 1):
+ # If this field is bound to a datasource and the datasource is read only,
+ # generate an error.
+ if self._parent.isFieldBound(field) and self._parent.isReadOnly():
+ # Provide better feedback??
+ tmsg = _("Attempted to modify read only field '%s'") % field
+ raise Exceptions.ReadOnlyError, tmsg
+ else:
+ fn = string.lower(field)
+ self._fields[fn] = value
+ if trackMod == 1:
+ if self._parent.isFieldBound(field):
+ self._emptyFlag = 0
+ self._updateFlag = 1
+ self._modifiedFlags[fn] = 1
+
+ try:
+ self._parent._dataObject._dataSource._onModification(self)
+ except AttributeError:
+ pass
+ return value
+
+ # Batch mode of above setField method
+ # If trackMod is set to 0 then the modification flag isn't raised
+ def setFields(self, updateDict, trackMod = 1):
+ # If this field is bound to a datasource and the datasource is read only,
+ # generate an error.
+ for field in updateDict.keys():
+ self.setField(field, updateDict[field], trackMod)
+
+
+ # Returns 1=Field has been modified
+ def isFieldModified(self, fieldName):
+ if self._modifiedFlags.has_key (fieldName):
+ return 1
+ else:
+ #TODO: the string.lower() line should never be called but is left here
+ #TODO: until the code is clean
+ return self._modifiedFlags.has_key (string.lower(fieldName))
+
+
+ # Mark the current record as deleted
+ def delete(self):
+ if self._parent.isReadOnly():
+ # Provide better feedback??
+ tmsg = _("Attempted to delete from a read only datasource")
+ raise Exceptions.ReadOnlyError, tmsg
+ else:
+ self._deleteFlag = 1
+
+
+ # Posts changes to database
+ def post(self):
+ # Should a post() to a read only datasource cause a ReadOnlyError?
+ # It does no harm to attempt to post since nothing will be posted,
+ # But does this allow sloppy programming?
+
+ GDebug.printMesg(5,'Preparing to post datasource %s' %
self._parent._dataObject.name)
+
+ # Save the initial status so we know if any triggers changed us
+ status = (self._insertFlag, self._deleteFlag, self._updateFlag)
+
+ # Call the hooks for commit-level hooks
+ if not self._emptyFlag and
hasattr(self._parent._dataObject,'_dataSource'):
+
+ if self._insertFlag and not self._deleteFlag:
+ self._parent._dataObject._dataSource._beforeCommitInsert(self)
+ elif self._deleteFlag and not self._insertFlag:
+ self._parent._dataObject._dataSource._beforeCommitDelete(self)
+ elif self._updateFlag:
+ self._parent._dataObject._dataSource._beforeCommitUpdate(self)
+
+ #
+ # If the record status changed while we were doing the triggers,
+ # start from the beginning and run the triggers again.
+ #
+ if status != (self._insertFlag, self._deleteFlag, self._updateFlag):
+ self.post()
+ return
+
+
+ if self.isPending():
+ GDebug.printMesg(5,'Posting datasource %s' %
self._parent._dataObject.name)
+
+ if self.isPending():
+ self._postChanges()
+
+
+ # Post all detail records
+ for child in (self._cachedDetailResultSets.keys()):
+ c = self._cachedDetailResultSets[child]._dataObject
+ # Set the primary key for any new child records
+ fk = {}
+ for i in range(len(c._masterfields)):
+ fk[c._detailfields[i]] = self.getField(c._masterfields[i])
+
+ self._cachedDetailResultSets[child].post(foreign_keys=fk)
+
+
+ # Sets the ResultSet associated with this master record
+ def addDetailResultSet(self, resultSet):
+ self._cachedDetailResultSets[resultSet._dataObject] = resultSet
+
+
+ ###
+ ### Methods below should be over-written by Vendor Specific functions
+ ###
+
+ # Post any changes to database
+ def _postChanges(self):
+ return 1
+
Index: gnue-common/src/datasources/drivers/Base/ResultSet.py
diff -c /dev/null gnue-common/src/datasources/drivers/Base/ResultSet.py:1.1.2.1
*** /dev/null Tue Nov 18 21:07:09 2003
--- gnue-common/src/datasources/drivers/Base/ResultSet.py Tue Nov 18
21:07:07 2003
***************
*** 0 ****
--- 1,367 ----
+ #
+ # 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.
+ #
+ # Copyright 2000-2003 Free Software Foundation
+ #
+ # FILE:
+ # ResultSet.py
+ #
+ # DESCRIPTION:
+ #
+ # NOTES:
+ #
+
+ __all__ = ['ResultSet']
+
+ from gnue.common.apps import GDebug
+ from gnue.common.datasources import GConditions, Exceptions
+ import string
+
+ from RecordSet import RecordSet
+
+ ###########################################################
+ #
+ #
+ #
+ ###########################################################
+ class ResultSet:
+
+ _recordSetClass = RecordSet
+
+ def __init__(self, dataObject,
cursor=None,defaultValues={},masterRecordSet=None):
+ self._dataObject = dataObject
+ self._cursor = cursor
+ self._cachedRecords = []
+ self._currentRecord = -1
+ self._masterRecordSet = masterRecordSet
+ self._readonly = 0
+ self._recordCount = 0
+ self._postingRecord = None
+
+ self._defaultValues = {}
+ self._defaultValues.update(defaultValues)
+
+ self.current = None
+
+ if masterRecordSet:
+ masterRecordSet.addDetailResultSet(self)
+
+ # Since we are overriding __len__
+ def __nonzero__(self):
+ return 1
+
+ # Return the # of records
+ def __len__(self):
+ return self.getRecordCount()
+
+ def __getitem__(self, index):
+ rs = self.getRecord(index)
+ if not rs:
+ raise IndexError
+ else:
+ return rs
+
+
+ # Returns whether this result set is read only or not
+ def isReadOnly(self):
+ return self._readonly
+
+
+ # Returns 1=At first record, 0=Not first record
+ def isFirstRecord(self):
+ return (self._currentRecord == 0)
+
+
+ # Returns 1=At last record, 0=Not last record
+ def isLastRecord(self):
+ if self._currentRecord < len(self._cachedRecords) - 1 or \
+ self._cacheNextRecord():
+ return 0
+ else:
+ return 1
+
+
+ # returns -1=No records in memory, #=Current record #
+ def getRecordNumber(self):
+ return self._currentRecord
+
+
+ # returns # of records currently loaded
+ def getCacheCount(self):
+ return len(self._cachedRecords)
+
+ # returns # of records the
+ def getRecordCount(self):
+ return self._recordCount > 0 and self._recordCount or
self.getCacheCount()
+
+ # Get a specific record (0=based)
+ def getRecord(self, record):
+ while (record + 1 > len(self._cachedRecords)) and self._cacheNextRecord():
+ pass
+
+ if record + 1 > len(self._cachedRecords):
+ return None
+ else:
+ return self._cachedRecords[record]
+
+
+ # move to record #, returns 1=New record loaded, 0=invalid #
+ def setRecord(self, record):
+
+ while (record > len(self._cachedRecords) -1) and self._cacheNextRecord():
+ pass
+
+ if record >= len(self._cachedRecords):
+ return None
+ else:
+ self._currentRecord = record
+ self.current = self._cachedRecords[self._currentRecord]
+ self.notifyDetailObjects()
+ return self.current
+
+ # returns 1=New record loaded, 0=No more records
+ def nextRecord(self):
+ if self._currentRecord + 1 == len(self._cachedRecords):
+ if not self._cacheNextRecord():
+ return None
+
+ self._currentRecord += 1
+ self.current = self._cachedRecords[self._currentRecord]
+ self.notifyDetailObjects()
+ return self.current
+
+
+ # returns 1=New record loaded, 0=At first record
+ def prevRecord(self):
+ if self._currentRecord < 1:
+ return None
+ else:
+ self._currentRecord -= 1
+ self.current = self._cachedRecords[self._currentRecord]
+ self.notifyDetailObjects()
+ return self.current
+
+
+ # returns 1=at first record, 0=No records loaded
+ def firstRecord(self):
+ if self._currentRecord < 0:
+ if not self._cacheNextRecord():
+ return None
+
+ self._currentRecord = 0
+ self.current = self._cachedRecords[0]
+ self.notifyDetailObjects()
+ return self.current
+
+
+
+ # returns 1=at last record, 0=No records loaded
+ def lastRecord(self):
+ if self._currentRecord == -1:
+ return None
+ else:
+ while self._cacheNextRecord():
+ pass
+ self._currentRecord = len(self._cachedRecords) - 1
+ self.current = self._cachedRecords[self._currentRecord]
+ self.notifyDetailObjects()
+ return self.current
+
+
+
+ # Insert a blank record after the current record
+ def insertRecord(self):
+ if self.isReadOnly():
+ # Provide better feedback??
+ tmsg = _("Attempted to insert into a read only datasource")
+ raise Exceptions.ReadOnlyError, tmsg
+ else:
+ GDebug.printMesg(7,'Inserting a blank record')
+ self._currentRecord += 1
+ self._cachedRecords.insert(self._currentRecord,
self._createEmptyRecord())
+ self._recordCount += 1
+ self.current = self._cachedRecords[self._currentRecord]
+
+ # Set any dataobject-wide default values
+ for field in self._dataObject._defaultValues.keys():
+ self.current.setField(field, self._dataObject._defaultValues[field],0)
+
+ # Set any resultset specific values
+ for field in self._defaultValues.keys():
+ self.current.setField(field, self._defaultValues[field],0)
+
+ # Pull any primary keys from a master record set
+ if self._masterRecordSet != None and hasattr(self._dataObject,
'_masterfields'):
+ i = 0
+ for field in self._dataObject._masterfields:
+
self.current.setField(self._dataObject._detailfields[i],self._masterRecordSet.getField(field),0)
+ i += 1
+
+ self.notifyDetailObjects()
+ return self.current
+
+
+ # Returns 1=DataObject, or a detail resultset, has uncommitted changes
+ def isPending(self):
+ for rec in (self._cachedRecords):
+ if rec.isPending():
+ return 1
+ else:
+ for detail in rec._cachedDetailResultSets.values():
+ if detail.isPending():
+ return 1
+ return 0
+
+
+ # Returns 1=DataObject has uncommitted changes
+ def isRecordPending(self):
+ return self.current.isPending()
+
+
+ def getPostingRecordset(self):
+ global postingRecordset
+ return postingRecordset
+
+ # Post changes to the database
+ def post(self, foreign_keys={}):
+ global postingRecordset
+ # post our changes
+ self._update_cursor = self._dataObject._dataConnection.cursor()
+
+ recordPosition = 0
+ while recordPosition < len(self._cachedRecords):
+ self._postingRecord = self._cachedRecords[recordPosition]
+ postingRecordset = self._postingRecord
+ delete = self._postingRecord._emptyFlag or
self._postingRecord._deleteFlag
+ if not delete:
+ # Flip the flag for 'default' values to true so that hidden
+ # default fields are included in insert statements
+ if self._postingRecord.isPending():
+ for field in self._dataObject._defaultValues.keys():
+ self._postingRecord._modifiedFlags[field] = 1
+
+ for field in foreign_keys.keys():
+ self._postingRecord._fields[field] = foreign_keys[field]
+ # Some DBs will throw an exception if you update a Primary Key
+ # (even if you are updating to the same value)
+ if self._postingRecord._insertFlag:
+ self._postingRecord._modifiedFlags[field] = 1
+
+ recordPosition += 1
+ else:
+ # Adjust the current record if a preceding record
+ # or the current record is deleted
+ if recordPosition <= self._currentRecord:
+ self._currentRecord -= 1
+ self._cachedRecords.pop(recordPosition)
+ self._recordCount -= 1
+
+ self._postingRecord.post()
+
+ # Move to record 0 if all preceding records were deleted
+ # (or set to -1 if all records were deleted)
+ if self._currentRecord < 0:
+ if len(self._cachedRecords):
+ self._currentRecord = 0
+ else:
+ self._currentRecord = -1
+ # TODO: I don't think we need this anymore
+ # if self._currentRecord >= self._recordCount:
+ # self._currentRecord = self._recordCount - 1
+
+ def notifyDetailObjects(self):
+ GDebug.printMesg(5,'Master record changed; Notifying Detail Objects')
+ for detail in self._dataObject._detailObjects:
+ if detail[1]:
+ detail[1].masterResultSetChanged(self,
+ detail[0]._masterRecordChanged(self))
+
+
+ # Returns 1=Field is bound to a database field
+ def isFieldBound(self, fieldName):
+ if self._dataObject._fieldReferences.has_key(fieldName):
+ return 1
+ else:
+ #TODO: the string.lower() line should never be called but is left
+ #TODO: here untill the code is cleaned up
+ return
self._dataObject._fieldReferences.has_key(string.lower(fieldName))
+
+
+ # Load cacheCount number of new records
+ def _cacheNextRecord(self):
+ rs = self._loadNextRecord()
+ if rs:
+ self._dataObject._dataSource._onRecordLoaded(self._cachedRecords[-1])
+ return rs
+
+
+
+ ###
+ ### Methods below should be overridden by Vendor Specific functions
+ ### (_createEmptyRecord may not need to be overridden in all cases)
+ ###
+
+ # Load cacheCount number of new records
+ def _loadNextRecord(self):
+ return 0
+
+ # Create an empty recordset
+ def _createEmptyRecord(self):
+ return self._recordSetClass(self)
+
+ # Iterator support (Python 2.2+)
+ def __iter__(self):
+ return _ResultSetIter(self)
+
+
+
+ # A simple resultset iterator
+ # Lets you use ResultSets as:
+ #
+ # for record in myResultSet:
+ # blah
+ #
+ # NOTE: Python 2.2+ (but it won't get called in
+ # Python 2.1 or below, so not a problem)
+ #
+ class _ResultSetIter:
+ def __init__(self, resultset):
+ self.resultset = resultset
+ self.used = 0
+ self.done = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.done:
+ raise StopIteration
+ if self.used:
+ rs = self.resultset.firstRecord()
+ else:
+ rs = self.resultset.nextRecord()
+
+ if not rs:
+ raise StopIteration
+ else:
+ return rs
+
+
+ # TODO: wtf?
+ postingRecordset = None
+
Index: gnue-common/src/datasources/drivers/Base/__init__.py
diff -c /dev/null gnue-common/src/datasources/drivers/Base/__init__.py:1.1.2.1
*** /dev/null Tue Nov 18 21:07:09 2003
--- gnue-common/src/datasources/drivers/Base/__init__.py Tue Nov 18
21:07:07 2003
***************
*** 0 ****
--- 1,32 ----
+ #
+ # 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.
+ #
+ # Copyright 2000-2003 Free Software Foundation
+ #
+ # FILE:
+ # Base/__init__.py
+ #
+ # DESCRIPTION:
+ #
+ # NOTES:
+ #
+
+ from Connection import Connection
+ from DataObject import DataObject
+ from ResultSet import ResultSet
+ from RecordSet import RecordSet
\ No newline at end of file
Index: gnue-common/src/datasources/drivers/DBSIG2/Connection.py
diff -c gnue-common/src/datasources/drivers/DBSIG2/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/DBSIG2/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/DBSIG2/Connection.py:1.1.2.1 Thu Oct
9 21:21:09 2003
--- gnue-common/src/datasources/drivers/DBSIG2/Connection.py Tue Nov 18
21:07:07 2003
***************
*** 33,44 ****
__all__ = ['Connection']
! from gnue.common.datasources import GConnection
from gnue.common.apps import GDebug
import string
import types
! class Connection(GConnection.Connection):
# This should be over-ridden only if driver needs more than user/pass
def getLoginFields(self):
--- 33,45 ----
__all__ = ['Connection']
! from gnue.common.datasources import Exceptions
! from gnue.common.datasources.drivers.Base.Connection import Connection as
BaseConnection
from gnue.common.apps import GDebug
import string
import types
! class Connection(BaseConnection):
# This should be over-ridden only if driver needs more than user/pass
def getLoginFields(self):
***************
*** 50,56 ****
try:
self.native.commit()
except self._DatabaseError, value:
! raise GDataObjects.ConnectionError, value
self._beginTransaction()
--- 51,57 ----
try:
self.native.commit()
except self._DatabaseError, value:
! raise Exceptions.ConnectionError, value
self._beginTransaction()
Index: gnue-common/src/datasources/drivers/DBSIG2/DataObject.py
diff -c gnue-common/src/datasources/drivers/DBSIG2/DataObject.py:1.1.2.3
gnue-common/src/datasources/drivers/DBSIG2/DataObject.py:1.1.2.4
*** gnue-common/src/datasources/drivers/DBSIG2/DataObject.py:1.1.2.3 Sun Oct
12 15:47:15 2003
--- gnue-common/src/datasources/drivers/DBSIG2/DataObject.py Tue Nov 18
21:07:07 2003
***************
*** 33,39 ****
__all__ = ['DataObject','DataObject_SQL','DataObject_Object']
! from gnue.common.datasources import GDataObjects, GConditions
from gnue.common.apps import GDebug
import string
import types
--- 33,40 ----
__all__ = ['DataObject','DataObject_SQL','DataObject_Object']
! from gnue.common.datasources import GConditions, Exceptions
! from gnue.common.datasources.drivers.Base import DataObject as BaseDataObject
from gnue.common.apps import GDebug
import string
import types
***************
*** 44,50 ****
#
#
#
! class DataObject(GDataObjects.DataObject):
_escapeSingleQuote = "'"
_resultSetClass = ResultSet
--- 45,51 ----
#
#
#
! class DataObject(BaseDataObject):
_escapeSingleQuote = "'"
_resultSetClass = ResultSet
***************
*** 94,100 ****
def __init__(self, *args, **params):
! GDataObjects.DataObject.__init__(self, *args, **params)
GDebug.printMesg (1,"DB-SIG database driver backend initializing")
--- 95,101 ----
def __init__(self, *args, **params):
! BaseDataObject.__init__(self, *args, **params)
GDebug.printMesg (1,"DB-SIG database driver backend initializing")
***************
*** 114,120 ****
try:
return value.strftime(self._dateTimeFormat)
except AttributeError:
!
if value == None:
return "NULL"
--- 115,121 ----
try:
return value.strftime(self._dateTimeFormat)
except AttributeError:
!
if value == None:
return "NULL"
***************
*** 159,165 ****
return "'%s'" % string.replace(str(value),
"'",
"%s'" % self._escapeSingleQuote)
!
# Used by drivers with a unique id (like rowid) (see Oracle for example)
def _checkForPrimaryId(self):
--- 160,166 ----
return "'%s'" % string.replace(str(value),
"'",
"%s'" % self._escapeSingleQuote)
!
# Used by drivers with a unique id (like rowid) (see Oracle for example)
def _checkForPrimaryId(self):
***************
*** 182,190 ****
recordCount = cursor.rowcount
#disable the count query and see if anyone screams
#recordCount = self._getQueryCount(conditions,sql)
!
except self._DatabaseError, err:
! raise GDataObjects.ConnectionError, err
rs = self._resultSetClass(self, cursor=cursor,
masterRecordSet=masterRecordSet)
if self._strictQueryCount:
--- 183,191 ----
recordCount = cursor.rowcount
#disable the count query and see if anyone screams
#recordCount = self._getQueryCount(conditions,sql)
!
except self._DatabaseError, err:
! raise Exceptions.ConnectionError, err
rs = self._resultSetClass(self, cursor=cursor,
masterRecordSet=masterRecordSet)
if self._strictQueryCount:
***************
*** 258,268 ****
if len(result) < self.conditionElements[otype][0]:
tmsg = _('Condition element "%s" expects at least %s arguments;
found %s') % \
(otype, self.conditionElements[otype][0], len(result))
! raise GConditions.ConditionError, tmsg
if len(result) > self.conditionElements[otype][1]:
tmsg = _('Condition element "%s" expects at most %s arguments;
found %s') % \
(otype, self.conditionElements[otype][0], len(result))
! raise GConditions.ConditionError, tmsg
if self.conditionElements[otype][3] == None:
return self.conditionElements[otype][2] % tuple(result)
--- 259,269 ----
if len(result) < self.conditionElements[otype][0]:
tmsg = _('Condition element "%s" expects at least %s arguments;
found %s') % \
(otype, self.conditionElements[otype][0], len(result))
! raise Exceptions.ConditionError, tmsg
if len(result) > self.conditionElements[otype][1]:
tmsg = _('Condition element "%s" expects at most %s arguments;
found %s') % \
(otype, self.conditionElements[otype][0], len(result))
! raise Exceptions.ConditionError, tmsg
if self.conditionElements[otype][3] == None:
return self.conditionElements[otype][2] % tuple(result)
***************
*** 271,277 ****
(string.join(result, self.conditionElements[otype][3]))
else:
tmsg = _('Condition clause "%s" is not supported by this db driver.')
% otype
! raise GConditions.ConditionNotSupported, tmsg
--- 272,278 ----
(string.join(result, self.conditionElements[otype][3]))
else:
tmsg = _('Condition clause "%s" is not supported by this db driver.')
% otype
! raise Exceptions.ConditionNotSupported, tmsg
Index: gnue-common/src/datasources/drivers/DBSIG2/Driver.py
diff -c gnue-common/src/datasources/drivers/DBSIG2/Driver.py:1.76.2.1
gnue-common/src/datasources/drivers/DBSIG2/Driver.py:removed
*** gnue-common/src/datasources/drivers/DBSIG2/Driver.py:1.76.2.1 Thu Oct
9 21:21:09 2003
--- gnue-common/src/datasources/drivers/DBSIG2/Driver.py Tue Nov 18
21:07:09 2003
***************
*** 1,600 ****
- #
- # 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.
- #
- # Copyright 2000-2003 Free Software Foundation
- #
- # FILE:
- # _dbsig/DBdriver.py
- #
- # DESCRIPTION:
- # Generic implementation of dbdriver using Python DB-SIG v2
- # specification.
- #
- # NOTES:
- # The classes below are meant to be extended
- #
- # HISTORY:
- #
-
- from gnue.common.datasources import GDataObjects, GConditions
- from gnue.common.apps import GDebug
- import string
- import types
-
- class DBSIG_RecordSet(GDataObjects.RecordSet):
-
- def _postChanges(self):
- if not self.isPending(): return
- if self._deleteFlag:
- statement = self._buildDeleteStatement()
- elif self._insertFlag:
- statement = self._buildInsertStatement()
- elif self._updateFlag:
- statement = self._buildUpdateStatement()
-
- 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 = {}
- self._initialData.update(self._fields)
-
- except self._parent._dataObject._DatabaseError, err:
- raise GDataObjects.ConnectionError, err
-
- self._updateFlag = 0
- self._insertFlag = 0
- 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
- # as default. Note that these functions are specific to DB-SIG based
- # 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():
- if self._parent.isFieldBound(field):
- if self._initialData[field] == None:
- where.append ("%s IS NULL" % field)
- else:
- where.append ("%s=%s" % (field,
-
self._parent._dataObject._toSqlString(self._initialData[field])))
-
- statement = "DELETE FROM %s WHERE %s" % \
- (self._parent._dataObject.table, string.join(where,' AND ') )
- return statement
-
- def _buildInsertStatement(self):
- 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
(self._parent._dataObject._toSqlString(self._fields[field]))
-
- return "INSERT INTO %s (%s) VALUES (%s)" % \
- (self._parent._dataObject.table, string.join(fields,','), \
- string.join(vals,',') )
-
- def _buildUpdateStatement(self):
- updates = []
- for field in self._modifiedFlags.keys():
- updates.append ("%s=%s" % (field,
- self._parent._dataObject._toSqlString(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._parent._dataObject._toSqlString(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__(
- self,dataObject,cursor,defaultValues,masterRecordSet)
- self._recordSetClass = DBSIG_RecordSet
- self._fieldNames = []
-
- if self._cursor:
- for t in(self._cursor.description):
- self._fieldNames.append(t[0])
- GDebug.printMesg(5, "Field names set to %s" % self._fieldNames)
-
- self._recordCount = cursor.rowcount or 0
-
- GDebug.printMesg(5, 'ResultSet created')
-
- def _loadNextRecord(self):
- if self._cursor:
- rs = None
-
- try:
- rsets = self._cursor.fetchmany()
- except self._dataObject._DatabaseError, err:
- raise GDataObjects.ConnectionError, err
- if rsets and len(rsets):
- for rs in(rsets):
- if rs:
- i = 0
- dict = {}
- for f in (rs):
- dict[string.lower(self._fieldNames[i])] = f
- i += 1
- self._cachedRecords.append (self._recordSetClass(parent=self, \
-
initialData=dict))
- else:
- return 0
- return 1
- else:
- # We no longer need the cursor if we are read only
- if self._readonly:
- self._cursor.close()
- return 0
- else:
- return 0
-
-
- class DBSIG_DataObject(GDataObjects.DataObject):
-
- conditionElements = {
- 'add': (2, 999, '(%s)', '+' ),
- 'sub': (2, 999, '(%s)', '-' ),
- 'mul': (2, 999, '(%s)', '*' ),
- '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 ),
- 'null': (1, 1, '(%s IS NULL)', None ),
- 'notnull': (1, 1, '(%s IS NOT NULL)', None ),
- 'eq': (2, 2, '(%s = %s)', None ),
- 'ne': (2, 2, '(%s != %s)', None ),
- 'gt': (2, 2, '(%s > %s)', None ),
- 'ge': (2, 2, '(%s >= %s)', None ),
- 'lt': (2, 2, '(%s < %s)', None ),
- 'le': (2, 2, '(%s <= %s)', None ),
- 'like': (2, 2, '%s LIKE %s', None ),
- 'notlike': (2, 2, '%s NOT LIKE %s', None ),
- 'between': (3, 3, '%s BETWEEN %s AND %s', None ),
- 'notbetween': (3, 3, '(%s NOT BETWEEN %s AND %s)', None ),
- # These two are hacks... these are not really valid tags
- # Used when the 2nd value of EQ or NE is NULL.
- '__iseq': (2, 2, '(%s IS %s)', None ),
- '__isne': (2, 2, '(%s IS NOT %s)', None )}
-
- schema2nativeTypes={}
-
- def __init__(self, strictQueryCount=1):
- GDataObjects.DataObject.__init__(self)
-
- 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
-
- self.distinct = 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.
- #
- # 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
-
-
- # The date/time format used in insert/select statements
- # (based on format used for time.strftime())
- self._dateTimeFormat = "'%c'"
-
-
- def _toSqlString(self, value):
- try:
- return value.strftime(self._dateTimeFormat)
- except AttributeError:
- if value == None:
- return "NULL"
- elif type(value) == types.FloatType:
- if value==int(value):
- return "%d" % value
- else:
- return str(value)
-
- elif type(value) == types.UnicodeType:
- return "'%s'" %
string.replace(value.encode(gConfig("textEncoding")),"'",
- "%s'" % self._escapeSingleQuote)
- else:
-
- try:
- return "'%s'" % string.replace(str(value),"'",
- "%s'" % self._escapeSingleQuote)
- except:
- return "'%s'" % string.replace(value,"'",
- "%s'" % self._escapeSingleQuote)
-
-
-
- # 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,sql=""):
-
- # Used by drivers with a unique id (like rowid)
- if not self._primaryIdChecked: self._checkForPrimaryId()
-
- try:
- cursor = self._dataConnection.cursor()
-
- cursor.arraysize = self.cache
- cursor.execute(self._buildQuery(conditions, additionalSQL=sql))
-
- # pull a record count
- if self._strictQueryCount:
- recordCount = cursor.rowcount
- #disable the count query and see if anyone screams
- #recordCount = self._getQueryCount(conditions,sql)
-
- except self._DatabaseError, err:
- raise GDataObjects.ConnectionError, err
-
- rs = self._resultSetClass(self, cursor=cursor,
masterRecordSet=masterRecordSet)
- if self._strictQueryCount:
- rs._recordCount = recordCount
- if readOnly:
- rs._readonly = readOnly
-
- return rs
-
- def _getQueryCount(self,conditions={},sql=""):
- cursor = self._dataConnection.cursor()
-
- cursor.execute(self._buildQueryCount(conditions,additionalSQL=sql))
- rs = cursor.fetchone()
- return int(rs[0])
-
- def commit(self):
- GDebug.printMesg (5,"DB-SIG database driver: commit()")
-
- try:
- self._dataConnection.commit()
- except self._DatabaseError, value:
- raise GDataObjects.ConnectionError, value
-
- self._beginTransaction()
-
- def rollback(self):
- GDebug.printMesg (5,"DB-SIG database driver: rollback()")
-
- try:
- self._dataConnection.rollback()
- except:
- pass # I'm SURE this isn't right (jcater)
- # But not all db's support transactions
-
- self._beginTransaction()
-
-
- # Used to convert a condition tree to an sql where clause
- def _conditionToSQL (self, condition):
- if condition == {} or condition == None:
- return ""
- elif type(condition) == types.DictType:
- cond = GConditions.buildConditionFromDict(condition)
- else:
- cond = condition
-
- if not len(cond._children):
- return ""
- elif len(cond._children) > 1:
- chillun = cond._children[:]
- cond._children = []
- _and = GConditions.GCand(cond)
- _and._children = chillun
-
- where = " WHERE (%s)" % (self.__conditionToSQL (cond._children[0]))
- GDebug.printMesg(5, where)
- return where
-
- #
- # Used internally by _conditionToSQL
- #
- # This code recursively travels down a condition tree replacing the objects
- # with a strings representation
- def __conditionToSQL (self, element):
- if type(element) != types.InstanceType:
- return "%s" % element
- else:
- # Note that we strip the GC from the object types and lowercase the rest
- otype = string.lower(element._type[2:])
- #print "Otype: ",otype
- if otype == 'cfield':
- return "%s" % element.name
- elif otype == 'cconst':
- if element.value == None:
- return "NULL"
- elif element.type == 'number':
- return "%s" % element.value
- else:
- return self._toSqlString(element.value)
- elif otype == 'cparam':
- v = element.getValue()
- return (v == None and "NULL") or ("'%s'" % v)
- elif self.conditionElements.has_key(otype):
- result=[]
- for i in range(0, len(element._children)):
- result.append(self.__conditionToSQL(element._children[i]))
- if len(result) == 2 and \
- otype in ('eq','ne') and \
- result[1] == 'NULL':
- otype = "__is%s" % otype
- if len(result) < self.conditionElements[otype][0]:
- tmsg = _('Condition element "%s" expects at least %s arguments;
found %s') % \
- (otype, self.conditionElements[otype][0], len(result))
- raise GConditions.ConditionError, tmsg
- if len(result) > self.conditionElements[otype][1]:
- tmsg = _('Condition element "%s" expects at most %s arguments;
found %s') % \
- (otype, self.conditionElements[otype][0], len(result))
- raise GConditions.ConditionError, tmsg
-
- if self.conditionElements[otype][3] == None:
- return self.conditionElements[otype][2] % tuple(result)
- else:
- return self.conditionElements[otype][2] % \
- (string.join(result, self.conditionElements[otype][3]))
- else:
- tmsg = _('Condition clause "%s" is not supported by this db driver.')
% otype
- raise GConditions.ConditionNotSupported, tmsg
-
- # Code necessary to force the connection into transaction mode...
- # this is usually not necessary (MySQL is one of few DBs that must force)
- def _beginTransaction(self):
- pass
-
-
- def _buildFieldDefinition(self,field):
- try:
- sql="%s %s" % (field.name,
- self.schema2nativeTypes[field.type])
- except:
- tmsg = _("Datatype '%s' is not supported by database")
- raise GDataObjects.DataTypeNotAvailable, tmsg
-
- if hasattr(field,"size"):
- sql=sql+"(%s)" % field.size
-
- # if hasattr(field,"precision"):
- # if hasattr(field,"scale"):
-
- if not field.nullable:
- sql=sql+" NOT NULL"
-
- if hasattr(field,"default"):
- sql=sql+" DEFAULT %s" % self._toSqlString(field.default)
-
- return sql
-
- def _buildTableDefinition(self,tbl):
-
- sql="CREATE TABLE %s (" % tbl.name
-
-
- # add fields to table
-
- fields=tbl.findChildOfType("GSFields")
-
- delim=""
-
- for field in fields._children:
-
- sql=sql+delim+"%s" % self._buildFieldDefinition(field)
- delim=","
-
- # define primary key
-
- pk=tbl.findChildOfType("GSPrimaryKey")
-
- if (pk!=None) and len(pk._children):
-
- sql=sql+", primary key %s (" % pk.name
-
- delim=""
-
- for pkfield in pk._children:
-
- sql=sql+delim+pkfield.name
-
- delim=","
-
- sql=sql+") "
-
-
- # close definition
-
- sql=sql+");"
-
- GDebug.printMesg(1,"SQL Statement: %s" % sql)
-
- return sql
-
- def writeTable(self,tbl,overwrite):
-
- sql = self._buildTableDefinition(tbl)
-
- try:
- cursor = self._dataConnection.cursor()
- cursor.execute(sql)
- cursor.close()
- except:
- # test it is an error because of an existing table
- # directly raise an error, if it is an access rights problem
- if not overwrite:
- return "Could not write table %s to database." % tbl.name
- else:
- cursor = self._dataConnection.cursor()
- # drop table
- cursor.execute("drop table %s" % tbl.name)
- # create table
- cursor.execute(sql)
- cursor.close()
-
-
- # write Schema to Database
- def writeSchema(self,obj,overwrite=0):
- if obj._type=="GSTable":
- return self.writeTable(obj,overwrite)
-
- elif obj._type=="GSView":
- return self.writeView(obj,overwrite)
-
- else:
- # do the same for all children
- result=[]
- for child in obj._children:
- result.append(self.writeSchema(child))
-
- if len(result)==0:
- return None
- elif len(result)==1:
- return result[0]
- else:
- return result
-
-
-
- class DBSIG_DataObject_Object:
- def __init__(self):
- # TODO: A dummy placeholder to let old db driver work
- # TODO: each can have their *_DataObject_Object object from __init__ing
- # TODO: DBSIG_DataObject_Object
- GDebug.printMesg(0,
- "Database driver needs updated to not initialize
DBSIG_DataObject_Object")
-
- def _buildQuery(self, conditions={}, forDetail=None, additionalSQL=""):
- GDebug.printMesg(7,'Implicit Fields: %s' % self._fieldReferences)
- if self.distinct:
- distinct = "distinct "
- else:
- distinct = ""
-
- if self._primaryIdSelect:
- pis = "%s," % self._primaryIdSelect
- else:
- pis = ""
-
- whereClause = self._conditionToSQL(conditions)
- if additionalSQL:
- if len(whereClause):
- whereClause += ' and %s' % (additionalSQL)
- else:
- whereClause = ' WHERE %s' % (additionalSQL)
-
- if forDetail:
- q = "%s in (SELECT %s FROM %s%s)" % \
- (string.join(self._masterfields,","),
- string.join(self._detailfields,","),
- self.table, whereClause)
- elif len(self._fieldReferences):
- q = "SELECT %s%s%s FROM %s%s" % \
- (distinct, pis, string.join(self._fieldReferences.keys(),","),
self.table,
- whereClause)
- else:
- self._primaryIdSelect = None
- q = "SELECT %s* FROM %s%s" % (distinct, self.table,
- whereClause)
-
- if hasattr(self,'order_by') and not forDetail:
- q = "%s ORDER BY %s " % (q, self.order_by)
-
- GDebug.printMesg(5,q)
-
- return q
-
- def _buildQueryCount(self, conditions={}, additionalSQL=""):
- whereClause = self._conditionToSQL(conditions)
- if additionalSQL:
- if len(whereClause):
- whereClause += ' and %s' % (additionalSQL)
- else:
- whereClause = ' WHERE %s' % (additionalSQL)
-
-
- q = "SELECT count(*) FROM %s%s" % (self.table, whereClause)
-
- GDebug.printMesg(5,q)
-
- 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
- }
-
-
-
-
-
--- 0 ----
Index: gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py
diff -c gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py:1.1.2.1
gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py:1.1.2.2
*** gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py:1.1.2.1 Thu Oct
9 21:21:10 2003
--- gnue-common/src/datasources/drivers/DBSIG2/RecordSet.py Tue Nov 18
21:07:07 2003
***************
*** 31,37 ****
__all__ = ['RecordSet']
! from gnue.common.datasources import GDataObjects, GConditions
from gnue.common.apps import GDebug
import string
import types
--- 31,38 ----
__all__ = ['RecordSet']
! from gnue.common.datasources import GConditions, Exceptions
! from gnue.common.datasources.drivers.Base import RecordSet as BaseRecordSet
from gnue.common.apps import GDebug
import string
import types
***************
*** 41,47 ****
#
#
#
! class RecordSet(GDataObjects.RecordSet):
def _postChanges(self):
if not self.isPending(): return
--- 42,48 ----
#
#
#
! class RecordSet(BaseRecordSet):
def _postChanges(self):
if not self.isPending(): return
***************
*** 63,69 ****
self._initialData.update(self._fields)
except self._parent._dataObject._DatabaseError, err:
! raise GDataObjects.ConnectionError, err
self._updateFlag = 0
self._insertFlag = 0
--- 64,70 ----
self._initialData.update(self._fields)
except self._parent._dataObject._DatabaseError, err:
! raise Exceptions.ConnectionError, err
self._updateFlag = 0
self._insertFlag = 0
Index: gnue-common/src/datasources/drivers/DBSIG2/ResultSet.py
diff -c gnue-common/src/datasources/drivers/DBSIG2/ResultSet.py:1.1.2.2
gnue-common/src/datasources/drivers/DBSIG2/ResultSet.py:1.1.2.3
*** gnue-common/src/datasources/drivers/DBSIG2/ResultSet.py:1.1.2.2 Fri Oct
10 08:18:49 2003
--- gnue-common/src/datasources/drivers/DBSIG2/ResultSet.py Tue Nov 18
21:07:07 2003
***************
*** 33,51 ****
__all__ = ['ResultSet']
! from gnue.common.datasources import GDataObjects, GConditions
from gnue.common.apps import GDebug
import string
import types
from RecordSet import RecordSet
! class ResultSet(GDataObjects.ResultSet):
! def __init__(self, dataObject, cursor=None, \
! defaultValues={}, masterRecordSet=None):
! GDataObjects.ResultSet.__init__(
! self,dataObject,cursor,defaultValues,masterRecordSet)
! self._recordSetClass = RecordSet
self._fieldNames = []
if self._cursor:
--- 33,50 ----
__all__ = ['ResultSet']
! from gnue.common.datasources import GConditions, Exceptions
! from gnue.common.datasources.drivers.Base import ResultSet as BaseResultSet
from gnue.common.apps import GDebug
import string
import types
from RecordSet import RecordSet
! class ResultSet(BaseResultSet):
! _recordSetClass = RecordSet
! def __init__(self, *args, **parms):
! BaseResultSet.__init__(self, *args, **parms)
self._fieldNames = []
if self._cursor:
***************
*** 53,59 ****
self._fieldNames.append(t[0])
GDebug.printMesg(5, "Field names set to %s" % self._fieldNames)
! self._recordCount = cursor.rowcount or 0
GDebug.printMesg(5, 'ResultSet created')
--- 52,58 ----
self._fieldNames.append(t[0])
GDebug.printMesg(5, "Field names set to %s" % self._fieldNames)
! self._recordCount = self._cursor.rowcount or 0
GDebug.printMesg(5, 'ResultSet created')
***************
*** 64,70 ****
try:
rsets = self._cursor.fetchmany()
except self._dataObject._DatabaseError, err:
! raise GDataObjects.ConnectionError, err
if rsets and len(rsets):
for rs in(rsets):
if rs:
--- 63,69 ----
try:
rsets = self._cursor.fetchmany()
except self._dataObject._DatabaseError, err:
! raise Exceptions.ConnectionError, err
if rsets and len(rsets):
for rs in(rsets):
if rs:
Index: gnue-common/src/datasources/drivers/adodbapi/adodbapi/Connection.py
diff -c
gnue-common/src/datasources/drivers/adodbapi/adodbapi/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/adodbapi/adodbapi/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/adodbapi/adodbapi/Connection.py:1.1.2.1
Thu Oct 9 21:21:11 2003
--- gnue-common/src/datasources/drivers/adodbapi/adodbapi/Connection.py Tue Nov
18 21:07:08 2003
***************
*** 50,58 ****
class Connection(DBSIG2.Connection):
! _defaultBehavior = Introspection
_DatabaseError = SIG2api.DatabaseError
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 50,58 ----
class Connection(DBSIG2.Connection):
! defaultBehavior = Introspection
_DatabaseError = SIG2api.DatabaseError
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
diff -c
gnue-common/src/datasources/drivers/appserver/appserver/Connection.py:1.1.2.3
gnue-common/src/datasources/drivers/appserver/appserver/Connection.py:1.1.2.4
***
gnue-common/src/datasources/drivers/appserver/appserver/Connection.py:1.1.2.3
Fri Nov 7 11:14:22 2003
--- gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
Tue Nov 18 21:07:08 2003
***************
*** 33,39 ****
__all__ = ['Connection']
! from gnue.common.datasources import GDataObjects, GConditions, GConnection
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
--- 33,40 ----
__all__ = ['Connection']
! from gnue.common.datasources import GConditions, Exceptions
! from gnue.common.datasources.drivers.Base import Connection as BaseConnection
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
***************
*** 48,58 ****
from DataObject import DataObject
from gnue.common.datasources.drivers.appserver.Schema.Discovery.Introspection
import Introspection
! class Connection(GConnection.Connection):
_DatabaseError = GComm.Error
! _defaultBehavior = Introspection
! _supportedDataObjects = {
'object': DataObject
}
--- 49,59 ----
from DataObject import DataObject
from gnue.common.datasources.drivers.appserver.Schema.Discovery.Introspection
import Introspection
! class Connection(BaseConnection):
_DatabaseError = GComm.Error
! defaultBehavior = Introspection
! supportedDataObjects = {
'object': DataObject
}
***************
*** 60,67 ****
def getLoginFields(self):
return [['_username', 'User Name',0],['_password', 'Password',1]]
- def connect(self):
user = connectData['_username']
passwd = connectData['_password']
--- 61,68 ----
def getLoginFields(self):
return [['_username', 'User Name',0],['_password', 'Password',1]]
+ def connect(self, connectData):
user = connectData['_username']
passwd = connectData['_password']
Index: gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py
diff -c
gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py:1.1.2.2
gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py:1.1.2.3
***
gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py:1.1.2.2
Fri Oct 10 08:18:50 2003
--- gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py
Tue Nov 18 21:07:08 2003
***************
*** 31,37 ****
__all__ = ['DataObject']
! from gnue.common.datasources import GDataObjects, GConditions
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
--- 31,38 ----
__all__ = ['DataObject']
! from gnue.common.datasources import GConditions, Exceptions
! from gnue.common.datasources.drivers.Base import DataObject as BaseDataObject
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
***************
*** 42,48 ****
from ResultSet import *
! class DataObject(GDataObjects.DataObject):
_resultSetClass = ResultSet
--- 43,49 ----
from ResultSet import *
! class DataObject(BaseDataObject):
_resultSetClass = ResultSet
***************
*** 93,106 ****
GDebug.printMesg (5,"Setting Conditions ...");
filter = self._buildQuery(conditions)
except self._connection._DatabaseError, err:
! raise GDataObjects.ConnectionError, err
try:
listcursor =
self._dataConnection.request(self.table,filter,sort,fieldlist,\
self._dataObject._unicodeMode)
except Exception, msg:
tmsg = _("Error during creation of object list \n\n --- %s ---)") % msg
! raise GDataObjects.ConnectionError, tmsg
rs = self._resultSetClass(self, cursor=listcursor, masterRecordSet=None)
--- 94,107 ----
GDebug.printMesg (5,"Setting Conditions ...");
filter = self._buildQuery(conditions)
except self._connection._DatabaseError, err:
! raise Exceptions.ConnectionError, err
try:
listcursor =
self._dataConnection.request(self.table,filter,sort,fieldlist,\
self._dataObject._unicodeMode)
except Exception, msg:
tmsg = _("Error during creation of object list \n\n --- %s ---)") % msg
! raise Exceptions.ConnectionError, tmsg
rs = self._resultSetClass(self, cursor=listcursor, masterRecordSet=None)
Index: gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py
diff -c
gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py:1.1.2.2
gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py:1.1.2.3
***
gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py:1.1.2.2
Fri Nov 7 11:14:22 2003
--- gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py
Tue Nov 18 21:07:08 2003
***************
*** 29,35 ****
# HISTORY:
#
! from gnue.common.datasources import GDataObjects, GConditions
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
--- 29,36 ----
# HISTORY:
#
! from gnue.common.datasources import GConditions, Exceptions
! from gnue.common.datasources.drivers.Base import RecordSet as BaseRecordSet
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
***************
*** 38,45 ****
import md5
import sys
! class RecordSet(GDataObjects.RecordSet):
! def _postChanges(self):
def _postChanges(self):
if self._deleteFlag:
GDebug.printMesg(5, 'AppServer database driver: Instance deleted')
--- 39,45 ----
import md5
import sys
! class RecordSet(BaseRecordSet):
def _postChanges(self):
if self._deleteFlag:
GDebug.printMesg(5, 'AppServer database driver: Instance deleted')
Index: gnue-common/src/datasources/drivers/appserver/appserver/ResultSet.py
diff -c
gnue-common/src/datasources/drivers/appserver/appserver/ResultSet.py:1.1.2.1
gnue-common/src/datasources/drivers/appserver/appserver/ResultSet.py:1.1.2.2
***
gnue-common/src/datasources/drivers/appserver/appserver/ResultSet.py:1.1.2.1
Thu Oct 9 21:21:12 2003
--- gnue-common/src/datasources/drivers/appserver/appserver/ResultSet.py
Tue Nov 18 21:07:08 2003
***************
*** 29,35 ****
# HISTORY:
#
! from gnue.common.datasources import GDataObjects, GConditions
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
--- 29,36 ----
# HISTORY:
#
! from gnue.common.datasources import GConditions, Exceptions
! from gnue.common.datasources.drivers.Base import ResultSet as BaseResultSet
from gnue.common.apps import GDebug
from gnue.common.rpc import GComm
***************
*** 45,51 ****
# In the Appserver driver a CURSOR is simply the List handle returned
# via the query interface
#
! class ResultSet(GDataObjects.ResultSet):
_recordSetClass = RecordSet
--- 46,52 ----
# In the Appserver driver a CURSOR is simply the List handle returned
# via the query interface
#
! class ResultSet(BaseResultSet):
_recordSetClass = RecordSet
Index: gnue-common/src/datasources/drivers/db2/db2/Connection.py
diff -c gnue-common/src/datasources/drivers/db2/db2/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/db2/db2/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/db2/db2/Connection.py:1.1.2.1 Thu Oct
9 21:21:13 2003
--- gnue-common/src/datasources/drivers/db2/db2/Connection.py Tue Nov 18
21:07:08 2003
***************
*** 49,56 ****
class Connection(DBSIG2.DataObject):
_DatabaseError = "Database Error"
! _defaultBehavior = Introspection
! _supportedDataObjects = {
'object': DBSIG2.DataObject_Object,
'sql': DBSIG2.DataObject_SQL
}
--- 49,56 ----
class Connection(DBSIG2.DataObject):
_DatabaseError = "Database Error"
! defaultBehavior = Introspection
! supportedDataObjects = {
'object': DBSIG2.DataObject_Object,
'sql': DBSIG2.DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/dbf/dbf/Connection.py
diff -c gnue-common/src/datasources/drivers/dbf/dbf/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/dbf/dbf/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/dbf/dbf/Connection.py:1.1.2.1 Thu Oct
9 21:21:15 2003
--- gnue-common/src/datasources/drivers/dbf/dbf/Connection.py Tue Nov 18
21:07:08 2003
***************
*** 35,41 ****
class Connection(GConnection.Connection):
! _supportedDataObjects = {'object': DataObject,
'static': DataObject} # TODO: Why static?!?
_DatabaseError = Error
--- 35,41 ----
class Connection(GConnection.Connection):
! supportedDataObjects = {'object': DataObject,
'static': DataObject} # TODO: Why static?!?
_DatabaseError = Error
Index: gnue-common/src/datasources/drivers/gadfly/gadfly/Connection.py
diff -c gnue-common/src/datasources/drivers/gadfly/gadfly/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/gadfly/gadfly/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/gadfly/gadfly/Connection.py:1.1.2.1
Thu Oct 9 21:21:15 2003
--- gnue-common/src/datasources/drivers/gadfly/gadfly/Connection.py Tue Nov
18 21:07:08 2003
***************
*** 68,74 ****
class Connection(DBSIG2.Connection):
_DatabaseError = Error
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 68,74 ----
class Connection(DBSIG2.Connection):
_DatabaseError = Error
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/informix/informix/Connection.py
diff -c
gnue-common/src/datasources/drivers/informix/informix/Connection.py:1.1.2.2
gnue-common/src/datasources/drivers/informix/informix/Connection.py:1.1.2.3
*** gnue-common/src/datasources/drivers/informix/informix/Connection.py:1.1.2.2
Sat Nov 8 11:14:56 2003
--- gnue-common/src/datasources/drivers/informix/informix/Connection.py Tue Nov
18 21:07:08 2003
***************
*** 55,61 ****
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 55,61 ----
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/ingres/ingres/Connection.py
diff -c gnue-common/src/datasources/drivers/ingres/ingres/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/ingres/ingres/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/ingres/ingres/Connection.py:1.1.2.1
Thu Oct 9 21:21:18 2003
--- gnue-common/src/datasources/drivers/ingres/ingres/Connection.py Tue Nov
18 21:07:08 2003
***************
*** 56,62 ****
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 56,62 ----
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/mysql/mysql/Connection.py
diff -c gnue-common/src/datasources/drivers/mysql/mysql/Connection.py:1.1.2.2
gnue-common/src/datasources/drivers/mysql/mysql/Connection.py:1.1.2.3
*** gnue-common/src/datasources/drivers/mysql/mysql/Connection.py:1.1.2.2
Sat Nov 8 11:14:56 2003
--- gnue-common/src/datasources/drivers/mysql/mysql/Connection.py Tue Nov
18 21:07:08 2003
***************
*** 53,61 ****
#
class Connection(DBSIG2.Connection):
! _defaultBehavior = Introspection
_DatabaseError = MySQLdb.DatabaseError
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 53,61 ----
#
class Connection(DBSIG2.Connection):
! defaultBehavior = Introspection
_DatabaseError = MySQLdb.DatabaseError
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/oracle/Base/Connection.py
diff -c gnue-common/src/datasources/drivers/oracle/Base/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/oracle/Base/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/oracle/Base/Connection.py:1.1.2.1
Thu Oct 9 21:21:23 2003
--- gnue-common/src/datasources/drivers/oracle/Base/Connection.py Tue Nov
18 21:07:08 2003
***************
*** 47,53 ****
#
class Connection(DBSIG2.Connection):
! _defaultBehavior = Introspection
#
--- 47,53 ----
#
class Connection(DBSIG2.Connection):
! defaultBehavior = Introspection
#
Index: gnue-common/src/datasources/drivers/postgresql/Base/Connection.py
diff -c
gnue-common/src/datasources/drivers/postgresql/Base/Connection.py:1.1.2.3
gnue-common/src/datasources/drivers/postgresql/Base/Connection.py:1.1.2.4
*** gnue-common/src/datasources/drivers/postgresql/Base/Connection.py:1.1.2.3
Sat Nov 8 11:14:57 2003
--- gnue-common/src/datasources/drivers/postgresql/Base/Connection.py Tue Nov
18 21:07:08 2003
***************
*** 34,39 ****
--- 34,40 ----
from string import lower, join, split
import sys
from gnue.common.apps import GDebug, GConfig
+ from gnue.common.datasources import Exceptions
from gnue.common.datasources.drivers import DBSIG2
from DataObject import *
from
gnue.common.datasources.drivers.postgresql.Schema.Discovery.Introspection
import Introspection
***************
*** 45,52 ****
#
class Connection(DBSIG2.Connection):
! _defaultBehavior = Introspection
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 46,53 ----
#
class Connection(DBSIG2.Connection):
! defaultBehavior = Introspection
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
***************
*** 54,92 ****
_pg_connectString = 'host=%s dbname=%s user=%s password=%s port=%s'
_pg_driver = None
- _pg_encTable={'ascii' : 'SQL_ASCII', # ASCII
- '' : 'EUC_JP', # Japanese EUC
- '' : 'EUC_CN', # Chinese EUC
- '' : 'EUC_KR', # Korean EUC
- '' : 'JOHAB', # Korean EUC (Hangle
base)
- '' : 'EUC_TW', # Taiwan EUC
- 'utf-8' : 'UNICODE', # Unicode (UTF-8)
- '' : 'MULE_INTERNAL', # Mule internal code
- 'iso8859-1' : 'LATIN1', # ISO 8859-1 ECMA-94 Latin
Alphabet No.1
- 'iso8859-2' : 'LATIN2', # ISO 8859-2 ECMA-94 Latin
Alphabet No.2
- 'iso8859-3' : 'LATIN3', # ISO 8859-3 ECMA-94 Latin
Alphabet No.3
- 'iso8859-4' : 'LATIN4', # ISO 8859-4 ECMA-94 Latin
Alphabet No.4
- 'iso8859-9' : 'LATIN5', # ISO 8859-9 ECMA-128 Latin
Alphabet No.5
- 'iso8859-10': 'LATIN6', # ISO 8859-10 ECMA-144 Latin
Alphabet No.6
- 'iso8859-13': 'LATIN7', # ISO 8859-13 Latin Alphabet
No.7
- 'iso8859-14': 'LATIN8', # ISO 8859-14 Latin Alphabet
No.8
- 'iso8859-15': 'LATIN9', # ISO 8859-15 Latin Alphabet
No.9
- 'iso8859-16': 'LATIN10', # ISO 8859-16 ASRO SR 14111
Latin Alphabet No.10
- 'iso8859-5' : 'ISO-8859-5', # ECMA-113 Latin/Cyrillic
- 'iso8859-6' : 'ISO-8859-6', # ECMA-114 Latin/Arabic
- 'iso8859-7' : 'ISO-8859-7', # ECMA-118 Latin/Greek
- 'iso8859-8' : 'ISO-8859-8', # ECMA-121 Latin/Hebrew
- '' : 'KOI8', # KOI8-R(U)
- '' : 'WIN', # Windows CP1251
- '' : 'ALT', # Windows CP866
- '' : 'WIN1256', # Arabic Windows CP1256
- '' : 'TCVN', # Vietnamese TCVN-5712
(Windows CP1258)
- '' : 'WIN874'} # Thai Windows CP874
! def connect(self
, connectData={}):
print "Postgresql database driver initializing"
!
if not hasattr(self,'_DatabaseError'):
self._DatabaseError = self._pg_driver.DatabaseError
--- 55,65 ----
_pg_connectString = 'host=%s dbname=%s user=%s password=%s port=%s'
_pg_driver = None
! def connect(self, connectData):
print "Postgresql database driver initializing"
!
if not hasattr(self,'_DatabaseError'):
self._DatabaseError = self._pg_driver.DatabaseError
***************
*** 111,131 ****
connectData['_password'],
port)))
GDebug.printMesg(1,"Exception %s " % value)
! raise GDataObjects.LoginError, value
try:
try:
! self._encoding = connectData['encoding']
! except KeyError:
! pass
!
! try:
! self._pg_encoding = self._pg_encTable[self._encoding]
except KeyError:
GDebug.printMesg(1,_("Encoding '%s' is not supported by postgresql
dbdriver.") % \
self._encoding + _('Using default encoding.'))
self._pg_encoding = ''
!
if self._pg_encoding not in ("",'DEFAULT'):
GDebug.printMesg(1,'Setting postgresql client_encoding to %s (%s)' %
(self._pg_encoding,
self._encoding))
--- 84,99 ----
connectData['_password'],
port)))
GDebug.printMesg(1,"Exception %s " % value)
! raise Exceptions.LoginError, _("The PostgreSQL driver returned the
following error:\n\t%s") % value
try:
try:
! self._pg_encoding = pg_encTable[self._encoding]
except KeyError:
GDebug.printMesg(1,_("Encoding '%s' is not supported by postgresql
dbdriver.") % \
self._encoding + _('Using default encoding.'))
self._pg_encoding = ''
!
if self._pg_encoding not in ("",'DEFAULT'):
GDebug.printMesg(1,'Setting postgresql client_encoding to %s (%s)' %
(self._pg_encoding,
self._encoding))
***************
*** 186,188 ****
--- 154,185 ----
return rv[0]
except:
return None
+
+ pg_encTable = {'ascii' : 'SQL_ASCII', # ASCII
+ '' : 'EUC_JP', # Japanese EUC
+ '' : 'EUC_CN', # Chinese EUC
+ '' : 'EUC_KR', # Korean EUC
+ '' : 'JOHAB', # Korean EUC (Hangle
base)
+ '' : 'EUC_TW', # Taiwan EUC
+ 'utf-8' : 'UNICODE', # Unicode (UTF-8)
+ '' : 'MULE_INTERNAL', # Mule internal code
+ 'iso8859-1' : 'LATIN1', # ISO 8859-1 ECMA-94 Latin
Alphabet No.1
+ 'iso8859-2' : 'LATIN2', # ISO 8859-2 ECMA-94 Latin
Alphabet No.2
+ 'iso8859-3' : 'LATIN3', # ISO 8859-3 ECMA-94 Latin
Alphabet No.3
+ 'iso8859-4' : 'LATIN4', # ISO 8859-4 ECMA-94 Latin
Alphabet No.4
+ 'iso8859-9' : 'LATIN5', # ISO 8859-9 ECMA-128 Latin
Alphabet No.5
+ 'iso8859-10': 'LATIN6', # ISO 8859-10 ECMA-144 Latin
Alphabet No.6
+ 'iso8859-13': 'LATIN7', # ISO 8859-13 Latin Alphabet
No.7
+ 'iso8859-14': 'LATIN8', # ISO 8859-14 Latin Alphabet
No.8
+ 'iso8859-15': 'LATIN9', # ISO 8859-15 Latin Alphabet
No.9
+ 'iso8859-16': 'LATIN10', # ISO 8859-16 ASRO SR 14111
Latin Alphabet No.10
+ 'iso8859-5' : 'ISO-8859-5', # ECMA-113 Latin/Cyrillic
+ 'iso8859-6' : 'ISO-8859-6', # ECMA-114 Latin/Arabic
+ 'iso8859-7' : 'ISO-8859-7', # ECMA-118 Latin/Greek
+ 'iso8859-8' : 'ISO-8859-8', # ECMA-121 Latin/Hebrew
+ '' : 'KOI8', # KOI8-R(U)
+ '' : 'WIN', # Windows CP1251
+ '' : 'ALT', # Windows CP866
+ '' : 'WIN1256', # Arabic Windows CP1256
+ '' : 'TCVN', # Vietnamese TCVN-5712
(Windows CP1258)
+ '' : 'WIN874'} # Thai Windows CP874
Index: gnue-common/src/datasources/drivers/postgresql/Base/DataObject.py
diff -c
gnue-common/src/datasources/drivers/postgresql/Base/DataObject.py:1.1.2.1
gnue-common/src/datasources/drivers/postgresql/Base/DataObject.py:1.1.2.2
*** gnue-common/src/datasources/drivers/postgresql/Base/DataObject.py:1.1.2.1
Thu Oct 9 21:21:26 2003
--- gnue-common/src/datasources/drivers/postgresql/Base/DataObject.py Tue Nov
18 21:07:08 2003
***************
*** 33,45 ****
from gnue.common.datasources.drivers import DBSIG2
!
! class DataObject_SQL(DBSIG2.DataObject_SQL):
_escapeSingleQuote = '\\'
_dateTimeFormat = "'%Y-%m-%d %H:%M:%S'"
! class DataObject_Object(DBSIG2.DataObject_Object):
! _escapeSingleQuote = '\\'
! _dateTimeFormat = "'%Y-%m-%d %H:%M:%S'"
--- 33,46 ----
from gnue.common.datasources.drivers import DBSIG2
! class _Base:
_escapeSingleQuote = '\\'
_dateTimeFormat = "'%Y-%m-%d %H:%M:%S'"
+ class DataObject_SQL(_Base, DBSIG2.DataObject_SQL):
+ def __init__(self, *args, **parms):
+ DBSIG2.DataObject_SQL.__init__(self, *args, **parms)
! class DataObject_Object(_Base, DBSIG2.DataObject_Object):
! pass
Index: gnue-common/src/datasources/drivers/postgresql/pypgsql/Driver.py
diff -c
gnue-common/src/datasources/drivers/postgresql/pypgsql/Driver.py:1.35.2.2
gnue-common/src/datasources/drivers/postgresql/pypgsql/Driver.py:1.35.2.3
*** gnue-common/src/datasources/drivers/postgresql/pypgsql/Driver.py:1.35.2.2
Sat Nov 8 11:14:58 2003
--- gnue-common/src/datasources/drivers/postgresql/pypgsql/Driver.py Tue Nov
18 21:07:08 2003
***************
*** 38,43 ****
--- 38,44 ----
try:
from pyPgSQL import PgSQL # pyPgSQL 2.0 support
except ImportError:
+ # TODO: Re-evaluate the minimum version we support!
import PgSQL # pyPgSQL 1.6 support
***************
*** 89,95 ****
_pg_driver = PgSQL
_pg_connectString = '%s::%s:%s:%s::%s'
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 90,96 ----
_pg_driver = PgSQL
_pg_connectString = '%s::%s:%s:%s::%s'
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/sapdb/sapdb/Connection.py
diff -c gnue-common/src/datasources/drivers/sapdb/sapdb/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/sapdb/sapdb/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/sapdb/sapdb/Connection.py:1.1.2.1
Thu Oct 9 21:21:30 2003
--- gnue-common/src/datasources/drivers/sapdb/sapdb/Connection.py Tue Nov
18 21:07:09 2003
***************
*** 80,87 ****
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! _defaultBehavior = Introspection
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 80,87 ----
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! defaultBehavior = Introspection
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py
diff -c gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py:1.1.2.1
Thu Oct 9 21:21:33 2003
--- gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py Tue Nov
18 21:07:09 2003
***************
*** 56,63 ****
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! _defaultBehavior = Introspection
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 56,63 ----
class Connection(DBSIG2.Connection):
_DatabaseError = SIG2api.DatabaseError
! defaultBehavior = Introspection
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/sqlrelay/sqlrelay/Connection.py
diff -c
gnue-common/src/datasources/drivers/sqlrelay/sqlrelay/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/sqlrelay/sqlrelay/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/sqlrelay/sqlrelay/Connection.py:1.1.2.1
Thu Oct 9 21:21:34 2003
--- gnue-common/src/datasources/drivers/sqlrelay/sqlrelay/Connection.py Tue Nov
18 21:07:09 2003
***************
*** 61,69 ****
#
class Connection(DBSIG2.Connection):
! _defaultBehavior = Introspection
_DatabaseError = SIG2api.DatabaseError
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 61,69 ----
#
class Connection(DBSIG2.Connection):
! defaultBehavior = Introspection
_DatabaseError = SIG2api.DatabaseError
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
Index: gnue-common/src/datasources/drivers/sybase/sybase/Connection.py
diff -c gnue-common/src/datasources/drivers/sybase/sybase/Connection.py:1.1.2.1
gnue-common/src/datasources/drivers/sybase/sybase/Connection.py:1.1.2.2
*** gnue-common/src/datasources/drivers/sybase/sybase/Connection.py:1.1.2.1
Thu Oct 9 21:21:35 2003
--- gnue-common/src/datasources/drivers/sybase/sybase/Connection.py Tue Nov
18 21:07:09 2003
***************
*** 54,60 ****
class Connection(DBSIG2.Connection)
_DatabaseError = SIG2api.DatabaseError
! _supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
--- 54,60 ----
class Connection(DBSIG2.Connection)
_DatabaseError = SIG2api.DatabaseError
! supportedDataObjects = {
'object': DataObject_Object,
'sql': DataObject_SQL
}
- CVSROOT: /cvsroot/gnue, Jason Cater, 2003/11/07
- CVSROOT: /cvsroot/gnue, Jason Cater, 2003/11/08
- CVSROOT: /cvsroot/gnue, Jason Cater, 2003/11/18
- CVSROOT: /cvsroot/gnue,
Jason Cater <=
- CVSROOT: /cvsroot/gnue, Jason Cater, 2003/11/18
- CVSROOT: /cvsroot/gnue, Jason Cater, 2003/11/18
- CVSROOT: /cvsroot/gnue, Jason Cater, 2003/11/18
- CVSROOT: /cvsroot/gnue, Jan Ischebeck, 2003/11/19
- CVSROOT: /cvsroot/gnue, Jan Ischebeck, 2003/11/19
- CVSROOT: /cvsroot/gnue, Jan Ischebeck, 2003/11/19
- CVSROOT: /cvsroot/gnue, Jan Ischebeck, 2003/11/19