f16a1e0f5775a060c6fd7d9b9a2ff5e3981d0d29
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / model / EntityImpl.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.sql.Statement;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13
14 import com.quantum.adapters.DatabaseAdapter;
15
16 /**
17  * This class models a table or view.
18  * 
19  * @author bcholmes
20  */
21 abstract class EntityImpl implements Entity {
22         
23         // The JDBC-ODBC Driver is more happy if you look up metadata values
24         // using the column number than if you use the column name
25         
26         private static final int INDEX_METADATA_INDEX_NAME = 6;
27         private static final int INDEX_METADATA_COLUMN_NAME = 9;
28         private static final int INDEX_METADATA_ASC_OR_DESC = 10;
29         
30         private static final int PRIMARY_KEYS_METADATA_COLUMN_NAME = 4;
31         private static final int PRIMARY_KEYS_METADATA_KEY_SEQ = 5;
32         
33         private static final int COLUMN_METADATA_COLUMN_NAME = 4;
34         private static final int COLUMN_METATDATA_DATA_TYPE = 5;
35         private static final int COLUMN_METATDATA_TYPE_NAME = 6;
36         private static final int COLUMN_METADATA_COLUMN_SIZE = 7;
37         private static final int COLUMN_METADATA_DECIMAL_DIGITS = 9;
38         private static final int COLUMN_METADATA_REMARKS = 12;
39         private static final int COLUMN_METADATA_ORDINAL_POSITION = 17;
40         private static final int COLUMN_METADATA_IS_NULLABLE = 18;
41         
42         private String schema;
43     private String name;
44     private String type;
45     private Bookmark bookmark;
46     private Boolean exists = Boolean.TRUE;
47     
48     public EntityImpl(Bookmark bookmark, String schema, String name, String type) {
49         this.schema = schema;
50         this.name = name;
51         this.type = type;
52         this.bookmark = bookmark;
53     }
54     public Bookmark getBookmark() {
55         return this.bookmark;
56     }
57     public String getName() {
58         return this.name;
59     }
60     public String getSchema() {
61         return this.schema;
62     }
63     public String getType() {
64         return this.type;
65     }
66     public String getQualifiedName() {
67         return (this.schema == null || this.schema.length() == 0) ?
68             this.name : this.schema + "." + this.name;
69     }
70     public Column getColumn(String columnName) throws NotConnectedException, SQLException  {
71         Column column = null;
72         Column[] columns = getColumns();
73         for (int i = 0, length = (columns == null) ? 0 : columns.length;
74             column == null && i < length;
75             i++) {
76             if (columnName != null && columnName.equals(columns[i].getName())) {
77                 column = columns[i];
78             }
79         }
80         return column;
81     }
82     public Column[] getColumns() throws NotConnectedException, SQLException {
83         
84         Map temp = new HashMap();
85         Connection connection = this.bookmark.getConnection();
86         DatabaseMetaData metaData = connection.getMetaData();
87         ResultSet resultSet = metaData.getColumns(null, getSchema(), getName(), null);
88         try {
89                 while (resultSet.next()) {
90                     ColumnImpl column = new ColumnImpl(
91                         this, 
92                         resultSet.getString(COLUMN_METADATA_COLUMN_NAME),
93                         resultSet.getString(COLUMN_METATDATA_TYPE_NAME),
94                         resultSet.getInt(COLUMN_METATDATA_DATA_TYPE),
95                         resultSet.getInt(COLUMN_METADATA_COLUMN_SIZE),
96                         resultSet.getInt(COLUMN_METADATA_DECIMAL_DIGITS),
97                         "YES".equalsIgnoreCase(resultSet.getString(COLUMN_METADATA_IS_NULLABLE)),
98                         resultSet.getInt(COLUMN_METADATA_ORDINAL_POSITION),
99                                         getComments(
100                                                         resultSet.getString(COLUMN_METADATA_REMARKS),
101                                                         getQualifiedName(), 
102                                                         resultSet.getString(COLUMN_METADATA_COLUMN_NAME))
103                         );
104                     temp.put(column.getName(), column);
105                 }
106         } finally {
107                 resultSet.close();
108         }
109
110         resultSet = metaData.getPrimaryKeys(null, getSchema(), getName());
111         try {
112                 while (resultSet.next()) {
113                     String name = resultSet.getString(PRIMARY_KEYS_METADATA_COLUMN_NAME);
114                     short keySequence = resultSet.getShort(PRIMARY_KEYS_METADATA_KEY_SEQ);
115                     ColumnImpl column = (ColumnImpl) temp.get(name);
116                     if (column != null) {
117                         column.setPrimaryKeyOrder(keySequence);
118                     }
119                 }
120                 resultSet.close();
121                 
122                 List columnList = Collections.synchronizedList(
123                     new ArrayList(temp.values()));
124                 Collections.sort(columnList);
125                 return (Column[]) columnList.toArray(new Column[columnList.size()]);
126         } finally {
127                 resultSet.close();
128         }
129     }
130     
131     /**
132      * Some JDBC drivers (Oracle for example) won't return the comments
133      * We recheck with a custom query, if it's defined
134          * @param iniComment The already got comment
135          * @param tableName The fully qualified table name
136          * @param columnName The column name
137          */
138         private String getComments( String iniComment, String tableName, String columnName) {
139                 if (iniComment != null && iniComment.length() > 0) 
140                         return iniComment;
141                 String comment = "";
142                 try {
143                         Connection con = this.bookmark.getConnection();
144                         DatabaseAdapter adapter = this.bookmark.getAdapter();
145                         Statement stmt = con.createStatement();
146                         try {
147                                 if (adapter != null && stmt != null 
148                                                 && adapter.getCommentsQuery(tableName, columnName) != null) {
149                                 
150                                         stmt.execute(adapter.getCommentsQuery(tableName, columnName));
151                                         ResultSet set = stmt.getResultSet();
152                                         try {
153                                                 if (set.next()) {
154                                                         comment = set.getString(1);
155                                                 }
156                                         } finally {
157                                                 set.close();
158                                         }
159                                 }
160                         } finally {
161                                 stmt.close();
162                         }
163                 } catch (NotConnectedException e) {
164                 } catch (SQLException e) {
165                 }
166             
167                 return comment;
168         }
169         
170         public Index[] getIndexes() {
171         
172         List indexList = new ArrayList();
173         Map temp = new HashMap();
174         try {
175             Connection connection = this.bookmark.getConnection();
176             DatabaseMetaData metaData = connection.getMetaData();
177             ResultSet resultSet = metaData.getIndexInfo(null, getSchema(), getName(), false, false);
178             
179             while (resultSet.next()) {
180                 String indexName = resultSet.getString(INDEX_METADATA_INDEX_NAME);
181                 IndexImpl index = (IndexImpl) temp.get(indexName);
182                 if (index == null) {
183                     index = new IndexImpl(this, indexName);
184                     temp.put(indexName, index);
185                 }
186                 String columnName = resultSet.getString(INDEX_METADATA_COLUMN_NAME);
187                 String ascending = resultSet.getString(INDEX_METADATA_ASC_OR_DESC);
188                 index.addColumn(columnName, ascending == null 
189                     ? null : (ascending.toUpperCase().startsWith("A") 
190                         ? Boolean.TRUE : Boolean.FALSE));
191             }
192             resultSet.close();
193             indexList.addAll(temp.values());
194             
195         } catch (NotConnectedException e) {
196         } catch (SQLException e) {
197         }
198         return (Index[]) indexList.toArray(new Index[indexList.size()]);
199     }
200     
201     public Boolean exists() {
202         return this.exists;
203     }
204     
205     
206     /**
207      * @see com.quantum.model.Entity#getQuotedTableName()
208      */
209     public String getQuotedTableName() {
210         return getBookmark().getAdapter().filterTableName(getQualifiedName());
211     }
212
213     public ForeignKey[] getExportedKeys() throws SQLException, NotConnectedException {
214         return this.bookmark.getDatabase().getExportedKeys(getSchema(), getName());
215     }
216
217     public ForeignKey[] getImportedKeys() throws SQLException, NotConnectedException {
218         return this.bookmark.getDatabase().getImportedKeys(getSchema(), getName());
219     }
220     public ForeignKey[] getReferences() throws SQLException, NotConnectedException {
221         ForeignKey[] importedKeys = getImportedKeys();
222         ForeignKey[] exportedKeys = getExportedKeys();
223         
224         List list = new ArrayList(); // if we could guarantee JDK 1.4, we'd use LinkedHashSet 
225         for (int i = 0, length = importedKeys == null ? 0 : importedKeys.length; i < length; i++) {
226                         list.add(importedKeys[i]);
227                 }
228         for (int i = 0, length = exportedKeys == null ? 0 : exportedKeys.length; i < length; i++) {
229                 if (!list.contains(exportedKeys[i])) {
230                         list.add(exportedKeys[i]);
231                 }
232                 }
233         return (ForeignKey[]) list.toArray(new ForeignKey[list.size()]);
234     }
235     
236     public int compareTo(Object object) {
237                 Entity that = (Entity) object;
238                 if (that.getQualifiedName() == null && this.getQualifiedName() != null) {
239                         return 1;
240                 } else if (this.getQualifiedName() == null && that.getQualifiedName() != null) {
241                         return -1;
242                 } else if (this.getQualifiedName() == null && that.getQualifiedName() == null) {
243                         return 0;
244                 } else {
245                         return this.getQualifiedName().compareTo(that.getQualifiedName());
246                 }
247         }
248 }