PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/IBM_DB/ibm_db_django/ibm_db_django/introspection.py

http://ibm-db.googlecode.com/
Python | 196 lines | 139 code | 15 blank | 42 comment | 32 complexity | d60a7467fdff375ea4ac81cc5b647c08 MD5 | raw file
Possible License(s): Apache-2.0
  1. # +--------------------------------------------------------------------------+
  2. # | Licensed Materials - Property of IBM |
  3. # | |
  4. # | (C) Copyright IBM Corporation 2009. |
  5. # +--------------------------------------------------------------------------+
  6. # | This module complies with Django 1.0 and is |
  7. # | Licensed under the Apache License, Version 2.0 (the "License"); |
  8. # | you may not use this file except in compliance with the License. |
  9. # | You may obtain a copy of the License at |
  10. # | http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable |
  11. # | law or agreed to in writing, software distributed under the License is |
  12. # | distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
  13. # | KIND, either express or implied. See the License for the specific |
  14. # | language governing permissions and limitations under the License. |
  15. # +--------------------------------------------------------------------------+
  16. # | Authors: Ambrish Bhargava, Tarun Pasrija, Rahul Priyadarshi |
  17. # +--------------------------------------------------------------------------+
  18. import sys
  19. from string import upper
  20. _IS_JYTHON = sys.platform.startswith( 'java' )
  21. if not _IS_JYTHON:
  22. try:
  23. # Import IBM_DB wrapper ibm_db_dbi
  24. import ibm_db_dbi as Database
  25. #from Database import DatabaseError
  26. except ImportError, e:
  27. raise ImportError( "ibm_db module not found. Install ibm_db module from http://code.google.com/p/ibm-db/. Error: %s" % e )
  28. else:
  29. from com.ziclix.python.sql import zxJDBC
  30. from django.db.backends import BaseDatabaseIntrospection
  31. from django import VERSION as djangoVersion
  32. class DatabaseIntrospection( BaseDatabaseIntrospection ):
  33. """
  34. This is the class where database metadata information can be generated.
  35. """
  36. if not _IS_JYTHON:
  37. if( djangoVersion[0:2] <= ( 1, 1 ) ):
  38. data_types_reverse = {
  39. Database.STRING : "CharField",
  40. Database.TEXT : "TextField",
  41. Database.XML : "XMLField",
  42. Database.NUMBER : "IntegerField",
  43. Database.BIGINT : "IntegerField",
  44. Database.FLOAT : "FloatField",
  45. Database.DECIMAL : "DecimalField",
  46. Database.DATE : "DateField",
  47. Database.TIME : "TimeField",
  48. Database.DATETIME : "DateTimeField",
  49. Database.BINARY : "ImageField",
  50. }
  51. else:
  52. data_types_reverse = {
  53. Database.STRING : "CharField",
  54. Database.TEXT : "TextField",
  55. Database.XML : "XMLField",
  56. Database.NUMBER : "IntegerField",
  57. Database.BIGINT : "BigIntegerField",
  58. Database.FLOAT : "FloatField",
  59. Database.DECIMAL : "DecimalField",
  60. Database.DATE : "DateField",
  61. Database.TIME : "TimeField",
  62. Database.DATETIME : "DateTimeField",
  63. Database.BINARY : "ImageField",
  64. }
  65. else:
  66. data_types_reverse = {
  67. zxJDBC.CHAR: "CharField",
  68. zxJDBC.BIGINT: "BigIntegerField",
  69. zxJDBC.BINARY: "ImageField",
  70. zxJDBC.BIT: "SmallIntegerField",
  71. zxJDBC.BLOB: "ImageField",
  72. zxJDBC.CLOB: "TextField",
  73. zxJDBC.DATE: "DateField",
  74. zxJDBC.DECIMAL: "DecimalField",
  75. zxJDBC.DOUBLE: "FloatField",
  76. zxJDBC.FLOAT: "FloatField",
  77. zxJDBC.INTEGER: "IntegerField",
  78. zxJDBC.LONGVARCHAR: "TextField",
  79. zxJDBC.LONGVARBINARY: "ImageField",
  80. zxJDBC.NUMERIC: "DecimalField",
  81. zxJDBC.REAL: "FloatField",
  82. zxJDBC.SMALLINT: "SmallIntegerField",
  83. zxJDBC.VARCHAR: "CharField",
  84. zxJDBC.TIMESTAMP: "DateTimeField",
  85. zxJDBC.TIME: "TimeField",
  86. }
  87. # Converting table name to lower case.
  88. def table_name_converter ( self, name ):
  89. return name.lower()
  90. # Getting the list of all tables, which are present under current schema.
  91. def get_table_list ( self, cursor ):
  92. table_list = []
  93. if not _IS_JYTHON:
  94. for table in cursor.connection.tables( cursor.connection.get_current_schema() ):
  95. table_list.append( table['TABLE_NAME'].lower() )
  96. else:
  97. cursor.execute( "select current_schema from sysibm.sysdummy1" )
  98. schema = cursor.fetchone()[0]
  99. # tables(String catalog, String schemaPattern, String tableNamePattern, String[] types) gives a description of tables available in a catalog
  100. cursor.tables( None, schema, None, ( "TABLE", ) )
  101. for table in cursor.fetchall():
  102. # table[2] is table name
  103. table_list.append( table[2].lower() )
  104. return table_list
  105. # Generating a dictionary for foreign key details, which are present under current schema.
  106. def get_relations( self, cursor, table_name ):
  107. relations = {}
  108. if not _IS_JYTHON:
  109. schema = cursor.connection.get_current_schema()
  110. for fk in cursor.connection.foreign_keys( True, schema, table_name ):
  111. relations[self.__get_col_index( cursor, schema, table_name, fk['FKCOLUMN_NAME'] )] = ( self.__get_col_index( cursor, schema, fk['PKTABLE_NAME'], fk['PKCOLUMN_NAME'] ), fk['PKTABLE_NAME'].lower() )
  112. else:
  113. cursor.execute( "select current_schema from sysibm.sysdummy1" )
  114. schema = cursor.fetchone()[0]
  115. # foreign_keys(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable)
  116. # gives a description of the foreign key columns in the foreign key table that reference the primary key columns
  117. # of the primary key table (describe how one table imports another's key.) This should normally return a single foreign key/primary key pair
  118. # (most tables only import a foreign key from a table once.) They are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and KEY_SEQ
  119. cursor.foreignkeys( None, schema, table_name, None, '%', '%' )
  120. for fk in cursor.fetchall():
  121. # fk[2] is primary key table name, fk[3] is primary key column name, fk[7] is foreign key column name being exported
  122. relations[self.__get_col_index( cursor, schema, table_name, fk[7] )] = ( self.__get_col_index( cursor, schema, fk[2], fk[3] ), fk[3], fk[2] )
  123. return relations
  124. # Private method. Getting Index position of column by its name
  125. def __get_col_index ( self, cursor, schema, table_name, col_name ):
  126. if not _IS_JYTHON:
  127. for col in cursor.connection.columns( schema, table_name, [col_name] ):
  128. return col['ORDINAL_POSITION'] - 1
  129. else:
  130. cursor.execute( "select current_schema from sysibm.sysdummy1" )
  131. schema = cursor.fetchone()[0]
  132. # columns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) gives a description of table columns available in the specified catalog
  133. cursor.columns( None, schema, table_name, col_name )
  134. for col in cursor.fetchall():
  135. #col[16] is index of column in table
  136. return col[16] - 1
  137. # Getting list of indexes associated with the table provided.
  138. def get_indexes( self, cursor, table_name ):
  139. indexes = {}
  140. if not _IS_JYTHON:
  141. schema = cursor.connection.get_current_schema()
  142. for index in cursor.connection.indexes( True, schema, table_name ):
  143. temp = {}
  144. if ( index['NON_UNIQUE'] ):
  145. temp['unique'] = False
  146. else:
  147. temp['unique'] = True
  148. temp['primary_key'] = False
  149. indexes[index['COLUMN_NAME'].lower()] = temp
  150. for index in cursor.connection.primary_keys( True, schema, table_name ):
  151. indexes[index['COLUMN_NAME'].lower()]['primary_key'] = True
  152. else:
  153. cursor.execute( "select current_schema from sysibm.sysdummy1" )
  154. schema = cursor.fetchone()[0]
  155. # statistics(String catalog, String schema, String table, boolean unique, boolean approximate) returns a description of a table's indices and statistics.
  156. cursor.statistics( None, schema, table_name, 0, 0 )
  157. for index in cursor.fetchall():
  158. temp = {}
  159. # index[3] indicate non-uniqueness of column
  160. if ( index[3] != None ):
  161. if ( index[3] ) == 1:
  162. temp['unique'] = False
  163. else:
  164. temp['unique'] = True
  165. temp['primary_key'] = False
  166. # index[8] is column name
  167. indexes[index[8].lower()] = temp
  168. # primarykeys(String catalog, String schema, String table) gives a description of a table's primary key columns
  169. cursor.primarykeys( None, schema, table_name )
  170. for index in cursor.fetchall():
  171. #index[3] is column name
  172. indexes[index[3].lower()]['primary_key'] = True
  173. return indexes
  174. # Getting the description of the table.
  175. def get_table_description( self, cursor, table_name ):
  176. qn = self.connection.ops.quote_name
  177. cursor.execute( "SELECT * FROM %s FETCH FIRST 1 ROWS ONLY" % qn( table_name ) )
  178. description = []
  179. for desc in cursor.description:
  180. description.append( [ desc[0].lower(), ] + desc[1:] )
  181. return description