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

« back to all changes in this revision

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