Hello,
I've been working on adding the ability to create tables easily on any
database to Dabo.
I have created a diff and put it at the end of this email. It fully
works with SQLite. I haven't started on any of the other databases
yet.
So I was wondering if the way I created it was good or not. I would
like to know your opinions before I started the support for other
databases.

--
-Echo

Here is the diff:
Index: dabo/db/__init__.py
===================================================================
--- dabo/db/__init__.py (revision 1873)
+++ dabo/db/__init__.py (working copy)
@@ -30,3 +30,4 @@
 from dCursorMixin import dCursorMixin
 from dMemento import dMemento
 from dConnectInfo import dConnectInfo
+from dTable import dTable
\ No newline at end of file
Index: dabo/db/dBackend.py
===================================================================
--- dabo/db/dBackend.py (revision 1873)
+++ dabo/db/dBackend.py (working copy)
@@ -364,7 +364,19 @@
                auxCrs.execute(tmpsql)
                return auxCrs.FieldDescription
        
+       def CreateJustTable(self, tabledef, cursor):
+               self.CreateTableAndIndex(tabledef, cursor, CreateIndexes=False)
+               
+       def CreateJustIndexes(self, tabledef, cursor):
+               self.CreateTableAndIndexes(tabledef, cursor, CreateTable=False)
        
+       def CreateTableAndIndexes(self, tabledef, cursor, CreateTable=True,
CreateIndex=True):
+               """Creates a table and/or indexes based on the dTable passed to 
it.
+               """
+               
+               # OVERRIDE IN SUBCLASSES!
+               pass
+       
        ###########################################     
        # The following methods by default simply return the text
        # supplied to them. If a particular backend (Firebird comes
Index: dabo/db/dbSQLite.py
===================================================================
--- dabo/db/dbSQLite.py (revision 1873)
+++ dabo/db/dbSQLite.py (working copy)
@@ -19,9 +19,12 @@
                return self.dbapi.Cursor

        def escQuote(self, val):
+               if val is None:
+                       return self.formatNone()
+                       
                sl = "\\"
                qt = "\'"
-               return qt + val.replace(sl, sl+sl).replace(qt, qt+qt) + qt
+               return qt + str(val).replace(sl, sl+sl).replace(qt, qt+qt) + qt
        
        def formatDateTime(self, val):
                """ We need to wrap the value in quotes. """
@@ -165,3 +168,68 @@
                                fields.append( (rec["name"], fldType, False))
                        ret = tuple(fields)
                return ret
+
+       def CreateTableAndIndexes(self, tabledef, cursor, CreateTable=True,
CreateIndexes=True):
+               if tabledef.Name == '':
+                       raise
+                       
+               #Create the table
+               if CreateTable == True:
+                       if tabledef.IsTemp == False:
+                               sql = 'CREATE TABLE '
+                       else:
+                               sql = 'CREATE TEMP TABLE '
+                               
+                       sql = sql + tabledef.Name + ' ('
+                       
+                       for f in tabledef.Fields:
+                               sql = sql + f.Name + ' '
+                               
+                               if f.DataType == 'Numeric':
+                                       sql = sql + 'INTEGER '
+                                       if f.IsPK:
+                                               sql = sql + 'PRIMARY KEY '
+                                               if f.IsAutoIncrement == True:
+                                                       sql = sql + 
'AUTOINCREMENT '
+                               elif f.DataType == 'Float':
+                                       sql = sql + 'REAL '
+                               elif f.DataType == 'String':
+                                       sql = sql + 'TEXT '
+                               elif f.DataType == 'Date':
+                                       sql = sql + 'TEXT '
+                               elif f.DataType == 'Time':
+                                       sql = sql + 'TEXT '
+                               elif f.DataType == 'DateTime':
+                                       sql = sql + 'TEXT '
+                               elif f.DataType == 'Stamp':
+                                       sql = sql + 'TEXT '
+                               elif f.DataType == 'Binary':
+                                       sql = sql + 'BLOB '
+                                       
+                               if f.AllowNulls == False:
+                                       sql = sql + 'NOT NULL '
+                               
+                               sql = sql + 'DEFAULT ' + 
self.escQuote(f.Default) + ','
+                               
+                       if sql[-1:] == ',':
+                               sql = sql[:-1]
+                       sql = sql + ')'
+                       
+                       cursor.execute(sql)
+
+               if CreateIndexes == True:
+                       #Create the indexes
+                       for i in tabledef.Indexes:
+                               if i.Name.lower() != 'primary':
+                                       sql = 'CREATE INDEX ' + i.Name + ' ON ' 
+ tabledef.Name + '('
+                                       
+                                       for f in i.Fields:
+                                               sql = sql + f + ','
+                               
+                                       if sql[-1:] == ',':
+                                               sql = sql[:-1]
+                                       sql = sql + ')'
+                               
+                       cursor.execute(sql)
+               
+               
\ No newline at end of file
Index: dabo/db/dCursorMixin.py
===================================================================
--- dabo/db/dCursorMixin.py     (revision 1873)
+++ dabo/db/dCursorMixin.py     (working copy)
@@ -1335,6 +1335,20 @@
                        ret = 
self.BackendObject.rollbackTransaction(self.AuxCursor)
                return ret
        
+       def CreateTable(self, tabledef):
+               """Create a table based on the table definition.
+               """
+               self.BackendObject.CreateJustTable(tabledef, self)
+               
+       def CreateIndexes(self, tabledef):
+               """Create indexes based on the table definition.
+               """
+               self.BackendObject.CreateJustIndexes(tabledef, self)
+               
+       def CreateTableAndIndexes(self, tabledef):
+               """Create a table and its indexes based on the table definition.
+               """
+               self.BackendObject.CreateTableAndIndexes(tabledef, self)

        ###     SQL Builder methods     ########
        def getFieldClause(self):
Index: dabo/db/dTable.py
===================================================================
--- dabo/db/dTable.py   (revision 0)
+++ dabo/db/dTable.py   (revision 0)
@@ -0,0 +1,325 @@
+from dabo.dLocalize import _
+import dabo.dException as dException
+from dabo.dObject import dObject
+
+class dTable(dObject):
+       """This class is used to hold information about a table so it can be
created on any database.
+       
+       For example:
+               To define a temporary table named 'mytemp' that has ? fields, 
where
the fields are:
+                       field 1: 'theid', it is an autoincrementing field that 
uses a 2 byte integer
+                       field 2: 'first_name', it is a string field that has a 
max of 25
charactors, part of an indexes 'idx_first' and 'idx_name'
+                       field 3: 'last_name', it is a string field that has a 
max of 25
charactors, NULL's are not allowed,
+                                                       part of an indexes 
'idx_last' and 'idx_name'
+                       field 4: 'amount_owes', it is a float that has a 
percision of 2
and uses 8 bytes, the default is 0
+                       
+               Code:
+                       from dabo.db import dTable
+                       
+                       mytable = dTable(Name='mytemp', IsTemp=True)
+                       mytable.AddField(Name='theid', IsPK=True, 
DataType='int', Size=2,
IsAutoIncrement=True)
+                       mytable.AddField(Name='first_name', DataType='string', 
Size=25,
Index='idx_first')
+                       mytable.AddField(Name='last_name', DataType='string', 
Size=25,
AllowNulls=False, Index='idx_last')
+                       mytable.AddField(Name='amount_owes', DataType='float',
Percision=2, Size=8, Default=0)
+                       
+                       #When you want to have more than one field in an index, 
use AddIndex().
+                       mytable.AddIndex(Name='idx_name', 
Fields=('last_name','first_name'))
+                       
+       """
+       def __init__(self, *args, **kwargs):
+               self._baseClass = dTable
+               
+               self._name = ''
+               self._is_temp = False
+               self._fields = []
+               self._indexes = []
+               self._pk = None
+               dTable.doDefault(*args, **kwargs)
+               
+       def __str__(self):
+               t = ''
+               
+               t = t + 'Table Name: ' + self._name
+               if self._is_temp == True:
+                       t = t + '\n  is TEMPOARY\n'
+               
+               t = t + '\nFields:\n'
+               for f in self._fields:
+                       t = t + ' ' + str(f) + '\n'
+                       
+               t = t + '\nIndexes:\n'          
+               for i in self._indexes:
+                       t = t + ' ' + str(i) + '\n'
+                       
+               return t
+               
+       def AddField(self, *args, **kwargs):
+               """Add a field to the table.
+               
+               Properties:
+                       
+               """
+               
+               #Check if adding an index
+               try:
+                       i = kwargs['Index']
+                       name = kwargs['Name']
+               except:
+                       pass
+               else:
+                       self._indexes.append(dIndex(Name=i,Fields=name))
+                       del kwargs['Index']
+                       
+               #Check if setting PK
+               try:
+                       pk = kwargs['IsPK']
+                       name = kwargs['Name']
+               except:
+                       pass
+               else:
+                       if pk == True:
+                               self._pk = name
+               
+               self._fields.append(dField(*args, **kwargs))
+               
+       def AddIndex(self, *args, **kwargs):
+               """Add an index to the table.
+               """             
+               self._indexes.append(dIndex(*args, **kwargs))
+               
+       def _SetName(self, name):
+               self._name = name
+       def _GetName(self):
+               return self._name
+               
+       def _SetIsTemp(self, value):
+               self._is_temp = value
+       def _GetIsTemp(self):
+               return self._is_temp
+               
+       def _GetFields(self):
+               return self._fields
+               
+       def _GetIndexes(self):
+               return self._indexes
+               
+       def _GetPK(self):
+               return self._pk
+               
+       Name = property(_GetName, _SetName, None, _('The name of the table. 
(str)'))
+       IsTemp = property(_GetIsTemp, _SetIsTemp, None, _('Weather or not
the table is temporary. (bool)'))
+       Fields = property(_GetFields, None, None, _('List of the fields in
the table. (list)'))
+       Indexes = property(_GetIndexes, None, None, _('List of the indexes
in the table. (list)'))
+       PK = property(_GetPK, None, None, _('The primary key of the table. 
(str)'))
+       
+class dIndex(dObject):
+       def __init__(self, *args, **kwargs):
+               self._baseClass = dIndex
+               
+               self._name = ''
+               self._fields = None
+               
+               dIndex.doDefault(*args, **kwargs)
+               
+       def __str__(self):
+               t = self._name + ' ('
+               
+               for f in self._fields:
+                       t = t + f + ','
+                       
+               if t[-1:] == ',':
+                       t = t[:-1]
+               
+               return t + ')'
+               
+       def _SetName(self, name):
+               self._name = name
+       def _GetName(self):
+               return self._name
+               
+       def _SetFields(self, fields):
+               if isinstance(fields, str):
+                       f = fields.split()
+                       self._fields = tuple(f)
+               elif isinstance(fields, list):
+                       self._fields = tuple(f)
+               else:
+                       self._fields = fields
+       def _GetFields(self):
+               return self._fields
+               
+       Name = property(_GetName, _SetName)
+       Fields = property(_GetFields, _SetFields)
+
+class dField(dObject):
+       def __init__(self, *args, **kwargs):
+               self._baseClass = dField
+       
+               self._name = ''
+               self._type = fType()
+               self._allow_nulls = True
+               self._default = None
+               self._autoincrement = False
+               self._pk = False
+               dField.doDefault(*args, **kwargs)
+               
+       def __str__(self):
+               if self._allow_nulls:
+                       allowednulls = 'Nulls Allowed'
+               else:
+                       allowednulls = 'Nulls Not Allowed'
+                       
+               if self._autoincrement:
+                       autoi = ' Auto Incrementing'
+               else:
+                       autoi = ''
+                       
+               if self._pk:
+                       pk = ' PK'
+               else:
+                       pk = ''
+               
+               return '%s%s (%s, Size:%i, Percision:%i)%s %s Default:%s' %
(self._name, pk, self._type.DataType, self._type.Size,
self._type.Percision, autoi, allowednulls, self._default)
+       
+       def _SetName(self, name):
+               self._name = name
+       def _GetName(self):
+               return self._name
+               
+       def _SetType(self, type):
+               self._type = type
+       def _GetType(self):
+               return self._type
+               
+       def _SetDataType(self, datatype):
+               self._type.DataType = datatype
+       def _GetDataType(self):
+               return self._type.DataType
+               
+       def _SetSize(self, size):
+               self._type.Size = size
+       def _GetSize(self):
+               return self._type.Size
+               
+       def _SetPercision(self, value):
+               self._type.Percision = value
+       def _GetPercision(self):
+               return self._type.Percision
+       
+       def _SetAllowNulls(self, allow):
+               self._allow_nulls = allow
+       def _GetAllowNulls(self):
+               return self._allow_nulls
+               
+       def _SetDefault(self, default):
+               self._default = default
+       def _GetDefault(self):
+               return self._default
+               
+       def _SetAutoIncrement(self, auto):
+               self._autoincrement = auto
+       def _GetAutoIncrement(self):
+               return self._autoincrement
+               
+       def _SetPK(self, value):
+               self._pk = value
+       def _GetPK(self):
+               return self._pk
+               
+       Name = property(_GetName, _SetName, None, _('The name of the table. 
(str)'))
+       Type = property(_GetType, _SetType, None, _('The type of the column.
(class)'))
+       DataType = property(_GetDataType, _SetDataType, None, _('The type of
the column. (str)'))
+       Size = property(_GetSize, _SetSize, None, _('The size required for
the column in bytes. (int)'))
+       Percision = property(_GetPercision, _SetPercision, None, _('The
number of decimal places to the right of the period. (int)'))
+       AllowNulls = property(_GetAllowNulls, _SetAllowNulls, None,
_('Weather or not nulls are allowed. Default:True (bool)'))
+       Default = property(_GetDefault, _SetDefault, None, _('The default
value for the field. Default:None (str)'))
+       IsAutoIncrement = property(_GetAutoIncrement, _SetAutoIncrement,
None, _('Weather or not the field is an auto incrementing field.
Default:False (bool)'))
+       IsPK = property(_GetPK, _SetPK, None, _('Weather or not the field
has the primary key. (bool)'))
+       
+class fType(dObject):
+       """Dabo DB Field Type - Used to hold the information about types of
fields in any database.
+       """
+       def __init__(self, *args, **kwargs):
+               self._baseClass = fType
+               
+               self._data_type = 'Numeric'
+               self._size = 1
+               self._percision = 0
+               
+               fType.doDefault(*args, **kwargs)
+               
+       def _SetDataType(self, datatype):
+               """Allowed types:
+                               Numeric
+                               Float
+                               String
+                               Date
+                               Time
+                               DateTime
+                               Stamp
+                               Binary
+                               """
+
+               check = {'numeric': 'Numeric',
+                                               'int': 'Numeric',
+                                               'integer': 'Numeric',
+                                               
+                                               'float': 'Float',
+                                               'decimal': 'Float',             
                        
+                                               
+                                               'string': 'String',
+                                               'varchar': 'String',
+                                               'char': 'String',
+                                               
+                                               'date': 'Date',
+                                               
+                                               'time': 'Time',
+                                               
+                                               'datetime': 'DateTime',
+                                               
+                                               'stamp': 'Stamp',
+                                               
+                                               'binary': 'Binary',
+                                               }
+               
+               self._data_type = check[datatype.lower()]
+       def _GetDataType(self):
+               return self._data_type
+               
+       def _SetSize(self, size):
+               self._size = size
+       def _GetSize(self):
+               return self._size
+               
+       def _SetPercision(self, percision):
+               self._percision = percision
+       def _GetPercision(self):
+               return self._percision
+               
+       DataType = property(_GetDataType, _SetDataType)
+       Size = property(_GetSize, _SetSize)
+       Percision = property(_GetPercision, _SetPercision)
+       
+       
+if __name__ == '__main__':
+       print '\n\nstarting\n'
+       
+       #type = fType(DataType='String', Size=25)
+       #print type.getProperties(('DataType','Size'))
+       
+       #col = dField(Name='colname', Type=fType(DataType='String',Size=50))
+       #print col
+       #col = dField(Name='colname', DataType='String', Size=50)
+       #print col
+       
+       mytable = dTable(Name='mytemp', IsTemp=True)
+       mytable.AddField(Name='theid', IsPK=True, DataType='int', Size=2,
IsAutoIncrement=True)
+       mytable.AddField(Name='first_name', DataType='string', Size=25,
Index='idx_first')
+       mytable.AddField(Name='last_name', DataType='string', Size=25,
AllowNulls=False, Index='idx_last')
+       mytable.AddField(Name='amount_owes', DataType='float', Percision=2,
Size=8, Default=0)
+       
+       #When you want to have more than one field in an index, use AddIndex().
+       mytable.AddIndex(Name='idx_name', Fields=('last_name','first_name'))
+       
+       print mytable
+

_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev

Reply via email to