/[gnue]/gnue-common/src/datasources/drivers/postgresql/Schema/Discovery/Introspection.py
ViewVC logotype

Diff of /gnue-common/src/datasources/drivers/postgresql/Schema/Discovery/Introspection.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by jcater, Fri Oct 10 01:21:27 2003 UTC revision 1.2 by jcater, Tue Nov 25 17:01:43 2003 UTC
# Line 0  Line 1 
1    #
2    # This file is part of GNU Enterprise.
3    #
4    # GNU Enterprise is free software; you can redistribute it
5    # and/or modify it under the terms of the GNU General Public
6    # License as published by the Free Software Foundation; either
7    # version 2, or(at your option) any later version.
8    #
9    # GNU Enterprise is distributed in the hope that it will be
10    # useful, but WITHOUT ANY WARRANTY; without even the implied
11    # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12    # PURPOSE. See the GNU General Public License for more details.
13    #
14    # You should have received a copy of the GNU General Public
15    # License along with program; see the file COPYING. If not,
16    # write to the Free Software Foundation, Inc., 59 Temple Place
17    # - Suite 330, Boston, MA 02111-1307, USA.
18    #
19    # Copyright 2000-2003 Free Software Foundation
20    #
21    # FILE:
22    # Introspection.py
23    #
24    # DESCRIPTION:
25    #
26    # NOTES:
27    #
28    
29    __all__ = ['Introspection']
30    
31    import string
32    from string import lower, join, split
33    import sys
34    
35    
36    from gnue.common.apps import GDebug, GConfig
37    from gnue.common.datasources import GIntrospection
38    
39    
40    class Introspection(GIntrospection.Introspection):
41    
42      # list of the types of Schema objects this driver provides
43      types =[ ('view',_('Views'),1),
44               ('table',_('Tables'),1) ]
45    
46      #
47      # TODO: This is a quick hack to get this class
48      # TODO: into the new-style schema format.
49      # TODO: getSchema* should be merged into find()
50      #
51      def find(self, name=None, type=None):
52        if name is None:
53          return self.getSchemaList(type)
54        else:
55          rs = self.getSchemaByName(name, type)
56          if rs:
57            return [rs]
58          else:
59            return None
60    
61    
62      # TODO: Merge into find()
63      # Return a list of Schema objects
64      def getSchemaList(self, type=None):
65        includeTables = (type in ('table','sources', None))
66        includeViews = (type in ('view','sources', None))
67    
68        inClause = []
69        if includeTables:
70          inClause.append ("'r'")
71        if includeViews:
72          inClause.append ("'v'")
73    
74        # TODO: This excludes any system tables and views. Should it?
75        statement = "select relname, relkind, oid from pg_class " + \
76                "where relkind in (%s) " % (join(inClause,',')) + \
77                "and relname not like 'pg_%' " + \
78                "order by relname"
79    
80        cursor = self._connection.native.cursor()
81        cursor.execute(statement)
82    
83        list = []
84        for rs in cursor.fetchall():
85          list.append(GIntrospection.Schema(attrs={'id':rs[2], 'name':rs[0],
86                             'type':rs[1] == 'v' and 'view' or 'table',
87                             'primarykey': self.__getPrimaryKey(cursor, rs[2])},
88                             getChildSchema=self.__getFieldSchema))
89    
90        cursor.close()
91        return list
92    
93    
94      # TODO: Merge into find()
95      # Find a schema object with specified name
96      def getSchemaByName(self, name, type=None):
97        statement = "select relname, relkind, oid from pg_class " + \
98                "where relname = '%s'" % (name)
99    
100        cursor = self._connection.native.cursor()
101        cursor.execute(statement)
102    
103        rs = cursor.fetchone()
104        if rs:
105          schema = GIntrospection.Schema(attrs={'id':rs[2], 'name':rs[0],
106                               'type':rs[1] == 'v' and 'view' or 'table',
107                               'primarykey': self.__getPrimaryKey(cursor, rs[2]) },
108                               getChildSchema=self.__getFieldSchema)
109        else:
110          schema = None
111    
112        cursor.close()
113        return schema
114    
115      def __getPrimaryKey(self, cursor, oid):
116        cursor = self._connection.native.cursor()
117        cursor.execute("select indkey from pg_index where indrelid=%s" % oid)
118        rs = cursor.fetchone()
119        statement = "select attname from pg_attribute " \
120                    "where attrelid = %s and attnum = %%s" % oid
121        if rs:
122          pks = []
123          for indpos in string.split(rs[0]):
124            cursor.execute(statement % int(indpos))
125            pks.append(cursor.fetchone()[0])
126          cursor.close()
127          return tuple(pks)
128        else:
129          cursor.close()
130          return None
131    
132      # Get fields for a table
133      def __getFieldSchema(self, parent):
134    
135        statement = "select attname, pg_type.oid, typname, " + \
136                " attnotnull, atthasdef, atttypmod, attnum, attlen " + \
137                "from pg_attribute, pg_type " + \
138                "where attrelid = %s and " % (parent.id) + \
139                "pg_type.oid = atttypid and attnum >= 0" + \
140                "order by attnum"
141    
142        cursor = self._connection.native.cursor()
143        cursor.execute(statement)
144    
145        list = []
146        for rs in cursor.fetchall():
147    
148          attrs={'id': rs[1], 'name': rs[0],
149                 'type':'field', 'nativetype': rs[2],
150                 'required': rs[3] and not rs[4]}
151    
152          if rs[2] in ('numeric','float4','float8','money','bool','int8','int2','int4'):
153            attrs['datatype']='number'
154          elif rs[2] in ('date','time','timestamp','abstime','reltime'):
155            attrs['datatype']='date'
156          else:
157            attrs['datatype']='text'
158    
159          if rs[7] > 0:
160            attrs['length'] = rs[7]
161          elif rs[5] != -1: #text field
162            attrs['length'] = rs[5] - 4
163    
164    
165          # Find any default values
166          if rs[4]:
167            cursor.execute("select adsrc " + \
168                           "from pg_attrdef " + \
169                           "where adrelid = %s and adnum = %s" % (parent.id, rs[6]))
170            defrs = cursor.fetchone()
171            if defrs:
172              dflt = defrs[0]
173              if dflt[:8] == 'nextval(':
174                attrs['defaulttype'] = 'sequence'
175                attrs['defaultval'] = split(dflt,"'")[1]
176              elif dflt == 'now()':
177                attrs['defaulttype'] = 'system'
178                attrs['defaultval'] = 'timestamp'
179              else:
180                attrs['defaulttype'] = 'constant'
181                attrs['defaultval'] = dflt
182    
183          list.append(GIntrospection.Schema(attrs=attrs))
184    
185        cursor.close()
186        return list
187    
188    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26