KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > table > TableLink


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.table;
6
7 import java.sql.Connection JavaDoc;
8 import java.sql.DatabaseMetaData JavaDoc;
9 import java.sql.DriverManager JavaDoc;
10 import java.sql.PreparedStatement JavaDoc;
11 import java.sql.ResultSet JavaDoc;
12 import java.sql.ResultSetMetaData JavaDoc;
13 import java.sql.SQLException JavaDoc;
14 import java.sql.Statement JavaDoc;
15 import java.util.HashMap JavaDoc;
16
17 import org.h2.engine.Session;
18 import org.h2.index.Index;
19 import org.h2.index.IndexType;
20 import org.h2.index.LinkedIndex;
21 import org.h2.message.Message;
22 import org.h2.result.Row;
23 import org.h2.schema.Schema;
24 import org.h2.util.JdbcUtils;
25 import org.h2.util.ObjectArray;
26 import org.h2.util.StringUtils;
27 import org.h2.value.DataType;
28
29 /**
30  * @author Thomas
31  */

32
33 public class TableLink extends Table {
34
35     private String JavaDoc driver, url, user, password, originalTable;
36     private Connection JavaDoc conn;
37     private HashMap JavaDoc prepared = new HashMap JavaDoc();
38     private ObjectArray indexes = new ObjectArray();
39
40     public TableLink(Schema schema, int id, String JavaDoc name, String JavaDoc driver, String JavaDoc url,
41             String JavaDoc user, String JavaDoc password, String JavaDoc originalTable) throws SQLException JavaDoc {
42         super(schema, id, name, false);
43         this.driver = driver;
44         this.url = url;
45         this.user = user;
46         this.password = password;
47         this.originalTable = originalTable;
48         try {
49             database.loadClass(driver);
50         } catch(ClassNotFoundException JavaDoc e) {
51             throw Message.getSQLException(Message.CLASS_NOT_FOUND_1, new String JavaDoc[]{driver}, e);
52         }
53         conn = DriverManager.getConnection(url, user, password);
54         DatabaseMetaData JavaDoc meta = conn.getMetaData();
55         boolean storesLowerCase = meta.storesLowerCaseIdentifiers();
56         ResultSet JavaDoc rs = meta.getColumns(null, null, originalTable, null);
57         int i=0;
58         ObjectArray columnList = new ObjectArray();
59         HashMap JavaDoc columnMap = new HashMap JavaDoc();
60         while(rs.next()) {
61             String JavaDoc n = rs.getString("COLUMN_NAME");
62             if(storesLowerCase && n.equals(StringUtils.toLowerEnglish(n))) {
63                 n = StringUtils.toUpperEnglish(n);
64             }
65             int sqlType = rs.getInt("DATA_TYPE");
66             long precision = rs.getInt("COLUMN_SIZE");
67             int scale = rs.getInt("DECIMAL_DIGITS");
68             int type = DataType.convertSQLTypeToValueType(sqlType);
69             precision = Math.max(precision, DataType.getDataType(type).defaultPrecision);
70             Column col = new Column(n, type, precision, scale);
71             col.setTable(this, i++);
72             columnList.add(col);
73             columnMap.put(n, col);
74         }
75         if(columnList.size()==0) {
76             Statement JavaDoc stat = null;
77             try {
78                 stat = conn.createStatement();
79                 rs = stat.executeQuery("SELECT * FROM " + originalTable + " T WHERE 1=0");
80                 ResultSetMetaData JavaDoc rsm = rs.getMetaData();
81                 for(i=0; i<rsm.getColumnCount();) {
82                     String JavaDoc n = rsm.getColumnName(i+1);
83                     if(storesLowerCase && n.equals(StringUtils.toLowerEnglish(n))) {
84                         n = StringUtils.toUpperEnglish(n);
85                     }
86                     int sqlType = rsm.getColumnType(i+1);
87                     long precision = rsm.getPrecision(i+1);
88                     int scale = rsm.getScale(i+1);
89                     int type = DataType.convertSQLTypeToValueType(sqlType);
90                     precision = Math.max(precision, DataType.getDataType(type).defaultPrecision);
91                     Column col = new Column(n, type, precision, scale);
92                     col.setTable(this, i++);
93                     columnList.add(col);
94                     columnMap.put(n, col);
95                 }
96             } catch(SQLException JavaDoc e) {
97                 throw Message.getSQLException(Message.TABLE_OR_VIEW_NOT_FOUND_1, new String JavaDoc[]{originalTable}, e);
98             } finally {
99                 JdbcUtils.closeSilently(stat);
100             }
101         }
102         Column[] cols = new Column[columnList.size()];
103         columnList.toArray(cols);
104         setColumns(cols);
105         Index index = new LinkedIndex(this, id, cols, IndexType.createNonUnique(false));
106         indexes.add(index);
107         rs = meta.getPrimaryKeys(null, null, originalTable);
108         String JavaDoc pkName = "";
109         ObjectArray list;
110         if (rs.next()) {
111             // the problem is, the rows are not sorted by KEY_SEQ
112
list = new ObjectArray();
113             do {
114                 int idx = rs.getInt("KEY_SEQ");
115                 if(pkName == null) {
116                     pkName = rs.getString("PK_NAME");
117                 }
118                 while (list.size() < idx) {
119                     list.add(null);
120                 }
121                 String JavaDoc col = rs.getString("COLUMN_NAME");
122                 Column column = (Column) columnMap.get(col);
123                 list.set(idx - 1, column);
124             } while (rs.next());
125             addIndex(list, IndexType.createPrimaryKey(false, false));
126         }
127         try {
128             rs = meta.getIndexInfo(null, null, originalTable, false, false);
129         } catch(SQLException JavaDoc e) {
130             // Oracle throws an exception if the table is not found or is a SYNONMY
131
rs = null;
132         }
133         String JavaDoc indexName = null;
134         list = new ObjectArray();
135         IndexType indexType = null;
136         while (rs != null && rs.next()) {
137             String JavaDoc newIndex = rs.getString("INDEX_NAME");
138             if (pkName.equals(newIndex)) {
139                 continue;
140             }
141             if (indexName != null && !indexName.equals(newIndex)) {
142                 addIndex(list, indexType);
143                 indexName = null;
144             }
145             if (indexName == null) {
146                 indexName = newIndex;
147                 list.clear();
148             }
149             boolean unique = !rs.getBoolean("NON_UNIQUE");
150             indexType = unique ? IndexType.createUnique(false, false): IndexType.createNonUnique(false);
151             String JavaDoc col = rs.getString("COLUMN_NAME");
152             Column column = (Column) columnMap.get(col);
153             list.add(column);
154         }
155         if (indexName != null) {
156             addIndex(list, indexType);
157         }
158     }
159
160     private void addIndex(ObjectArray list, IndexType indexType) {
161         Column[] cols = new Column[list.size()];
162         list.toArray(cols);
163         Index index = new LinkedIndex(this, 0, cols, indexType);
164         indexes.add(index);
165     }
166
167     public String JavaDoc getCreateSQL() {
168         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
169         buff.append("CREATE LINKED TABLE ");
170         buff.append(getSQL());
171         if(comment != null) {
172             buff.append(" COMMENT ");
173             buff.append(StringUtils.quoteStringSQL(comment));
174         }
175         buff.append("(");
176         buff.append(StringUtils.quoteStringSQL(driver));
177         buff.append(", ");
178         buff.append(StringUtils.quoteStringSQL(url));
179         buff.append(", ");
180         buff.append(StringUtils.quoteStringSQL(user));
181         buff.append(", ");
182         buff.append(StringUtils.quoteStringSQL(password));
183         buff.append(", ");
184         buff.append(StringUtils.quoteStringSQL(originalTable));
185         buff.append(")");
186         return buff.toString();
187     }
188
189     public Index addIndex(Session session, String JavaDoc indexName, int indexId, Column[] cols, IndexType indexType, int headPos, String JavaDoc comment) throws SQLException JavaDoc {
190         throw Message.getUnsupportedException();
191     }
192
193     public void lock(Session session, boolean exclusive) throws SQLException JavaDoc {
194         // nothing to do
195
}
196     
197     public boolean isLockedExclusively() {
198         return false;
199     }
200
201     public Index getScanIndex(Session session) {
202         return (Index) indexes.get(0);
203     }
204
205     public void removeRow(Session session, Row row) throws SQLException JavaDoc {
206         getScanIndex(session).remove(session, row);
207     }
208
209     public void addRow(Session session, Row row) throws SQLException JavaDoc {
210         getScanIndex(session).add(session, row);
211     }
212
213     public void close(Session session) throws SQLException JavaDoc {
214         if(conn != null) {
215             try {
216                 conn.close();
217             } finally {
218                 conn = null;
219             }
220         }
221     }
222
223     public int getRowCount() throws SQLException JavaDoc {
224         PreparedStatement JavaDoc prep = getPreparedStatement("SELECT COUNT(*) FROM "+originalTable);
225         ResultSet JavaDoc rs = prep.executeQuery();
226         rs.next();
227         int count = rs.getInt(1);
228         rs.close();
229         return count;
230     }
231
232     public String JavaDoc getOriginalTable() {
233         return originalTable;
234     }
235
236     public PreparedStatement JavaDoc getPreparedStatement(String JavaDoc sql) throws SQLException JavaDoc {
237         PreparedStatement JavaDoc prep = (PreparedStatement JavaDoc) prepared.get(sql);
238         if(prep==null) {
239             prep = conn.prepareStatement(sql);
240             prepared.put(sql, prep);
241         }
242         return prep;
243     }
244
245     public void unlock(Session s) {
246         // nothing to do
247
}
248
249     public void checkRename() throws SQLException JavaDoc {
250     }
251
252     public void checkSupportAlter() throws SQLException JavaDoc {
253         throw Message.getUnsupportedException();
254     }
255     
256     public void truncate(Session session) throws SQLException JavaDoc {
257         throw Message.getUnsupportedException();
258     }
259
260     public boolean canGetRowCount() {
261         return true;
262     }
263
264     public boolean canDrop() {
265         return true;
266     }
267
268     public String JavaDoc getTableType() {
269         return Table.TABLE_LINK;
270     }
271
272     public void removeChildrenAndResources(Session session) throws SQLException JavaDoc {
273         super.removeChildrenAndResources(session);
274         close(session);
275         driver = null;
276         url = user = password = originalTable = null;
277         conn = null;
278         prepared = null;
279         invalidate();
280     }
281
282     public ObjectArray getIndexes() {
283         return indexes;
284     }
285
286     public long getMaxDataModificationId() {
287         // data may have been modified externally
288
return Long.MAX_VALUE;
289     }
290
291     public Index getUniqueIndex() {
292         for(int i=0; i<indexes.size(); i++) {
293             Index idx = (Index) indexes.get(i);
294             if(idx.getIndexType().isUnique()) {
295                 return idx;
296             }
297         }
298         return null;
299     }
300     
301 }
302
Popular Tags