[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r7712 - in trunk/gnue-common/src/datasources/drivers/sql: . maxdb
From: |
johannes |
Subject: |
[gnue] r7712 - in trunk/gnue-common/src/datasources/drivers/sql: . maxdb sqlite2 sqlite3 |
Date: |
Fri, 8 Jul 2005 04:15:45 -0500 (CDT) |
Author: johannes
Date: 2005-07-08 04:15:44 -0500 (Fri, 08 Jul 2005)
New Revision: 7712
Added:
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/Behavior.py
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/__init__.py
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlite2drv.py
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlitedrv.py
trunk/gnue-common/src/datasources/drivers/sql/sqlite3/
trunk/gnue-common/src/datasources/drivers/sql/sqlite3/Behavior.py
Removed:
trunk/gnue-common/src/datasources/drivers/sql/sqlite/
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/Behavior.py
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/__init__.py
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlite2drv.py
trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlitedrv.py
Modified:
trunk/gnue-common/src/datasources/drivers/sql/maxdb/maxdbdrv.py
Log:
Startet split of sqlite driver
Modified: trunk/gnue-common/src/datasources/drivers/sql/maxdb/maxdbdrv.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/sql/maxdb/maxdbdrv.py
2005-07-08 09:09:19 UTC (rev 7711)
+++ trunk/gnue-common/src/datasources/drivers/sql/maxdb/maxdbdrv.py
2005-07-08 09:15:44 UTC (rev 7712)
@@ -108,6 +108,7 @@
_behavior_ = Behavior.Behavior
_named_as_sequence_ = True
+ _broken_rowcount_ = True
_std_datetime_ = True
Copied: trunk/gnue-common/src/datasources/drivers/sql/sqlite2 (from rev 7707,
trunk/gnue-common/src/datasources/drivers/sql/sqlite)
Deleted: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/Behavior.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/sql/sqlite/Behavior.py
2005-07-07 21:20:20 UTC (rev 7707)
+++ trunk/gnue-common/src/datasources/drivers/sql/sqlite2/Behavior.py
2005-07-08 09:15:44 UTC (rev 7712)
@@ -1,461 +0,0 @@
-# GNU Enterprise Common Library - Schema support for SQLite
-#
-# Copyright 2000-2005 Free Software Foundation
-#
-# 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.
-#
-# $Id$
-
-"""
-Schema support plugin for SQLite.
-"""
-
-import re
-
-from gnue.common.apps import errors
-from gnue.common.datasources import GSchema
-from gnue.common.datasources.drivers import DBSIG2
-
-
-# ===========================================================================
-# Regular expressions and constants
-# ===========================================================================
-
-_REPCOMMAS = re.compile ('\(\s*(\d+)\s*,\s*(\d+)\s*\)')
-_ALIGN = re.compile ('\s*\(\s*(.*?)\s*\)')
-_LEN_SCALE = re.compile ('^\s*(\w+)\s*\((\d+)[;]{0,1}(\d*)\)\s*')
-_TEXTTYPE = re.compile ('.*(BLOB|CHAR|CLOB|TEXT){1}.*')
-_BLANKS = re.compile ('\s+')
-_NOTNULL = re.compile ('(.*)(NOT NULL)(.*)', re.I)
-_CONSTRAINTS = re.compile ('.*?((UNIQUE|CHECK|PRIMARY KEY)\s*\(.*?\)).*', re.I)
-_PRIMARYKEY = re.compile ('.*?PRIMARY KEY\s*\((.*?)\).*', re.I)
-_PKFIELD = re.compile ('.*?PRIMARY\s+KEY\s*', re.I)
-_INDEX = re.compile ('CREATE\s*(\w+){0,1}\s*INDEX\s*(\w+)\s*ON\s*\w+\s*'\
- '\((.*?)\).*', re.I)
-_VIEWCODE = re.compile ('^\s*CREATE\s+VIEW\s+\w+\s+AS\s+(.*)\s*$', re.I)
-_DEFAULT = re.compile ('.*\s+DEFAULT\s+(.*)', re.I)
-_SQLCODE = re.compile ('\s*SELECT\s+(.*)\s+FROM\s+(\w+).*', re.I)
-_CMD = re.compile ('(.*?)\((.*)\)(.*)')
-
-
-# =============================================================================
-# Excpetions
-# =============================================================================
-
-class MissingTableError (errors.AdminError):
- def __init__ (self, table):
- msg = u_("Cannot find table '%s' anymore") % table
- errors.AdminError.__init__ (self, msg)
-
-class InvalidSQLCommand (errors.SystemError):
- def __init__ (self, sql):
- msg = u_("Cannot split SQL command: '%s'") % sql
- errors.SystemError.__init__ (self, msg)
-
-
-# =============================================================================
-# Behavior class
-# =============================================================================
-
-class Behavior (DBSIG2.Behavior):
- """
- Behavior class for SQLite backens.
-
- Limitations:
- - Since SQLite is typeless we cannot derive a 'length' for columns
- specified as 'integer' or 'text' without any further information.
- - SQLite does not support referential constraints
- - SQLite has no real concept of a serial
- - SQLite has no concept of a 'default with timestamp'
- - Name of Primary Keys is not available
- """
-
- # ---------------------------------------------------------------------------
- # Constructor
- # ---------------------------------------------------------------------------
-
- def __init__ (self, connection):
-
- DBSIG2.Behavior.__init__ (self, connection)
-
- self._maxIdLength = 31
- self._alterMutliple = False
- self._numbers = [[(None, 'integer')], "", "numeric (%(length)s,%(scale)s)"]
-
- self._RELTYPE = {'table': {'type': 'table', 'name': _("Tables")},
- 'view' : {'type': 'view', 'name': _("Views")}}
-
- self._type2native.update ({'boolean' : 'integer',
- 'datetime': 'timestamp'})
-
-
- # ---------------------------------------------------------------------------
- # Create a new database
- # ---------------------------------------------------------------------------
-
- def createDatabase (self):
- """
- Create a new SQLite database for the associated connection.
- """
-
- dbname = self.__connection.parameters.get ('dbname')
- self.__connection.manager.loginToConnection (self.__connection)
-
-
- # ---------------------------------------------------------------------------
- # Read the current connection's schema
- # ---------------------------------------------------------------------------
-
- def _readSchema_ (self, parent):
- """
- Read the connection's schema and build a GSchema object tree connected to
- the given parent object (which is of type GSSchema).
- """
-
- tables = self.__readTables (parent)
- self.__readIndices (tables)
-
-
- # ---------------------------------------------------------------------------
- # Read all tables
- # ---------------------------------------------------------------------------
-
- def __readTables (self, parent):
-
- cmd = u"SELECT type, name, sql FROM sqlite_master ORDER BY lower (name)"
-
- result = {}
- masters = {}
- views = {}
- cursor = self.__connection.makecursor (cmd)
-
- try:
- for (reltype, name, sql) in cursor.fetchall ():
- if not reltype in self._RELTYPE:
- continue
-
- if not reltype in masters:
- masters [reltype] = GSchema.GSTables (parent,
- **self._RELTYPE [reltype])
-
- key = name.lower ()
- result [key] = GSchema.GSTable (masters [reltype], name = name,
- sql = sql)
-
- if reltype == 'table':
- self.__parseFields (result [key], sql)
-
- pkm = _PRIMARYKEY.match (sql)
- if pkm is not None:
- pk = GSchema.GSPrimaryKey (result [key], name = 'pk_%s' % name)
-
- for field in [f.strip () for f in pkm.groups () [0].split (',')]:
- GSchema.GSPKField (pk, name = field)
-
- else:
- views [key] = sql
-
- finally:
- cursor.close ()
-
- self.__parseViews (result, views)
-
- return result
-
-
- # ---------------------------------------------------------------------------
- # Parse all fields from a given SQL code
- # ---------------------------------------------------------------------------
-
- def __parseFields (self, table, sql):
-
- result = {}
-
- # Replace all newlines by a single whitespace and take all the code in
- # between the first and last bracket
- code = ' '.join (sql.splitlines ())
- code = code [code.find ('(') + 1:code.rfind (')')]
-
- # Reduce multiple blanks to a single blank
- code = _BLANKS.sub (' ', code)
- # Make sure to have numeric arugments like '( 5 , 2)' given as '(5;2)'
- code = _REPCOMMAS.sub (r'(\1;\2)', code)
- # Realign arguments in parenthesis, i.e. from 'char( 7 )' to 'char (7)'
- code = _ALIGN.sub (r' (\1)', code)
-
- # we currently skip all constraints (primary key, unique, check)
- cma = _CONSTRAINTS.match (code)
- while cma is not None:
- constraint = cma.groups () [0]
- code = code.replace (constraint, '')
- cma = _CONSTRAINTS.match (code)
-
- for item in [i.strip () for i in code.split (',')]:
- if not len (item):
- continue
-
- parts = item.split ()
-
- if _PKFIELD.match (item) is not None:
- pk = table.findChildOfType ('GSPrimaryKey') or \
- GSchema.GSPrimaryKey (table, name = 'pk_%s' % table.name)
- GSchema.GSPKField (pk, name = parts [0])
-
- attrs = {'id' : "%s.%s" % (table.name, parts [0]),
- 'name': parts [0]}
-
- datatype = ' '.join (parts [1:])
-
- lsmatch = _LEN_SCALE.match (datatype)
- if lsmatch is not None:
- (typename, length, scale) = lsmatch.groups ()
- else:
- typename = parts [1]
- length = 0
- scale = 0
-
- nativetype = typename
- add = filter (None, [length, scale])
- nativetype += add and "(%s)" % ','.join (add) or ''
-
- attrs ['nativetype'] = nativetype
-
- if length:
- attrs ['length'] = int (length)
- if scale:
- attrs ['precision'] = int (scale)
-
- attrs ['nullable'] = _NOTNULL.match (item) is None
-
- if _TEXTTYPE.match (typename.upper ()):
- attrs ['type'] = 'string'
-
- elif typename.lower () == 'timestamp':
- attrs ['type'] = 'datetime'
-
- elif typename.lower () in ['date', 'datetime', 'time']:
- attrs ['type'] = typename.lower ()
-
- else:
- attrs ['type'] = 'number'
-
- fields = table.findChildOfType ('GSFields') or GSchema.GSFields (table)
- result [attrs ['id']] = GSchema.GSField (fields, **attrs)
-
- match = _DEFAULT.match (item)
- if match is not None:
- text = match.groups () [0].strip ()
- if text [0] in ["'", '"']:
- default = text [1:text.find (text [0], 1)]
- else:
- default = text.split () [0]
-
- result [attrs ['id']].defaultwith = 'constant'
- result [attrs ['id']].default = default
-
- return result
-
-
- # ---------------------------------------------------------------------------
- # Read all indices for the given tables
- # ---------------------------------------------------------------------------
-
- def __readIndices (self, tables):
-
- cmd = u"SELECT lower (tbl_name), name, sql FROM sqlite_master " \
- "WHERE type = 'index' AND sql IS NOT NULL"
-
- cursor = self.__connection.makecursor (cmd)
-
- try:
- for (tname, name, sql) in cursor.fetchall ():
- table = tables [tname]
-
- ixm = _INDEX.match (sql)
- if ixm is not None:
- (unique, name, fields) = ixm.groups ()
-
- top = table.findChildOfType ('GSIndexes') or GSchema.GSIndexes
(table)
- index = GSchema.GSIndex (top, name = name,
- unique = unique is not None and unique.lower () == 'unique')
-
- for field in [f.strip () for f in fields.split (',')]:
- GSchema.GSIndexField (index, name = field)
-
- finally:
- cursor.close ()
-
-
- # ---------------------------------------------------------------------------
- # Populate the view objects
- # ---------------------------------------------------------------------------
-
- def __parseViews (self, tables, views):
-
- for (viewname, sql) in views.items ():
- code = ' '.join (sql.splitlines ())
- code = _VIEWCODE.match (code)
- if not code:
- continue
-
- match = _SQLCODE.match (code.groups () [0])
- if match:
- (fieldseq, relname) = match.groups ()
- tablename = relname.lower ()
- if not viewname in tables or not tablename in tables:
- continue
-
- view = tables [viewname]
- table = tables [tablename]
- tfields = table.findChildrenOfType ('GSField', False, True)
- vfields = view.findChildOfType ('GSFields') or GSchema.GSFields (view)
-
- for item in [f.strip ().lower () for f in fieldseq.split (',')]:
- tf = None
- for f in tfields:
- if f.name.lower () == item:
- tf = f
- break
-
- if tf is None: continue
-
- vf = GSchema.GSField (vfields, name = tf.name, type = tf.type)
- for key in ['length', 'precision', 'nullable', 'default',
- 'defaultwith']:
- if hasattr (tf, key):
- setattr (vf, key, getattr (tf, key))
-
-
- # ---------------------------------------------------------------------------
- # Create constraint definition
- # ---------------------------------------------------------------------------
-
- def _createConstraint_ (self, constraint):
- """
- SQLite does not support referential constraints, so this function returns
- an empty code-triple.
- """
-
- return ([], [], [])
-
-
- # ---------------------------------------------------------------------------
- # Drop a given constraint
- # ---------------------------------------------------------------------------
-
- def _dropConstraint (self, constraint):
- """
- SQLite does not support referential constraints, so this function returns
- an empty code-triple.
- """
- return ([], [], [])
-
-
- # ---------------------------------------------------------------------------
- # Create a primary key definition
- # ---------------------------------------------------------------------------
-
- def _createPrimaryKey_ (self, pkey):
- """
- Create a code-triple for the given primary key
-
- @param pkey: GSPrimaryKey instance to create a code-sequence for
- @return: code-triple for the primary key
- """
-
- fields = pkey.findChildrenOfType ('GSPKField', False, True)
- code = u"PRIMARY KEY (%s)" % ", ".join ([f.name for f in fields])
-
- return ([], [code], [])
-
-
- # ---------------------------------------------------------------------------
- # Create a command sequence for creating/modifying tables
- # ---------------------------------------------------------------------------
-
- def _createTable_ (self, table):
- """
- """
-
- # We need to know if the diff contains new fields. If not, we can use the
- # DBSIG2 way for code-generation
- newFields = [f.name for f in table.fields ('add')]
-
- # DBSIG2 behavior can handle new or removed tables well
- if table._action != 'change' or not newFields:
- result = DBSIG2.Behavior._createTable_ (self, table)
- return result
-
- # But since SQLite does not support ALTER TABLE statements we've to handle
- # that situation here
- else:
- result = (pre, body, post) = ([], [], [])
- original = None
-
- # First find the original table
- for item in self._current.findChildrenOfType ('GSTable', False, True):
- if item._id_ (self._maxIdLength) == table._id_ (self._maxIdLength):
- original = item
- break
-
- if original is None:
- raise MissingTableError, table.name
-
- parts = _CMD.match (original.sql)
- if not parts:
- raise InvalidSQLCommand, original.sql
-
- fields = [f.name for f in original.fields ()]
- nfields = ["NULL" for f in table.fields ()]
- nfields.extend (fields)
-
- # Build the temporary table, populate it with all rows and finally
- # drop the table. This will drop all indices too.
- body.append (u"CREATE TEMPORARY TABLE t1_backup (%s)" % ",".join
(fields))
- body.append (u"INSERT INTO t1_backup SELECT %(fields)s FROM %(table)s" \
- % {'fields': ", ".join (fields),
- 'table' : self.shortenName (table.name)})
- body.append (u"DROP TABLE %s" % self.shortenName (table.name))
-
- # Build the new table using all new fields concatenated with the old
- # SQL-command.
- fcode = self._createFields_ (table)
- self.mergeTriple (result, (fcode [0], [], fcode [2]))
-
- oldSQL = parts.groups ()
- newBody = [", ".join (fcode [1])]
- if len (oldSQL [1]):
- newBody.append (oldSQL [1])
-
- cmd = u"%s (%s)%s" % (oldSQL [0], ", ".join (newBody), oldSQL [2])
-
- body.append (cmd)
- body.append (u"INSERT INTO %(table)s SELECT %(fields)s FROM t1_backup" \
- % {'table' : self.shortenName (table.name),
- 'fields': ",".join (nfields)})
- body.append (u"DROP TABLE t1_backup")
-
- # Finally create all indices as given by the new table
- for item in self._new.findChildrenOfType ('GSTable', False, True):
- if item._id_ (self._maxIdLength) == table._id_ (self._maxIdLength):
- for index in item.findChildrenOfType ('GSIndex', False, True):
- self.mergeTriple (result, self._createIndex_ (index))
-
- break
-
- return result
Copied: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/Behavior.py (from
rev 7711, trunk/gnue-common/src/datasources/drivers/sql/sqlite/Behavior.py)
Deleted: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/__init__.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/sql/sqlite/__init__.py
2005-07-07 21:20:20 UTC (rev 7707)
+++ trunk/gnue-common/src/datasources/drivers/sql/sqlite2/__init__.py
2005-07-08 09:15:44 UTC (rev 7712)
@@ -1,48 +0,0 @@
-# GNU Enterprise Common Library - SQLite database driver plugins
-#
-# Copyright 2000-2005 Free Software Foundation
-#
-# 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.
-#
-# $Id$
-
-"""
-Database driver plugins for SQLite backends.
-"""
-
-
-# =============================================================================
-# Driver info
-# =============================================================================
-
-class DriverInfo:
-
- name = "SQLite Embedded Database"
-
- url = "http://www.sqlite.org/"
-
- description = """
-SQLite is a C library that implements an embeddable SQL database engine.
-Programs that link with the SQLite library can have SQL database access
-without running a separate RDBMS process.
-
-SQLite is a great database to use with GNUe for single-user installations
-where a self-contained, distributable package is desired.
-"""
-
- isfree = True
Copied: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/__init__.py (from
rev 7711, trunk/gnue-common/src/datasources/drivers/sql/sqlite/__init__.py)
Deleted: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlite2drv.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/sql/sqlite/pysqlite2drv.py
2005-07-07 21:20:20 UTC (rev 7707)
+++ trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlite2drv.py
2005-07-08 09:15:44 UTC (rev 7712)
@@ -1,192 +0,0 @@
-# GNU Enterprise Common Library - SQLite3 database driver using pysqlite2
-#
-# Copyright 2000-2005 Free Software Foundation
-#
-# 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.
-#
-# $Id: $
-
-"""
-Database driver plugin for SQLite3 backends using the pysqlite2 DBSIG2 module.
-"""
-
-__all__ = ['Connection']
-__pluginalias__ = ['sqlite3']
-
-import datetime
-
-from gnue.common.datasources.drivers import DBSIG2
-from gnue.common.datasources.drivers.sql.sqlite import Behavior
-
-
-# =============================================================================
-# Test if plugin is functional
-# =============================================================================
-
-def __initplugin__ ():
- from gnue.common.datasources import GConnections
- try:
- from pysqlite2 import dbapi2
-
- except ImportError:
- raise GConnections.DependencyError, ('pysqlite2.dbapi2', None)
-
-
-# =============================================================================
-# Driver info
-# =============================================================================
-
-class DriverInfo:
-
- name = "pysqlite2"
-
- url = "http://initd.org"
-
- doc = """
-Description
------------
-PySQLite is a Python extension for SQLite that conforms to the Python
-Database API Specification 2.0. The source is released under the
-Python license.
-
-Support
--------
-Supported Platforms:
-
- - Linux/BSD
- - Solaris
- - MS Windows 98/NT/2000/XP
-
-Connection Properties
----------------------
-* dbname -- This is the file name of the sqlite database (required)
-* timeout -- When a database is accessed by multiple connections, and one of
- the processes modifies the database, the SQLite database is
- locked until that transaction is committed. The timeout
- parameter specifies how long the connection should wait for the
- lock to go away until raising an exception
-
-Examples
---------
-[myconn]
-provider=sqlite2 # Use the SQLite adapter
-dbname=/usr/db/testdb # The filename for the SQLite database
-
-Notes
------
-1. The database engine stores all data in string format. Many
- SQL statements won't work.
-
-2. Other than that, this driver is fully functional without any serious
- known problems.
-"""
-
-
-# =============================================================================
-# Connection class
-# =============================================================================
-
-class Connection (DBSIG2.Connection):
- """
- Connection class for SQLite backends using the pysqlite DBSIG2 module.
- """
-
- _drivername_ = 'pysqlite2.dbapi2'
- _behavior_ = Behavior.Behavior
-
- # SQLite doesn't like boolean type in SQL parameters
- _boolean_true_ = 1
- _boolean_false_ = 0
- _std_datetime_ = True
- _rowidField_ = u'oid'
-
-
- # ---------------------------------------------------------------------------
- # Return a sequence of required login fields
- # ---------------------------------------------------------------------------
-
- def _getLoginFields_ (self):
- """
- This function returns an empty sequence since SQLite doesn't use any user
- authentication.
- """
- return []
-
-
- # ---------------------------------------------------------------------------
- # Get connection parameters
- # ---------------------------------------------------------------------------
-
- def _getConnectParams_ (self, connectData):
-
- from pysqlite2 import dbapi2
-
- # Register the missing converter and adpater for time values
- dbapi2.register_adapter (datetime.time, adapt_time)
- dbapi2.register_converter ('time', convert_time)
- # NOTE: gnue-forms allways creates datetime values, even for dates. This is
- # why we have to define our own converter. Please remove as soon as
- # gnue-forms is fixed.
- dbapi2.register_converter ('date', convert_date)
-
- # mandatory parameters
- kwargs = {'database' : connectData ['dbname'],
- 'detect_types': dbapi2.PARSE_DECLTYPES}
-
- if 'timeout' in connectData:
- kwargs ['timeout'] = connectData ['timeout']
-
- return ([], kwargs)
-
-
-# =============================================================================
-# The following functions should go into pysqlite2.dbapi2 !
-# =============================================================================
-
-# -----------------------------------------------------------------------------
-
-def convert_time (value):
-
- # Be nice to datetime values passed in and take only the timepart
- parts = value.split (' ', 1)
- timepart = len (parts) > 1 and parts [1] or parts [0]
-
- timepart_full = timepart.split(".")
- hours, minutes, seconds = map(int, timepart_full[0].split(":"))
- if len(timepart_full) == 2:
- microseconds = int(float("0." + timepart_full[1]) * 1000000)
- else:
- microseconds = 0
-
- return datetime.time (hours, minutes, seconds, microseconds)
-
-# -----------------------------------------------------------------------------
-
-def convert_date (value):
-
- datepart = value.split (' ', 1) [0]
- return datetime.date (*map (int, datepart.split ('-')))
-
-# -----------------------------------------------------------------------------
-
-def adapt_time (value):
-
- if isinstance (value, datetime.datetime):
- value = value.time ()
-
- return value.isoformat ()
Copied: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlite2drv.py
(from rev 7711,
trunk/gnue-common/src/datasources/drivers/sql/sqlite/pysqlite2drv.py)
Deleted: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlitedrv.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/sql/sqlite/pysqlitedrv.py
2005-07-07 21:20:20 UTC (rev 7707)
+++ trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlitedrv.py
2005-07-08 09:15:44 UTC (rev 7712)
@@ -1,171 +0,0 @@
-# GNU Enterprise Common Library - SQLite database driver using pysqlite
-#
-# Copyright 2000-2005 Free Software Foundation
-#
-# 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.
-#
-# $Id$
-
-"""
-Database driver plugin for SQLite backends using the pysqlite DBSIG2 module.
-"""
-
-__all__ = ['Connection']
-__pluginalias__ = ['sqlite2']
-
-from gnue.common.datasources.drivers import DBSIG2
-from gnue.common.datasources.drivers.sql.sqlite import Behavior
-
-
-# =============================================================================
-# Test if plugin is functional
-# =============================================================================
-
-def __initplugin__ ():
- from gnue.common.datasources import GConnections
- try:
- import sqlite
-
- # This is a workaround for a bug in PySQLite. All the following mebers are
- # not imported from main.py in __init__.py
- if not hasattr (sqlite, 'Timestamp') and sqlite.main.have_datetime:
- sqlite.Date = sqlite.main.Date
- sqlite.Time = sqlite.main.Time
- sqlite.Timestamp = sqlite.main.Timestamp
- sqlite.DateFromTicks = sqlite.main.DateFromTicks
- sqlite.TimeFromTicks = sqlite.main.TimeFromTicks
- sqlite.TimestampFromTicks = sqlite.main.TimestampFromTicks
-
- sqlite.DateTimeType = sqlite.main.DateTimeType
- sqlite.DateTimeDeltaType = sqlite.main.DateTimeDeltaType
-
- except ImportError:
- raise GConnections.DependencyError, ('SQLitedbapi', None)
-
-
-# =============================================================================
-# Driver info
-# =============================================================================
-
-class DriverInfo:
-
- name = "pysqlite"
-
- url = "http://pysqlite.sourceforge.net/"
-
- doc = """
-Description
------------
-PySQLite is a Python extension for SQLite that conforms to the Python
-Database API Specification 2.0. The source is released under the
-Python license.
-
-Support
--------
-Supported Platforms:
-
- - Linux/BSD
- - Solaris
- - MS Windows 98/NT/2000/XP
-
-Connection Properties
----------------------
-* dbname -- This is the file name of the sqlite database (required)
-
-Examples
---------
-[myconn]
-provider=sqlite # Use the SQLite adapter
-dbname=/usr/db/testdb # The filename for the SQLite database
-
-Notes
------
-1. The database engine stores all data in string format. Many
- SQL statements won't work. Comparison of date types won't work
- correctly, etc.
-
-2. Other than that, this driver is fully functional without any serious
- known problems.
-"""
-
-
-# =============================================================================
-# Connection class
-# =============================================================================
-
-class Connection (DBSIG2.Connection):
- """
- Connection class for SQLite backends using the pysqlite DBSIG2 module.
- """
-
- _drivername_ = 'sqlite'
- _behavior_ = Behavior.Behavior
-
- # SQLite doesn't like boolean type in SQL parameters
- _boolean_true_ = 1
- _boolean_false_ = 0
- _rowidField_ = u'oid'
-
-
- # ---------------------------------------------------------------------------
- # Constructor
- # ---------------------------------------------------------------------------
-
- def __init__ (self, connections, name, parameters):
-
- DBSIG2.Connection.__init__ (self, connections, name, parameters)
- # FIXME: what was the problem with transactions? Comment should go here.
- self.__noTransactions = parameters.get ('appserver', False)
-
-
- # ---------------------------------------------------------------------------
- # Return a sequence of required login fields
- # ---------------------------------------------------------------------------
-
- def _getLoginFields_ (self):
- """
- This function returns an empty sequence since SQLite doesn't use any user
- authentication.
- """
- return []
-
-
- # ---------------------------------------------------------------------------
- # Get connection parameters
- # ---------------------------------------------------------------------------
-
- def _getConnectParams_ (self, connectData):
-
- # mandatory parameters
- kwargs = {'db' : connectData ['dbname'],
- 'encoding' : self._encoding,
- 'autocommit': self.__noTransactions}
-
- return ([], kwargs)
-
-
- # ---------------------------------------------------------------------------
- # Commit a pending transactiona pending transaction
- # ---------------------------------------------------------------------------
-
- def _commit_ (self):
- """
- This function performs a commit depending on the current transaction-flag.
- """
- if not self.__noTransactions:
- DBSIG2.Connection._commit_ (self)
Copied: trunk/gnue-common/src/datasources/drivers/sql/sqlite2/pysqlitedrv.py
(from rev 7711,
trunk/gnue-common/src/datasources/drivers/sql/sqlite/pysqlitedrv.py)
Property changes on: trunk/gnue-common/src/datasources/drivers/sql/sqlite3
___________________________________________________________________
Name: svn:ignore
+ *.pyc
Added: trunk/gnue-common/src/datasources/drivers/sql/sqlite3/Behavior.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/sql/sqlite3/Behavior.py
2005-07-08 09:09:19 UTC (rev 7711)
+++ trunk/gnue-common/src/datasources/drivers/sql/sqlite3/Behavior.py
2005-07-08 09:15:44 UTC (rev 7712)
@@ -0,0 +1,150 @@
+# GNU Enterprise Common Library - Schema support for SQLite3
+#
+# Copyright 2000-2005 Free Software Foundation
+#
+# 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.
+#
+# $Id: $
+
+"""
+Schema support plugin for SQLite3.
+"""
+
+from gnue.common.datasources.drivers.sql import sqlite2
+
+
+# =============================================================================
+# Behavior class
+# =============================================================================
+
+class Behavior (sqlite2.Behavior):
+ """
+ Behavior class for SQLite3 backends.
+
+ Limitations:
+ - Since SQLite3 is typeless we cannot derive a 'length' for columns
+ specified as 'integer' or 'text' without any further information.
+ - SQLite3 does not support referential constraints
+ - SQLite3 has no real concept of a serial
+ - SQLite3 has no concept of a 'default with timestamp'
+ - Name of Primary Keys is not available
+ """
+
+ # ---------------------------------------------------------------------------
+ # Constructor
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, connection):
+
+ sqlite2.Behavior.__init__ (self, connection)
+
+ self._type2native.update ({'boolean' : 'boolean',
+ 'datetime': 'timestamp'})
+
+
+ # ---------------------------------------------------------------------------
+ # Parse all fields from a given SQL code
+ # ---------------------------------------------------------------------------
+
+ def __parseFields (self, table, sql):
+
+ result = {}
+
+ # Replace all newlines by a single whitespace and take all the code in
+ # between the first and last bracket
+ code = ' '.join (sql.splitlines ())
+ code = code [code.find ('(') + 1:code.rfind (')')]
+
+ # Reduce multiple blanks to a single blank
+ code = _BLANKS.sub (' ', code)
+ # Make sure to have numeric arugments like '( 5 , 2)' given as '(5;2)'
+ code = _REPCOMMAS.sub (r'(\1;\2)', code)
+ # Realign arguments in parenthesis, i.e. from 'char( 7 )' to 'char (7)'
+ code = _ALIGN.sub (r' (\1)', code)
+
+ # we currently skip all constraints (primary key, unique, check)
+ cma = _CONSTRAINTS.match (code)
+ while cma is not None:
+ constraint = cma.groups () [0]
+ code = code.replace (constraint, '')
+ cma = _CONSTRAINTS.match (code)
+
+ for item in [i.strip () for i in code.split (',')]:
+ if not len (item):
+ continue
+
+ parts = item.split ()
+
+ if _PKFIELD.match (item) is not None:
+ pk = table.findChildOfType ('GSPrimaryKey') or \
+ GSchema.GSPrimaryKey (table, name = 'pk_%s' % table.name)
+ GSchema.GSPKField (pk, name = parts [0])
+
+ attrs = {'id' : "%s.%s" % (table.name, parts [0]),
+ 'name': parts [0]}
+
+ datatype = ' '.join (parts [1:])
+
+ lsmatch = _LEN_SCALE.match (datatype)
+ if lsmatch is not None:
+ (typename, length, scale) = lsmatch.groups ()
+ else:
+ typename = parts [1]
+ length = 0
+ scale = 0
+
+ nativetype = typename
+ add = filter (None, [length, scale])
+ nativetype += add and "(%s)" % ','.join (add) or ''
+
+ attrs ['nativetype'] = nativetype
+
+ if length:
+ attrs ['length'] = int (length)
+ if scale:
+ attrs ['precision'] = int (scale)
+
+ attrs ['nullable'] = _NOTNULL.match (item) is None
+
+ if _TEXTTYPE.match (typename.upper ()):
+ attrs ['type'] = 'string'
+
+ elif typename.lower () == 'timestamp':
+ attrs ['type'] = 'datetime'
+
+ elif typename.lower () in ['date', 'datetime', 'time', 'boolean']:
+ attrs ['type'] = typename.lower ()
+
+ else:
+ attrs ['type'] = 'number'
+
+ fields = table.findChildOfType ('GSFields') or GSchema.GSFields (table)
+ result [attrs ['id']] = GSchema.GSField (fields, **attrs)
+
+ match = _DEFAULT.match (item)
+ if match is not None:
+ text = match.groups () [0].strip ()
+ if text [0] in ["'", '"']:
+ default = text [1:text.find (text [0], 1)]
+ else:
+ default = text.split () [0]
+
+ result [attrs ['id']].defaultwith = 'constant'
+ result [attrs ['id']].default = default
+
+ return result
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r7712 - in trunk/gnue-common/src/datasources/drivers/sql: . maxdb sqlite2 sqlite3,
johannes <=