[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gnue gnue-common/src/GDataObjects.py gnue-commo...
From: |
Jason Cater |
Subject: |
gnue gnue-common/src/GDataObjects.py gnue-commo... |
Date: |
Sun, 04 Nov 2001 17:04:49 -0500 |
CVSROOT: /home/cvs
Module name: gnue
Changes by: Jason Cater <address@hidden> 01/11/04 17:04:48
Modified files:
gnue-common/src: GDataObjects.py
gnue-common/src/dbdrivers/odbc: DBdriver.py
gnuef/src : GFForm.py UIbase.py UIwxpython.py
gnuef/src/GFObjects: GFBlock.py
Log message:
fixes to form's exception handling, rollbacks
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/GDataObjects.py.diff?cvsroot=OldCVS&tr1=1.26&tr2=1.27&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue-common/src/dbdrivers/odbc/DBdriver.py.diff?cvsroot=OldCVS&tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnuef/src/GFForm.py.diff?cvsroot=OldCVS&tr1=1.127&tr2=1.128&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnuef/src/UIbase.py.diff?cvsroot=OldCVS&tr1=1.46&tr2=1.47&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnuef/src/UIwxpython.py.diff?cvsroot=OldCVS&tr1=1.115&tr2=1.116&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnuef/src/GFObjects/GFBlock.py.diff?cvsroot=OldCVS&tr1=1.20&tr2=1.21&r1=text&r2=text
Patches:
Index: gnue/gnue-common/src/GDataObjects.py
diff -u gnue/gnue-common/src/GDataObjects.py:1.26
gnue/gnue-common/src/GDataObjects.py:1.27
--- gnue/gnue-common/src/GDataObjects.py:1.26 Sun Nov 4 13:36:32 2001
+++ gnue/gnue-common/src/GDataObjects.py Sun Nov 4 17:04:48 2001
@@ -95,7 +95,7 @@
self._dataConnection = None
self._resultSetClass = ResultSet
self._fieldReferences = {} # Set by GDataSource; lists all fields
- # a client explicits references
+ # a client explicits references
self._unboundFieldReferences = {} # Contains names of all unbound
# field references
@@ -134,7 +134,7 @@
# the master ResultSet and the detail ResultSet
def addDetailDataObject(self, dataObject, handler=None, **params):
- for param in params.keys():
+ for param in params.keys():
dataObject.__dict__[param] = params[param]
GDebug.printMesg (1,"Adding a master/detail relationship to DataObject")
@@ -215,11 +215,11 @@
# Return a list of the types of Schema objects this driver provides
# Contains tuples of (key, description, dataSource??)
# dataSource?? is true if this schema type can be a datasource
- def getSchemaTypes(self):
+ def getSchemaTypes(self):
return []
# Return a list of Schema objects
- def getSchemaList(self, type=None):
+ def getSchemaList(self, type=None):
return []
# Find a schema object with specified name
@@ -514,9 +514,9 @@
# Returns 1=Record is pending an insertion
def isInserted(self):
- if self._emptyFlag:
+ if self._emptyFlag:
return 0
- else:
+ else:
return self._insertFlag
Index: gnue/gnue-common/src/dbdrivers/odbc/DBdriver.py
diff -u gnue/gnue-common/src/dbdrivers/odbc/DBdriver.py:1.4
gnue/gnue-common/src/dbdrivers/odbc/DBdriver.py:1.5
--- gnue/gnue-common/src/dbdrivers/odbc/DBdriver.py:1.4 Wed Aug 29 20:23:12 2001
+++ gnue/gnue-common/src/dbdrivers/odbc/DBdriver.py Sun Nov 4 17:04:48 2001
@@ -1,270 +1,162 @@
#
# 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
+# 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
+# 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
+# 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 Free Software Foundation
+# Copyright 2000, 2001 Free Software Foundation
#
# FILE:
-# DBdriver.py
+# odbc/DBdriver.py
#
# DESCRIPTION:
-# Driver to provide access to data vi ODBC
-# Accessed via the GFBlock object
+# Driver to provide access to data via the mxODBC Driver
+# Requires mxODBC (http://)
#
# NOTES:
#
-import string
+# Supported attributes (via connections.conf or <database> tag)
+#
+# host= This is the ODBC host for your connection (required)
+# service= This is the ODBC connection string to use
+#
+
+#### THIS IS AN UNTESTED DRIVER ####
+#### Any volunteers? ####
+
+
+from string import lower
import sys
-#from gnue.forms import GFOptions
-from gnue.forms.GFError import DBError
+from gnue.common import GDebug, GDataObjects, GConnections
+from gnue.common.dbdrivers._dbsig.DBdriver \
+ import DBSIG_RecordSet, DBSIG_ResultSet, DBSIG_DataObject, \
+ DBSIG_DataObject_SQL, DBSIG_DataObject_Object
+
+try:
+ import sapdbapi as SIG2api
+except ImportError, message:
+ raise GConnections.AdapterNotInstalled, \
+ "Driver not installed: sapdbapi for SAP-DB 7.x \n[%s]" % message
+
+
+class ODBC_RecordSet(DBSIG_RecordSet):
+ pass
+
+
+class ODBC_ResultSet(DBSIG_ResultSet):
+ def __init__(self, dataObject, cursor=None, defaultValues={},
masterRecordSet=None):
+ DBSIG_ResultSet.__init__(self, dataObject, \
+ cursor, defaultValues, masterRecordSet)
+ self._recordSetClass = ODBC_RecordSet
+
-class DBdriver:
+
+class ODBC_DataObject(DBSIG_DataObject):
def __init__(self):
- GDebug.printMesg(1,"ODBC database driver initializing")
- self.connection = None
- self.cursor = None
- self.uniqueKey = None
- self.oldMaskData = {}
- self.maskCount = 1
+ DBSIG_DataObject.__init__(self)
+ self._DatabaseError = SIG2api.DatabaseError
+ self._resultSetClass = ODBC_ResultSet
- def connect(self, dbhost, dbname, dbuser, dbpasswd):
- GDebug.printMesg(1,"connecting")
- try:
- self.connection = self.driver.DriverConnect(self.dsn)
- self.cursor = self.connection.cursor()
- self.triggerExtensions = TriggerExtensions(self.connection)
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
- def disconnect(self):
+ def connect(self, connectData={}):
+ GDebug.printMesg(1,"SAP database driver initializing")
try:
- self.connection.close()
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
+ self._dataConnection = SIG2api.connect( \
+ user=connectData['_username'], \
+ password=connectData['_password'], \
+ database=connectData['dbname'], \
+ host=connectData['host'], \
+ autocommit="off")
+ except self._DatabaseError, value:
+ raise GDataObjects.ConnectError, value
- def beginTransaction(self):
- try:
- pass
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
+ self._postConnect()
- def commit(self):
- try:
- pass
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
- def rollback(self):
- try:
- pass
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
+ #
+ # Schema (metadata) functions
+ #
- def insert(self, table, mask):
- for fieldname in mask.keys():
- if mask[fieldname] == None or len(mask[fieldname]) == 0:
- del mask[fieldname]
+ # TODO: See postgresql for an example of what these functions do.
- command = self.constructSQL('insert', table, mask)
- try:
- self.cursor.execute(command)
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
- mask[self.uniqueKey] = self.getMaskCount()
- return mask
-
- def delete(self, table, mask):
- command = self.constructSQL('delete', table, mask)
- try:
- self.cursor.execute(command)
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
+ # Return a list of the types of Schema objects this driver provides
+ def getSchemaTypes(self):
+ return [('view','View',1), ('table','Table',1)]
- def update(self, table, mask):
- command = self.constructSQL('update', table, mask)
- try:
- self.cursor.execute(command)
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
-
- def getFieldList(self, table):
- l = {}
- self.fieldlist = {}
- self.fieldlistmap = {}
- self.cursor.columns(None, None, table, None)
- try:
- rs = self.cursor.fetchall()
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
-
- self.getUniqueKey(table)
- self.fieldlistmap[self.uniqueKey] = 0
- i = 1
- for r in rs:
- l[r[3]] = "text"
- self.fieldlistmap[r[3]] = i
- i = i + 1
-
- self.fieldlist = l
- return l
+ # Return a list of Schema objects
+ def getSchemaList(self, type=None):
+ return []
- def query(self, table, mask, order_by = None):
- command = self.constructSQL('query',table, mask)
- try:
- self.cursor.execute(command)
- except:
- raise DBError, "Database Error: %s" % (sys.exc_info()[1])
- rs = self.cursor.fetchall()
- self.oldMaskData = {}
- self.maskCount = 1
- nrs = []
- for r in rs:
- l = {}
- l[self.uniqueKey] = self.getMaskCount()
- i = 0
- for key in self.cursor.description:
- l[key[0]] = r[i]
- i = i + 1
-
- # add to oldMaskData to preserve old info for use in WHERE clause
- self.oldMaskData[int(l[self.uniqueKey])] = self.copyDict(l)
- nrs.append(l)
-
- return nrs
-
- def constructSQL(self, style, table, mask = None):
- sql = None
- fields = None
- qualifier = None
-
- if style == 'query':
- action = "SELECT "
- location = "FROM %s " % (table)
- fields = " * "
-
- if type(mask) == type({}):
- fields = "%s" % (string.join(mask.keys(), ','))
- fields = string.replace(fields, "%s," % (self.uniqueKey), '')
- fields = "%s " % (fields)
- for fieldname in mask.keys():
- if fieldname != self.uniqueKey:
- if mask[fieldname] != None and len(mask[fieldname]):
- if qualifier == None:
- qualifier = "WHERE %s LIKE '%s'" % (fieldname,mask[fieldname])
- else:
- qualifier = "%s AND %s LIKE '%s'" % (qualifier,
fieldname,mask[fieldname])
-
- sql = action + fields + location + (qualifier and qualifier or "")
-
- elif style == 'insert':
- action = "INSERT "
- location = "INTO %s " % (table)
- values = None
-
- if type(mask) == type({}):
- fields = "(%s) " % (string.join(mask.keys(), ','))
- for fieldname in mask.keys():
- if fieldname != self.uniqueKey:
- if mask[fieldname] != None and len(mask[fieldname]):
- if values == None:
- values = "VALUES ('%s'" % (mask[fieldname])
- else:
- values = "%s, '%s'" % (values, mask[fieldname])
- values = "%s)" % (values)
-
- sql = action + location + fields + values + (qualifier and qualifier or
"")
-
- elif style == 'update':
- action = "UPDATE "
- location = "%s " % (table)
- values = " SET "
- qualifier = " WHERE "
-
- if type(mask) == type({}):
- for fieldname in mask.keys():
- if fieldname != self.uniqueKey:
- if mask[fieldname] != None and len(mask[fieldname]):
- values = "%s %s='%s'," % (values, fieldname, mask[fieldname])
- qualifier = "%s %s='%s' AND" % (qualifier, fieldname,
self.oldMaskData[int(mask[self.uniqueKey])][fieldname])
- values = values[:-1]
- qualifier = qualifier[:-3]
-
- sql = action + location + values + (qualifier and qualifier or "")
-
- elif style == 'delete':
- action = "DELETE FROM "
- location = "%s " % (table)
- values = ""
- qualifier = " WHERE "
-
- if type(mask) == type({}):
- for fieldname in mask.keys():
- if fieldname != self.uniqueKey:
- if mask[fieldname] != None and len(mask[fieldname]):
- qualifier = "%s %s='%s' AND" % (qualifier, fieldname,
self.oldMaskData[int(mask[self.uniqueKey])][fieldname])
- qualifier = qualifier[:-3]
-
- sql = action + location + values + (qualifier and qualifier or "")
-
- else:
- print "constructSQL: unsupport SQL statement type"
-
- return sql
-
- def getUniqueKey(self, table):
- self.uniqueKey = "uniqueKey_%s" % (table)
- return self.uniqueKey
-
- def getMaskCount(self):
- self.maskCount = self.maskCount + 1
- return self.maskCount - 1
-
- def copyDict(self, dict):
- nd = {}
- for key in dict.keys():
- nd[key] = dict[key]
-
- return nd
-
- def loadDriver(self, driver):
- GDebug.printMesg(1,"Loading ODBC subpackage %s" % (driver[1]))
- self.driver = __import__("ODBC/%s" % (driver[1]))
- if len(driver) > 2:
- self.dsn = driver[2]
+ # Find a schema object with specified name
+ def getSchemaByName(self, name, type=None):
+ return None
+ def _postConnect(self):
+ self.triggerExtensions = TriggerExtensions(self._dataConnection)
+
+class ODBC_DataObject_Object(ODBC_DataObject, \
+ DBSIG_DataObject_Object):
+
+ def __init__(self):
+ # Call DBSIG init first because ODBC_DataObject needs to overwrite
+ # some of its values
+ DBSIG_DataObject_Object.__init__(self)
+ ODBC_DataObject.__init__(self)
+
+ def _buildQuery(self, conditions={}):
+ return DBSIG_DataObject_Object._buildQuery(self, conditions)
+
+
+class ODBC_DataObject_SQL(ODBC_DataObject, \
+ DBSIG_DataObject_SQL):
+ def __init__(self):
+ # Call DBSIG init first because ODBC_DataObject needs to overwrite
+ # some of its values
+ DBSIG_DataObject_SQL.__init__(self)
+ ODBC_DataObject.__init__(self)
+
+ def _buildQuery(self, conditions={}):
+ return DBSIG_DataObject_SQL._buildQuery(self, conditions)
+
+
#
# Extensions to Trigger Namespaces
-#
-class TriggerExtensions:
+#
+class TriggerExtensions:
- def __init__(self, connection):
+ def __init__(self, connection):
self.__connection = connection
+
+
+
+
- # Return the current date, according to database
-# def getDate(self):
-# pass
-
- # Return a sequence number from sequence 'name'
-# def getSequence(self, name):
-# pass
-
- # Run the SQL statement 'statement'
-# def sql(self, statement):
-# pass
+######################################
+#
+# The following hashes describe
+# this driver's characteristings.
+#
+######################################
+
+#
+# All datasouce "types" and corresponding DataObject class
+#
+supportedDataObjects = {
+ 'object': ODBC_DataObject_Object,
+ 'sql': ODBC_DataObject_SQL
+}
Index: gnue/gnuef/src/GFForm.py
diff -u gnue/gnuef/src/GFForm.py:1.127 gnue/gnuef/src/GFForm.py:1.128
--- gnue/gnuef/src/GFForm.py:1.127 Sun Nov 4 15:26:38 2001
+++ gnue/gnuef/src/GFForm.py Sun Nov 4 17:04:48 2001
@@ -12,8 +12,8 @@
# 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
+# 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, 2001 Free Software Foundation
@@ -35,7 +35,7 @@
from gnue.common import GDebug, openResource, GConnections, GConfig
from GFObjects import *
from GFEvent import *
-from GFError import DBError
+from gnue.common.GDataObjects import ConnectionError as DBError
from GFTriggerError import *
from GFLibrary import *
import GFLibrary
@@ -57,7 +57,7 @@
# Insert/Overwrite mode
self._insertMode = 1
-
+
# Focus information
self._currentPage = None
self._currentBlock = None
@@ -239,7 +239,7 @@
hasattr(object, id) and \
object.__dict__[id] == find.__dict__[id]:
return object
- elif hasattr(object,'_children'):
+ elif hasattr(object,'_children'):
rv = None
for child in object._children:
rv = self.__findImportItem(find, child, id)
@@ -301,7 +301,7 @@
entry.setValue(entry.queryDefault)
self._currentBlock.initQuery()
return message
-
+
def executeQuery(self):
self._app.dispatchEvent(GFEvent('beginWAIT',None));
@@ -310,7 +310,7 @@
self._currentBlock.processQuery()
except DBError:
- self.processRollback()
+ self.rollback(1)
message = "Database query error:\n%s\n%s " % (sys.exc_info()[0],
sys.exc_info()[1])
self._app.dispatchEvent(GFEvent('endWAIT',None));
@@ -347,14 +347,14 @@
message = 'Form is readonly'
self._app.dispatchEvent(GFEvent('endWAIT',None));
return message
-
+
self.processTrigger('Post-Commit')
except DBError:
- self.processRollback()
+ self.rollback(1)
message = "Database commit error:\n%s\n%s " % (sys.exc_info()[0],
sys.exc_info()[1])
except:
- print "\n\nGFForm: Unexpected Exception:"
+ print "\n\nGFForm: Unexpected Exception:"
print '-'*60
traceback.print_exc(file=sys.stdout)
print '-'*60
@@ -372,21 +372,21 @@
self.dispatchEvent(GFEvent('uiABOUT',[version,name,formversion,author,description]))
- def rollback(self):
+ def rollback(self, recover=0):
for block in self._blockList:
- block.processRollback();
+ block.processRollback(recover);
self._currentBlock.jumpRecord(self._currentBlock._currentRecord)
-
-
+
+
# i question if this fuction is needed as one could just use t.msg
-# however i gave it a return and converted print to debugas some of the
+# however i gave it a return and converted print to debugas some of the
# stuff using this hasnt been migrated to use the return
def TriggerErrorFunc(self, t):
't is an instance of TriggerError'
trigMsg = "Trigger Exception :\n" + t.msg
GDebug.printMesg(0, trigMsg)
- return trigMsg
+ return trigMsg
#
# changeFocus
Index: gnue/gnuef/src/GFObjects/GFBlock.py
diff -u gnue/gnuef/src/GFObjects/GFBlock.py:1.20
gnue/gnuef/src/GFObjects/GFBlock.py:1.21
--- gnue/gnuef/src/GFObjects/GFBlock.py:1.20 Wed Oct 10 13:11:29 2001
+++ gnue/gnuef/src/GFObjects/GFBlock.py Sun Nov 4 17:04:48 2001
@@ -194,7 +194,7 @@
jump = self._resultSet.getRecordNumber() - self._currentRecord
self._currentRecord = self._resultSet.getRecordNumber()
self.switchRecord(jump)
-
+
#
# processCommit
#
@@ -202,7 +202,7 @@
GDebug.printMesg(1, "processing commit on block %s"%self.name)
self.mode='commit'
- if not self._dataSourceLink.hasMaster():
+ if not self._dataSourceLink.hasMaster():
self._resultSet.post()
self._dataSourceLink._dataObject.commit()
@@ -212,10 +212,12 @@
#
# processRollback
#
- def processRollback(self):
- self._currentRecord = 0
- self._recordCount = 0
- self._dataSourceLink.createEmptyResultSet()
+ def processRollback(self, recovering=0):
+ self.mode='normal'
+ if not recovering:
+ self._currentRecord = 0
+ self._recordCount = 0
+ self._dataSourceLink.createEmptyResultSet()
self.switchRecord(0)
#
@@ -231,7 +233,7 @@
self.mode = 'query'
self._query2 = int(GConfig.get("RememberLastQuery","1"))
self._queryValues = {}
- for entry in self._queryDefaults.keys():
+ for entry in self._queryDefaults.keys():
entry.setValue(self._queryDefaults[entry])
self.switchRecord(0)
elif self._query2:
@@ -287,7 +289,7 @@
elif len(conditionLike.keys()):
conditions = GConditions.buildConditionFromDict(conditionLike,
GConditions.GClike)
- elif len(conditionEq.keys()):
+ elif len(conditionEq.keys()):
conditions = GConditions.buildConditionFromDict(conditionEq,
GConditions.GCeq)
else:
Index: gnue/gnuef/src/UIbase.py
diff -u gnue/gnuef/src/UIbase.py:1.46 gnue/gnuef/src/UIbase.py:1.47
--- gnue/gnuef/src/UIbase.py:1.46 Fri Oct 12 20:06:18 2001
+++ gnue/gnuef/src/UIbase.py Sun Nov 4 17:04:48 2001
@@ -8,11 +8,11 @@
#
# 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
+# 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,
+# 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.
#
Index: gnue/gnuef/src/UIwxpython.py
diff -u gnue/gnuef/src/UIwxpython.py:1.115 gnue/gnuef/src/UIwxpython.py:1.116
--- gnue/gnuef/src/UIwxpython.py:1.115 Sun Nov 4 13:36:33 2001
+++ gnue/gnuef/src/UIwxpython.py Sun Nov 4 17:04:48 2001
@@ -19,7 +19,7 @@
# Copyright 2000, 2001 Free Software Foundation
#
# FILE:
-# UIwxpython
+# UIwxpython.py
#
# DESCRIPTION:
# A wxPython based user interface for GNUE forms.
@@ -81,7 +81,7 @@
def getLargest(val1, val2):
if val1 > val2:
return val1
- else:
+ else:
return val2
- gnue gnue-common/src/GDataObjects.py gnue-commo...,
Jason Cater <=