[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5944 - in trunk/gnue-common/src/datasources/drivers: interbase/Schema/D
From: |
johannes |
Subject: |
r5944 - in trunk/gnue-common/src/datasources/drivers: interbase/Schema/Discovery interbase/interbase postgresql/Schema/Discovery |
Date: |
Wed, 7 Jul 2004 17:14:22 -0500 (CDT) |
Author: johannes
Date: 2004-07-06 08:19:38 -0500 (Tue, 06 Jul 2004)
New Revision: 5944
Modified:
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Discovery/Introspection.py
trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py
trunk/gnue-common/src/datasources/drivers/postgresql/Schema/Discovery/Introspection.py
Log:
Rebuilt introspection for interbase
Modified:
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Discovery/Introspection.py
===================================================================
---
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Discovery/Introspection.py
2004-07-06 08:45:14 UTC (rev 5943)
+++
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Discovery/Introspection.py
2004-07-06 13:19:38 UTC (rev 5944)
@@ -18,173 +18,170 @@
#
# Copyright 2000-2004 Free Software Foundation
#
-# FILE:
-# Introspection.py
-#
-# DESCRIPTION:
-#
-# NOTES:
-#
+# $Id$
__all__ = ['Introspection']
import string
-from string import lower, join, rstrip, upper
-import sys
+import re
-from gnue.common.apps import GDebug, GConfig
from gnue.common.datasources import GIntrospection
-DESCRIPTION_NAME = 0
-DESCRIPTION_TYPE_CODE = 1
-DESCRIPTION_DISPLAY_SIZE = 2
-DESCRIPTION_INTERNAL_SIZE = 3
-DESCRIPTION_PRECISION = 4
-DESCRIPTION_SCALE = 5
-DESCRIPTION_NULL_OK = 6
+# =============================================================================
+# This class implements schema introspection for Interbase / Firebird
+# =============================================================================
class Introspection(GIntrospection.Introspection):
- _primaryKeyFields = []
# list of the types of Schema objects this driver provides
- types =[ ('table',_('Tables'),1),
- ('view',_('Views'),1)]
+ types = [('table', _('Tables'), 1),
+ ('view' , _('Views') , 1)]
- #
- # TODO: This is a quick hack to get this class
- # TODO: into the new-style schema format.
- # TODO: getSchema* should be merged into find()
- #
- def find(self, name=None, type=None):
- if name is None:
- return self.getSchemaList(type)
- else:
- rs = self.getSchemaByName(name, type)
- if rs:
- return [rs]
- else:
- return None
+ _NOW = re.compile ("'(NOW\s*\(\)\s*)'", re.IGNORECASE)
- # TODO: Merge into find()
- # Return a list of Schema objects
+ # ---------------------------------------------------------------------------
+ # Find a schema element by name and/or type
+ # ---------------------------------------------------------------------------
- #
- # Schema (metadata) functions
- #
+ def find (self, name = None, type = None):
+ """
+ This function searches the schema for an element by name and/or type. If no
+ name and no type is given, all elements will be retrieved.
- # Return a list of Schema objects
- def getSchemaList(self, type=None):
+ @param name: look for an element with this name
+ @param type: look for an element with this type
+ @return: A sequence of schema instances, one per element found, or None if
+ no element could be found.
+ """
- # This excludes any system tables and views.
- statement = "select rdb$relation_name, rdb$view_source "+\
- "from rdb$relations " + \
- "where rdb$system_flag=0 " + \
- "order by rdb$relation_name"
+ result = []
+ cond = ["rdb$system_flag = 0"]
- cursor = self._connection.native.cursor()
- cursor.execute(statement)
+ if name is not None:
+ cond.append (u"rdb$relation_name = '%s'" \
+ % self._connection.identifier (name))
- # TODO: rdb$view_source is null for table and rdb$view_source is not null
for view
- list = []
- for rs in cursor.fetchall():
- list.append(GIntrospection.Schema(attrs={'id':rs[0],
'name':rstrip(rs[0]),
- 'type':'table',
- 'primarykey': self.__getPrimaryKey(rstrip(rs[0]))},
- getChildSchema=self.__getFieldSchema))
+ if type == 'table':
+ cond.append (u"rdb$view_source IS NULL")
+ elif type == 'view':
+ cond.append (u"rdb$view_source IS NOT NULL")
- cursor.close()
- return list
+ cmd = u"SELECT rdb$relation_name, rdb$view_source FROM RDB$RELATIONS " \
+ "WHERE %s ORDER BY rdb$relation_name" % string.join (cond, " AND ")
- # Find a schema object with specified name
- def getSchemaByName(self, name, type=None):
+ cursor = self._connection.makecursor (cmd)
- statement = "select rdb$relation_name, rdb$view_source "+\
- "from rdb$relations " + \
- "where rdb$relation_name = '%s'" % (name.upper ())
+ try:
+ for rs in cursor.fetchall ():
+ relname = self._connection.identifier (string.strip (rs [0]))
- cursor = self._connection.native.cursor()
- cursor.execute(statement)
+ attrs = {'id' : relname,
+ 'name' : relname,
+ 'type' : rs [1] is None and 'table' or 'view',
+ 'primarykey': self.__getPrimaryKey (relname)}
- rs = cursor.fetchone()
- if rs:
- schema = GIntrospection.Schema(attrs={'id':rs[0], 'name':rstrip(rs[0]),
- 'type':'table',
- 'primarykey': self.__getPrimaryKey(rstrip(rs[0]))},
- getChildSchema=self.__getFieldSchema)
- else:
- schema = None
+ result.append ( \
+ GIntrospection.Schema (attrs, getChildSchema = self._getChildSchema))
- cursor.close()
- return schema
+ finally:
+ cursor.close ()
- # Return a list of fields (for _buildDeleteStatement and for
_buildUpdateStatement)
- def __getPrimaryKey(self, relname):
- statement = "select rdb$relation_name, rdb$field_name, "+\
- "rdb$constraint_name, rdb$field_position "+\
- "from rdb$relation_constraints rc,
rdb$index_segments ri "+\
- "where ri.rdb$index_name =
rc.rdb$index_name "+\
- "and rc.rdb$constraint_type =
'PRIMARY KEY' "+\
- "and rc.rdb$relation_name = '%s' "
% (relname)+\
- "order by ri.rdb$field_position"
+ return len (result) and result or None
- cursor = self._connection.native.cursor()
- cursor.execute(statement)
- list = []
- for rs in cursor.fetchall():
- list.append(lower(rstrip(rs[1])))
+ # ---------------------------------------------------------------------------
+ # Get all fields of a relation / view
+ # ---------------------------------------------------------------------------
- cursor.close()
- return list
+ def _getChildSchema (self, parent):
+ """
+ This function returns a list of all child elements of a given parent
+ relation.
- # Get fields for a table
- def __getFieldSchema(self, parent):
+ @param parent: schema object instance whose child elements should be
+ fetched.
+ @return: sequence of schema instances, one per element found
+ """
- statement = "select * from %s"%(parent.name) + " where (0=1)"
+ result = []
- cursor = self._connection.native.cursor()
- cursor.execute(statement)
+ cmd = u"SELECT rf.rdb$field_name, tp.rdb$type_name, rf.rdb$null_flag, " \
+ "rf.rdb$default_source, fs.rdb$field_length, " \
+ "fs.rdb$field_scale, fs.rdb$field_precision " \
+ "FROM rdb$relation_fields rf, rdb$fields fs, rdb$types tp " \
+ "WHERE rf.rdb$relation_name = '%s' AND " \
+ "fs.rdb$field_name = rf.rdb$field_source AND " \
+ "tp.rdb$type = fs.rdb$field_type AND " \
+ "tp.rdb$field_name = 'RDB$FIELD_TYPE'" \
+ "ORDER BY rf.rdb$field_name" % parent.name
- list = []
+ cursor = self._connection.makecursor (cmd)
- for d in cursor.description:
- try:
- nativetype = lower(d[DESCRIPTION_TYPE_CODE].__name__)
- except AttributeError:
- nativetype='unknown'
-
- attrs={'id':d[DESCRIPTION_NAME],
- 'name':lower (d[DESCRIPTION_NAME]),
- 'type':'field',
+ try:
+ for rs in cursor.fetchall ():
+ nativetype = rs [1].strip ()
+ attrs = {'id' : "%s.%s" % (parent.name, rs [0].strip ()),
+ 'name' : self._connection.identifier (rs [0].strip ()),
+ 'type' : 'field',
'nativetype': nativetype,
- 'required': d[DESCRIPTION_NULL_OK]==0,
- 'length': d[DESCRIPTION_DISPLAY_SIZE]}
+ 'required' : rs [2] is not None}
- if nativetype in ('int','float','long'):
- attrs['datatype']='number'
- attrs['precision']=d[DESCRIPTION_SCALE]
- elif nativetype == 'tuple':
- attrs['datatype']='date'
- else:
- attrs['datatype']='text'
+ if nativetype in ['DATE', 'TIME', 'TIMESTAMP']:
+ attrs ['datatype'] = 'date'
- cursor.execute("select rdb$default_source from rdb$relation_fields"+ \
- " where rdb$relation_name = '%s' " % (parent.name.upper ())+
\
- " and rdb$field_name = '%s'" % (upper(attrs['name'])))
- defrs = cursor.fetchone()
- try:
- if defrs[0]:
- dflt = defrs[0]
- if dflt[9:12] == "NOW":
- attrs['defaulttype'] = 'timestamp'
+ elif nativetype in ['DOUBLE', 'FLOAT', 'INT64', 'LONG', 'QUAD', \
+ 'SHORT']:
+ attrs ['datatype'] = 'number'
+ attrs ['length'] = rs [6]
+ attrs ['precision'] = abs (rs [5])
+
+ else:
+ attrs ['datatype'] = 'text'
+ attrs ['length'] = rs [4]
+
+ if rs [3] is not None:
+ default = rs [3]
+ if self._NOW.search (default) is not None:
+ attrs ['defaulttype'] = 'timestamp'
else:
- attrs['defaulttype'] = 'constant'
- attrs['defaultval'] = dflt[8:]
- except:
- pass
+ attrs ['defaulttype'] = 'constant'
+ attrs ['defaultval'] = default [8:]
- list.append(GIntrospection.Schema(attrs=attrs))
+ result.append (GIntrospection.Schema (attrs))
- cursor.close()
- return list
+ finally:
+ cursor.close ()
+
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Get all parts of a primary key
+ # ---------------------------------------------------------------------------
+
+ def __getPrimaryKey (self, relname):
+ """
+ This function fetches all fields of a primary key for the given relation.
+
+ @param relid: object id of the relation in question
+ @return: sequence with the fieldnames of the primary key or None, if the
+ relation has no primary key.
+ """
+
+ cmd = u"SELECT rdb$field_name " \
+ "FROM rdb$relation_constraints rc, rdb$index_segments ri " \
+ "WHERE ri.rdb$index_name = rc.rdb$index_name " \
+ "AND rc.rdb$constraint_type = 'PRIMARY KEY' " \
+ "AND rc.rdb$relation_name = '%s'" \
+ "ORDER BY ri.rdb$field_position" % relname
+
+ cursor = self._connection.makecursor (cmd)
+
+ try:
+ result = [rs [0].strip () for rs in cursor.fetchall ()]
+
+ finally:
+ cursor.close ()
+
+ return len (result) and result or None
Property changes on:
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Discovery/Introspection.py
___________________________________________________________________
Name: svn:keywords
+ Id
Modified:
trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py
2004-07-06 08:45:14 UTC (rev 5943)
+++ trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py
2004-07-06 13:19:38 UTC (rev 5944)
@@ -169,8 +169,12 @@
return None
+ # ---------------------------------------------------------------------------
+ # convert an identifier to be safely used
+ # ---------------------------------------------------------------------------
+
def identifier (self, identifier):
- return identifier.lower ()
+ return identifier.upper ()
Property changes on:
trunk/gnue-common/src/datasources/drivers/postgresql/Schema/Discovery/Introspection.py
___________________________________________________________________
Name: svn:keywords
- +Id
+ Id
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5944 - in trunk/gnue-common/src/datasources/drivers: interbase/Schema/Discovery interbase/interbase postgresql/Schema/Discovery,
johannes <=