~ubuntu-branches/ubuntu/hardy/gnue-common/hardy

« back to all changes in this revision

Viewing changes to src/datasources/drivers/gadfly/gadfly/RecordSet.py

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2005-03-09 11:06:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050309110631-8gvvn39q7tjz1kj6
Tags: upstream-0.5.14
ImportĀ upstreamĀ versionĀ 0.5.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# This file is part of GNU Enterprise.
 
3
#
 
4
# GNU Enterprise is free software; you can redistribute it
 
5
# and/or modify it under the terms of the GNU General Public
 
6
# License as published by the Free Software Foundation; either
 
7
# version 2, or (at your option) any later version.
 
8
#
 
9
# GNU Enterprise is distributed in the hope that it will be
 
10
# useful, but WITHOUT ANY WARRANTY; without even the implied
 
11
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
12
# PURPOSE. See the GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public
 
15
# License along with program; see the file COPYING. If not,
 
16
# write to the Free Software Foundation, Inc., 59 Temple Place
 
17
# - Suite 330, Boston, MA 02111-1307, USA.
 
18
#
 
19
# Copyright 2000-2005 Free Software Foundation
 
20
#
 
21
# FILE:
 
22
# gadfly/DBdriver.py
 
23
#
 
24
# DESCRIPTION:
 
25
# Driver to provide access to data via Gadfly
 
26
#
 
27
# NOTES:
 
28
# The Gadfly notes state that it is not safe to use in a multi-user environment
 
29
# where there may be concurrent read/writes. Use at own risk :)
 
30
 
 
31
 
 
32
import string
 
33
import sys
 
34
from gnue.common.apps import GDebug
 
35
from gnue.common.datasources import GDataObjects
 
36
from gnue.common.datasources.drivers import DBSIG2
 
37
 
 
38
import gadfly
 
39
 
 
40
raise "This data driver has not been upgraded to the new format."
 
41
 
 
42
class Gadfly_RecordSet(DBSIG2.RecordSet): 
 
43
  pass
 
44
 
 
45
 
 
46
class Gadfly_ResultSet(DBSIG2.ResultSet): 
 
47
  def __init__(self, dataObject, cursor=None, defaultValues={}, masterRecordSet=None):
 
48
    cursor.rowcount=0
 
49
    DBSIG2.ResultSet.__init__(self, dataObject, \
 
50
            cursor, defaultValues, masterRecordSet)
 
51
    self._recordSetClass = Gadfly_RecordSet
 
52
    
 
53
  def _loadNextRecord(self):
 
54
    if self._cursor:
 
55
      rs = None
 
56
 
 
57
      try:
 
58
        rsets = self._cursor.fetchall()
 
59
      except self._dataObject._connection._DatabaseError, err:
 
60
        raise GDataObjects.ConnectionError, err
 
61
 
 
62
      if rsets and len(rsets):
 
63
        for rs in(rsets):
 
64
          if rs:
 
65
            i = 0
 
66
            dict = {}
 
67
            for f in (rs):
 
68
              dict[string.lower(self._fieldNames[i])] = f
 
69
              i += 1
 
70
            self._cachedRecords.append (self._recordSetClass(parent=self, \
 
71
                                                             initialData=dict))
 
72
          else:
 
73
            return 0
 
74
        return 1
 
75
      else:
 
76
        return 0
 
77
    else:
 
78
     return 0
 
79
 
 
80
##### EVIL HACK
 
81
class Error(StandardError):
 
82
  """Generic Error"""
 
83
 
 
84
class InterfaceError(Error):
 
85
  """Interface Error"""
 
86
  
 
87
class DatabaseError(InterfaceError):
 
88
  """DB Error"""
 
89
 
 
90
class DataError(DatabaseError):
 
91
  """Data Error"""
 
92
 
 
93
class OperationalError(DatabaseError):
 
94
  """Operational Error"""
 
95
  
 
96
class IntegrityError(DatabaseError):
 
97
  """Integrity Error"""
 
98
 
 
99
##### END EVIL HACK
 
100
 
 
101
class Gadfly_DataObject(DBSIG2.DataObject):
 
102
 
 
103
 
 
104
  def __init__(self): 
 
105
    DBSIG2.DataObject.__init__(self)
 
106
    self._DatabaseError = Error
 
107
    self._resultSetClass = Gadfly_ResultSet
 
108
 
 
109
    # LIKE is not supported on database level at the moment
 
110
    # there should be used other ways to emulate it
 
111
    # until that works, do a = instead of a like
 
112
    # EVIL HACK
 
113
    self.conditionElements.update({\
 
114
       'like':            (2,   2, '%s = %s',             None     ),\
 
115
       'notlike':         (2,   2, 'NOT (%s = %s)',       None     )})
 
116
    # END EVIL HACK
 
117
 
 
118
 
 
119
 
 
120
  def connect(self, connectData={}): 
 
121
    gDebug(9,"Gadfly database driver initializing")
 
122
    #GDebug.printMesg(1,"Connecting with %s, %s" %( connectData['_dbname'], connectData['directory']))
 
123
    try:
 
124
      self._dataConnection = gadfly.gadfly(connectData['dbname'],
 
125
                                           connectData['directory'])
 
126
    except self._DatabaseError, value:
 
127
      #GDebug.printMesg(1,"Boom")
 
128
      raise GDataObjects.LoginError, value
 
129
      
 
130
    self._beginTransaction()
 
131
    self._postConnect()
 
132
 
 
133
 
 
134
  def _postConnect(self): 
 
135
    self.triggerExtensions = TriggerExtensions(self._dataConnection)
 
136
 
 
137
 
 
138
  def _beginTransaction(self):
 
139
    try:
 
140
      self._dataConnection.begin()
 
141
    except: 
 
142
      pass
 
143
 
 
144
  # This should be over-ridden only if driver needs more than user/pass
 
145
  def getLoginFields(self):
 
146
    return []
 
147
 
 
148
  #
 
149
  # Schema (metadata) functions
 
150
  #
 
151
 
 
152
  # Return a list of the types of Schema objects this driver provides
 
153
  def getSchemaTypes(self):
 
154
    return [('view',_('Views'),1),
 
155
            ('table',_('Tables'),1)]
 
156
 
 
157
  # Return a list of Schema objects
 
158
  def getSchemaList(self, type=None):
 
159
 
 
160
    statement = "select * from __table_names__"
 
161
 
 
162
    cursor = self._dataConnection.cursor()
 
163
    GDebug.printMesg(1,"** Executing: %s **" % statement)
 
164
    cursor.execute(statement)    
 
165
 
 
166
    list = []
 
167
    for rs in cursor.fetchall():
 
168
      # exclude any system tables and views. f.e. __table_names__
 
169
      if rs[1][:2]!="__":       
 
170
        list.append(GDataObjects.Schema(attrs={'id':rs[1], 'name':rs[1], \
 
171
                                'type':rs[0] == 1 and 'view' or 'table',},
 
172
                                       getChildSchema=self.__getFieldSchema))
 
173
 
 
174
    cursor.close()
 
175
    return list
 
176
 
 
177
 
 
178
  # Find a schema object with specified name
 
179
  def getSchemaByName(self, name, type=None):
 
180
    statement = "SELECT * from __table_names__ WHERE TABLE_NAME='%s'" % (name)
 
181
 
 
182
    cursor = self._dataConnection.cursor()
 
183
    GDebug.printMesg(1,"** Executing: %s **" % statement)
 
184
    cursor.execute(statement)
 
185
 
 
186
    rs = cursor.fetchone()
 
187
    if rs:
 
188
      schema = GDataObjects.Schema(attrs={'id':rs[1], 'name':rs[1], \
 
189
                                'type':rs[0] == 1 and 'view' or 'table',},
 
190
                                       getChildSchema=self.__getFieldSchema)
 
191
    else:
 
192
      schema = None
 
193
 
 
194
    cursor.close()
 
195
    return schema
 
196
 
 
197
 
 
198
  # Get fields for a table
 
199
  def __getFieldSchema(self, parent):
 
200
 
 
201
    # TODO: Read whole definitions from __DATADEFS__ and parse them
 
202
    #       to distinguish between varchar, float and integer
 
203
    
 
204
    statement = "SELECT * FROM __COLUMNS__ WHERE TABLE_NAME='%s'" % parent.id
 
205
 
 
206
    cursor = self._dataConnection.cursor()
 
207
    GDebug.printMesg(1,"** Executing: %s **" % statement)
 
208
    cursor.execute(statement)
 
209
    columns = cursor.description
 
210
 
 
211
    list = []
 
212
    for rs in cursor.fetchall():
 
213
 
 
214
      #nativetype = string.split(string.replace(rs[1],')',''),'(')
 
215
 
 
216
 
 
217
      attrs={'id': "%s.%s" % (parent.id, rs[0]), 'name': rs[0],
 
218
             'type':'field', 'nativetype': 'varchar',
 
219
             'required': 0}
 
220
 
 
221
      #if nativetype[0] in ('int','integer','bigint','mediumint',
 
222
      #                     'smallint','tinyint','float','real',
 
223
      #                     'double','decimal'):
 
224
      #  attrs['datatype']='number'
 
225
      #elif nativetype[0] in ('date','time','timestamp','datetime'):
 
226
      #  attrs['datatype']='date'
 
227
      #else:
 
228
      #  attrs['datatype']='text'
 
229
 
 
230
      ## MORE EVILNESS
 
231
      attrs['datatype']='text'
 
232
      ##END HACK
 
233
      
 
234
      #try:
 
235
      #  if len(nativetype) == 2:
 
236
      #    attrs['length'] = int(string.split(nativetype[1])[0])
 
237
      #except ValueError:
 
238
      #  GDebug.printMesg(1,'WARNING: mysql native type error: %s' % nativetype)
 
239
 
 
240
      list.append(GDataObjects.Schema(attrs=attrs))
 
241
 
 
242
    cursor.close()
 
243
    return list
 
244
 
 
245
 
 
246
 
 
247
 
 
248
class Gadfly_DataObject_Object(Gadfly_DataObject, \
 
249
      DBSIG2.DataObject_Object):
 
250
 
 
251
  def __init__(self):
 
252
    Gadfly_DataObject.__init__(self)
 
253
 
 
254
  def _buildQuery(self, conditions={},forDetail=None,additionalSQL=""):
 
255
    return DBSIG2.DataObject_Object._buildQuery(self, conditions,forDetail,additionalSQL)
 
256
 
 
257
  def _getQueryCount(self,conditions={}):
 
258
    cursor = self._dataConnection.cursor()
 
259
 
 
260
    cursor.execute(self._buildQueryCount(conditions))
 
261
    # GADFLY throws an error if executing COUNT(*) on an empty set
 
262
    try:
 
263
      rs = cursor.fetchone()
 
264
      return int(rs[0])
 
265
    except:
 
266
      return 0
 
267
 
 
268
  def _buildQueryCount(self, conditions={}):
 
269
    # GADFLY seems to hate big letter "SELECT"
 
270
    q = "select count(*) from %s%s" % (self.table, self._conditionToSQL(conditions))
 
271
 
 
272
    GDebug.printMesg(5,q)
 
273
 
 
274
    return q
 
275
 
 
276
class Gadfly_DataObject_SQL(Gadfly_DataObject, \
 
277
      DBSIG2.DataObject_SQL):
 
278
  def __init__(self):
 
279
    # Call DBSIG init first because Gadfly_DataObject needs to overwrite
 
280
    # some of its values
 
281
    DBSIG2.DataObject_SQL.__init__(self)
 
282
    Gadfly_DataObject.__init__(self)
 
283
 
 
284
  def _buildQuery(self, conditions={}):
 
285
    return DBSIG2.DataObject_SQL._buildQuery(self, conditions)
 
286
 
 
287
 
 
288
 
 
289
#
 
290
#  Extensions to Trigger Namespaces
 
291
#  
 
292
class TriggerExtensions: 
 
293
 
 
294
  def __init__(self, connection): 
 
295
    self.__connection = connection
 
296
 
 
297
  # Return the current date, according to database
 
298
#  def getDate(self): 
 
299
#    pass
 
300
 
 
301
  # Return a sequence number from sequence 'name' 
 
302
#  def getSequence(self, name): 
 
303
#    pass
 
304
 
 
305
  # Run the SQL statement 'statement'
 
306
#  def sql(self, statement): 
 
307
#    pass
 
308
 
 
309
 
 
310
 
 
311
######################################
 
312
#
 
313
#  The following hashes describe 
 
314
#  this driver's characteristings.
 
315
#
 
316
######################################
 
317
 
 
318
#
 
319
#  All datasouce "types" and corresponding DataObject class
 
320
 
321
supportedDataObjects = {
 
322
  'object': Gadfly_DataObject_Object,
 
323
  'sql':    Gadfly_DataObject_SQL
 
324
}
 
325
 
 
326