misc changes
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / model / Database.java
1 package com.quantum.model;
2
3 import java.sql.Connection;
4 import java.sql.DatabaseMetaData;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.HashSet;
10 import java.util.List;
11 import java.util.Set;
12
13 import com.quantum.IQuantumConstants;
14 import com.quantum.adapters.DatabaseAdapter;
15 import com.quantum.sql.MultiSQLServer;
16 import com.quantum.sql.SQLResults;
17
18 /**
19  * @author BC
20  */
21 public class Database {
22     
23     private DatabaseAdapter databaseAdapter;
24     private Bookmark bookmark;
25     
26     public Database(Bookmark bookmark) {
27         this.bookmark = bookmark;
28         this.databaseAdapter = bookmark.getAdapter();
29     }
30
31     private static final String[] ALL_TYPES = { 
32         IQuantumConstants.Table, 
33         IQuantumConstants.View, 
34         IQuantumConstants.Sequence };
35         
36     private static final List STANDARD_TABLE_TYPES = 
37         Collections.synchronizedList(new ArrayList());
38         
39     static {
40         for (int i = 0, length = (ALL_TYPES == null) ? 0 : ALL_TYPES.length;
41             i < length;
42             i++) {
43             STANDARD_TABLE_TYPES.add(ALL_TYPES[i]);
44         }
45     }
46     
47     public String[] getEntityTypes() 
48         throws NotConnectedException, SQLException {
49         return getEntityTypes(this.bookmark.getConnection(), this.bookmark.getSchemas()[0]);
50     }
51
52
53     /**
54      * <p>This method returns a list of entity types supported by the database
55      * adapter.  This list will always be limited to Tables, Views and 
56      * Sequences.</p>
57      * 
58      * <p>Not all databases support all types.  MySQL only supports 
59      * Tables.  Informix supports Tables and Views.  Oracle and DB2 support
60      * Tables, Views and Sequences.</p>
61      * 
62      * @param connection
63      * @param schema -
64      *      This parameter is somewhat bogus.  It is used to determine if the
65      *      adapter defines an SQL statement for finding entities of a 
66      *      particular types.  
67      * @return
68      * @throws SQLException
69      */
70     public String[] getEntityTypes(Connection connection, Schema schema) 
71         throws SQLException {
72         
73         Set set = new HashSet();
74         if (this.databaseAdapter.getShowTableQuery(schema.getName(), false) != null) {
75             set.add(IQuantumConstants.Table);
76         } else if (this.databaseAdapter.getShowViewQuery(schema.getName(), false) != null) {
77             set.add(IQuantumConstants.View);
78         } else if (this.databaseAdapter.getShowSequenceQuery(schema.getName(), false) != null) {
79             set.add(IQuantumConstants.Sequence);
80         }
81         
82         DatabaseMetaData metaData = connection.getMetaData();
83         ResultSet resultSet = metaData.getTableTypes();
84         while (resultSet.next()) {
85             String type = resultSet.getString("TABLE_TYPE");
86             if (type != null) {
87                 type = type.trim();
88             }
89             if (STANDARD_TABLE_TYPES.contains(type)) {
90                 set.add(type);
91             }
92         }
93         
94         return (String[]) set.toArray(new String[set.size()]);
95     }
96
97     public String getInformation() throws SQLException {
98         try {
99             Connection connection = this.bookmark.getConnection();
100             DatabaseMetaData metaData = connection.getMetaData();
101         
102             return metaData == null ? null : metaData.getDatabaseProductName() + " " 
103                     + metaData.getDatabaseProductVersion();
104         } catch (NotConnectedException e) {
105             // TODO: think about this...
106             return "";
107         }
108     }
109     
110     /**
111      * Get a list of entities (tables, views, sequences) for a particular
112      * bookmark. This function is usually not redefined because it gives
113      * an external interface. You will usually redefine the getShowTableQuery(), 
114      * getShowViewQuery(), etc.
115      * 
116      * @param bookmark -
117      *     the bookmark that describes the database that is being accessed.
118      * @param passwordFinder -
119      *     a utility class that knows how to obtain a password, if required
120      * @param schema -
121      *     the schema from which to extract
122      * @param type -
123      *     the type ("VIEW", "TABLE", etc.) of entities to extract or null
124      *     if all entity types should be extracted
125      * @return 
126      *     an array of entity objects representing the tables, views and sequences.
127      * @throws SQLException
128      */
129     public Entity[] getEntities(Bookmark bookmark, Schema schema, String type) 
130         throws SQLException, NotConnectedException {
131         Connection connection = bookmark.getConnection();
132         Entity[] result = getEntities(bookmark, connection, schema, type);
133         return (result == null) ? new Entity[0] : result;
134     }
135     
136     protected Entity[] getEntities(Bookmark bookmark, Connection connection, Schema schema, String type) 
137         throws SQLException {
138         
139         List list = new ArrayList();
140         String[] types = (type == null) ? ALL_TYPES : new String[] { type };
141             
142         for (int i = 0; i < types.length; i++) {
143             list.addAll(getEntitiesList(bookmark, connection, types[i], schema));
144         }
145
146         return (Entity[]) list.toArray(new Entity[list.size()]);
147     }
148
149     protected List getEntitiesList(Bookmark bookmark, Connection connection, String type, Schema schema)
150         throws SQLException {
151
152         String sql = getSQL(bookmark, type, schema);
153         List list = new ArrayList();
154         SQLResults results = null;
155         if (sql != null) {
156             results = MultiSQLServer.getInstance().execute(connection, sql);
157             for (int i = 1, size = (results == null) ? 0 : results.getRowCount(); i <= size; i++) {
158                 String schemaName = results.getColumnCount() == 1 
159                     ? schema.getName() : results.getElement(1, i).toString();
160                 String tableName = results.getColumnCount() == 1 
161                     ? results.getElement(1, i).toString() 
162                     : results.getElement(2, i).toString();
163                 if (tableName != null && tableName.length() > 0) {
164                     Entity entity = EntityFactory.getInstance().create(
165                         bookmark, schemaName, tableName, type);
166                     if (entity != null) {
167                         list.add(entity);
168                     }
169                 }
170             }
171         }
172         // If we have some results, we go back
173         if (results != null) return list;
174         // Else, we try the JDBC driver
175         DatabaseMetaData metaData = connection.getMetaData();
176         // getTables needs a null schema to get all the schemas. So we don't pass a "" schema, but a null one
177                 ResultSet set = null;
178                 if (metaData.supportsSchemasInTableDefinitions())
179                 set = metaData.getTables(null, (schema != null) ? schema.getName() : null, "%", new String[] { type });
180             else
181                         set = metaData.getTables(null, null, "%", new String[] { type });
182             
183         while (set.next()) {
184             String tempSchema = set.getString("TABLE_SCHEM");
185             tempSchema = (tempSchema == null) ? "" : tempSchema.trim();
186             String tableName = set.getString("TABLE_NAME");
187             tableName = (tableName == null) ? "" : tableName.trim();
188
189             if (tableName != null && tableName.length() > 0) {
190                 Entity entity = EntityFactory.getInstance().create(bookmark, tempSchema, tableName, type);
191                 if (entity != null) {
192                     list.add(entity);
193                 }
194             }
195         }
196         set.close();
197         return list;
198     }
199
200
201     private String getSQL(Bookmark bookmark, String type, Schema schema) {
202         if (Entity.TABLE_TYPE.equals(type)) {
203             return this.databaseAdapter.getShowTableQuery(schema.getName(), schema.isDefault());
204         } else if (Entity.VIEW_TYPE.equals(type)) {
205             return this.databaseAdapter.getShowViewQuery(schema.getName(), schema.isDefault());
206         } else if (Entity.SEQUENCE_TYPE.equals(type)) {
207             return this.databaseAdapter.getShowSequenceQuery(schema.getName(), schema.isDefault());
208         } else {
209             return null;
210         }
211     }
212     
213
214 }