commit-gnue
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]