Initial implementation
[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     private String schema;
23     private String name;
24     private String type;
25     private Bookmark bookmark;
26     private Boolean exists = Boolean.TRUE;
27     
28     public EntityImpl(Bookmark bookmark, String schema, String name, String type) {
29         this.schema = schema;
30         this.name = name;
31         this.type = type;
32         this.bookmark = bookmark;
33     }
34     public Bookmark getBookmark() {
35         return this.bookmark;
36     }
37     public String getName() {
38         return this.name;
39     }
40     public String getSchema() {
41         return this.schema;
42     }
43     public String getType() {
44         return this.type;
45     }
46     public String getQualifiedName() {
47         return (this.schema == null || this.schema.length() == 0) ?
48             this.name : this.schema + "." + this.name;
49     }
50     public Column getColumn(String columnName) throws NotConnectedException, SQLException  {
51         Column column = null;
52         Column[] columns = getColumns();
53         for (int i = 0, length = (columns == null) ? 0 : columns.length;
54             column == null && i < length;
55             i++) {
56             if (columnName != null && columnName.equals(columns[i].getName())) {
57                 column = columns[i];
58             }
59         }
60         return column;
61     }
62     public Column[] getColumns() throws NotConnectedException, SQLException {
63         
64         Map temp = new HashMap();
65         Connection connection = this.bookmark.getConnection();
66         DatabaseMetaData metaData = connection.getMetaData();
67         ResultSet resultSet = metaData.getColumns(null, getSchema(), getName(), null);
68         try {
69                 while (resultSet.next()) {
70                     ColumnImpl column = new ColumnImpl(
71                         this, 
72                         resultSet.getString("COLUMN_NAME"),
73                         resultSet.getString("TYPE_NAME"),
74                         resultSet.getInt("DATA_TYPE"),
75                         resultSet.getInt("COLUMN_SIZE"),
76                         resultSet.getInt("DECIMAL_DIGITS"),
77                         "YES".equalsIgnoreCase(resultSet.getString("IS_NULLABLE")),
78                         resultSet.getInt("ORDINAL_POSITION"),
79                                         getComments(resultSet.getString("REMARKS"),getQualifiedName(), resultSet.getString("COLUMN_NAME"))
80                         );
81                     temp.put(column.getName(), column);
82                 }
83         } finally {
84                 resultSet.close();
85         }
86
87         resultSet = metaData.getPrimaryKeys(null, getSchema(), getName());
88         try {
89                 while (resultSet.next()) {
90                     String name = resultSet.getString("COLUMN_NAME");
91                     short keySequence = resultSet.getShort("KEY_SEQ");
92                     ColumnImpl column = (ColumnImpl) temp.get(name);
93                     if (column != null) {
94                         column.setPrimaryKeyOrder(keySequence);
95                     }
96                 }
97                 resultSet.close();
98                 
99                 List columnList = Collections.synchronizedList(
100                     new ArrayList(temp.values()));
101                 Collections.sort(columnList);
102                 return (Column[]) columnList.toArray(new Column[columnList.size()]);
103         } finally {
104                 resultSet.close();
105         }
106     }
107     
108     /**
109      * Some JDBC drivers (Oracle for example) won't return the comments
110      * We recheck with a custom query, if it's defined
111          * @param iniComment The already got comment
112          * @param tableName The fully qualified table name
113          * @param columnName The column name
114          */
115         private String getComments( String iniComment, String tableName, String columnName) {
116                 if (iniComment != null && iniComment.length() > 0) 
117                         return iniComment;
118                 String comment = "";
119                 try {
120                         Connection con = this.bookmark.getConnection();
121                         Statement stmt = con.createStatement();
122                         DatabaseAdapter adapter = this.bookmark.getAdapter();
123                         if (adapter != null && stmt != null && adapter.getCommentsQuery(tableName, columnName) != null) {
124                         
125                                 stmt.execute(adapter.getCommentsQuery(tableName, columnName));
126                                 ResultSet set = stmt.getResultSet();
127                                 if (set.next())
128                                         comment = set.getString(1);
129                         }
130                 } catch (NotConnectedException e) {
131                 } catch (SQLException e) {
132                 }
133             
134                 return comment;
135         }
136         public Index[] getIndexes() {
137         
138         List indexList = new ArrayList();
139         Map temp = new HashMap();
140         try {
141             Connection connection = this.bookmark.getConnection();
142             DatabaseMetaData metaData = connection.getMetaData();
143             ResultSet resultSet = metaData.getIndexInfo(null, getSchema(), getName(), false, false);
144             
145             while (resultSet.next()) {
146                 String indexName = resultSet.getString("INDEX_NAME");
147                 IndexImpl index = (IndexImpl) temp.get(indexName);
148                 if (index == null) {
149                     index = new IndexImpl(this, indexName);
150                     temp.put(indexName, index);
151                 }
152                 String columnName = resultSet.getString("COLUMN_NAME");
153                 String ascending = resultSet.getString("ASC_OR_DESC");
154                 index.addColumn(columnName, ascending == null 
155                     ? null : (ascending.toUpperCase().startsWith("A") 
156                         ? Boolean.TRUE : Boolean.FALSE));
157             }
158             resultSet.close();
159             indexList.addAll(temp.values());
160             
161         } catch (NotConnectedException e) {
162         } catch (SQLException e) {
163         }
164         return (Index[]) indexList.toArray(new Index[indexList.size()]);
165     }
166     
167     public Boolean exists() {
168         return this.exists;
169     }
170     
171     
172     /**
173      * @see com.quantum.model.Entity#getQuotedTableName()
174      */
175     public String getQuotedTableName() {
176         return getBookmark().getAdapter().filterTableName(getQualifiedName());
177     }
178
179     public ForeignKey[] getExportedKeys() throws SQLException, NotConnectedException {
180         return this.bookmark.getDatabase().getExportedKeys(getSchema(), getName());
181     }
182
183     public ForeignKey[] getImportedKeys() throws SQLException, NotConnectedException {
184         return this.bookmark.getDatabase().getImportedKeys(getSchema(), getName());
185     }
186     public ForeignKey[] getReferences() throws SQLException, NotConnectedException {
187         ForeignKey[] importedKeys = getImportedKeys();
188         ForeignKey[] exportedKeys = getExportedKeys();
189         
190         List list = new ArrayList(); // if we could guarantee JDK 1.4, we'd use LinkedHashSet 
191         for (int i = 0, length = importedKeys == null ? 0 : importedKeys.length; i < length; i++) {
192                         list.add(importedKeys[i]);
193                 }
194         for (int i = 0, length = exportedKeys == null ? 0 : exportedKeys.length; i < length; i++) {
195                 if (!list.contains(exportedKeys[i])) {
196                         list.add(exportedKeys[i]);
197                 }
198                 }
199         return (ForeignKey[]) list.toArray(new ForeignKey[list.size()]);
200     }
201     
202     public int compareTo(Object object) {
203                 Entity that = (Entity) object;
204                 if (that.getQualifiedName() == null && this.getQualifiedName() != null) {
205                         return 1;
206                 } else if (this.getQualifiedName() == null && that.getQualifiedName() != null) {
207                         return -1;
208                 } else if (this.getQualifiedName() == null && that.getQualifiedName() == null) {
209                         return 0;
210                 } else {
211                         return this.getQualifiedName().compareTo(that.getQualifiedName());
212                 }
213         }
214 }