KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > metadata > JdbcTable


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc.metadata;
13
14 import com.versant.core.common.Debug;
15 import com.versant.core.jdbc.sql.exp.AndExp;
16 import com.versant.core.jdbc.sql.exp.SelectExp;
17 import com.versant.core.jdbc.sql.exp.SqlExp;
18 import com.versant.core.util.CharBuf;
19 import com.versant.core.jdbc.sql.exp.*;
20 import com.versant.core.jdbc.sql.JdbcNameGenerator;
21 import com.versant.core.jdbc.sql.SqlDriver;
22
23 import java.io.PrintStream JavaDoc;
24 import java.io.Serializable JavaDoc;
25 import java.util.*;
26
27 /**
28  * A table in a JDBC database.
29  */

30 public class JdbcTable implements Serializable JavaDoc, Comparable JavaDoc {
31
32     /**
33      * Cached sql to delete row from table.
34      */

35     public String JavaDoc deleteRowSql;
36
37     public String JavaDoc name;
38     public SqlDriver sqlDriver;
39     /**
40      * All the columns making up this table in 'create table' order.
41      */

42     public JdbcColumn[] cols;
43     /**
44      * The primary key of this table. Note that these may be compound columns
45      * consisting of multiple JdbcSimpleColumns.
46      */

47     public JdbcColumn[] pk;
48     /**
49      * How many simple columns make up the primary key of this table?
50      */

51     public int pkSimpleColumnCount;
52     /**
53      * The primary key of this table flattened into its JdbcColumn's.
54      */

55     public JdbcColumn[] pkSimpleCols;
56     /**
57      * The name of this tables primary key constraint.
58      */

59     public String JavaDoc pkConstraintName;
60     /**
61      * All the indexes.
62      */

63     public JdbcIndex[] indexes;
64     /**
65      * All the referential integrity constraints.
66      */

67     public JdbcConstraint[] constraints;
68     /**
69      * Comment info for the SQL script (e.g. class or field this table for).
70      */

71     public String JavaDoc comment;
72
73     private JdbcColumn lockRowColumn;
74
75     public JdbcTable() {
76     }
77
78     public List getConstraintList() {
79         if (constraints == null) {
80             return Collections.EMPTY_LIST;
81         }
82         ArrayList list = new ArrayList(constraints.length);
83         for (int i = 0; i < constraints.length; i++) {
84             JdbcConstraint constraint = constraints[i];
85             list.add(constraint);
86         }
87         return list;
88     }
89
90     public List getColumnList() {
91         if (cols == null) {
92             return Collections.EMPTY_LIST;
93         }
94         ArrayList list = new ArrayList(cols.length);
95         for (int i = 0; i < cols.length; i++) {
96             JdbcColumn col = cols[i];
97             list.add(col);
98         }
99         return list;
100     }
101
102     public String JavaDoc toString() {
103         return name;
104     }
105
106     public int hashCode() {
107         return name.hashCode();
108     }
109
110     /**
111      * Tables with the same name and store are equal.
112      */

113     public boolean equals(Object JavaDoc o) {
114         if (o instanceof JdbcTable) {
115             JdbcTable t = (JdbcTable)o;
116             return name.equals(t.name);
117         } else {
118             return false;
119         }
120     }
121
122     /**
123      * Sort by name.
124      */

125     public int compareTo(Object JavaDoc o) {
126         return name != null ? o != null ?
127                 name.compareTo(((JdbcTable)o).name) : 1 : -1;
128     }
129
130     /**
131      * Format the primary key as a String for debugging.
132      */

133     public String JavaDoc formatPkString() {
134         if (pk == null) return "(null)";
135         StringBuffer JavaDoc s = new StringBuffer JavaDoc();
136         for (int i = 0; i < pk.length; i++) {
137             if (i > 0) s.append(", ");
138             s.append(pk[i]);
139         }
140         return s.toString();
141     }
142
143     public void dump() {
144         dump(Debug.OUT, "");
145     }
146
147     public void dump(PrintStream JavaDoc out, String JavaDoc indent) {
148         out.println(indent + this + " PK " + formatPkString() + " constraint " +
149                 pkConstraintName);
150         String JavaDoc is = indent + " ";
151         if (cols != null) {
152             out.println(is + cols.length + " col(s)");
153             for (int i = 0; i < cols.length; i++) {
154                 out.println(is + "[" + i + "] " + cols[i]);
155             }
156         }
157         if (indexes != null) {
158             out.println(is + indexes.length + " index(es)");
159             for (int i = 0; i < indexes.length; i++) {
160                 out.println(is + "[" + i + "] " + indexes[i]);
161             }
162         }
163         if (constraints != null) {
164             out.println(is + constraints.length + " constraint(s)");
165             for (int i = 0; i < constraints.length; i++) {
166                 out.println(is + "[" + i + "] " + constraints[i]);
167             }
168         }
169     }
170
171     /**
172      * Find a primary key column by name. Returns column found or null if
173      * none.
174      */

175     public JdbcColumn findPkColumn(String JavaDoc columnName) {
176         for (int i = pk.length - 1; i >= 0; i--) {
177             JdbcColumn c = pk[i];
178             if (c.name.equals(columnName)) return c;
179         }
180         return null;
181     }
182
183     /**
184      * Get the names of all the JdbcColumn's in the primary key.
185      */

186     public String JavaDoc[] getPkNames() {
187         int pklen = pk == null ? 0 : pk.length;
188         String JavaDoc[] a = new String JavaDoc[pklen];
189         for (int i = 0; i < pklen; i++) {
190             a[i] = pk[i].name;
191         }
192         return a;
193     }
194
195     /**
196      * Set the table reference on all of our columns to us.
197      */

198     public void setTableOnCols() {
199         for (int i = 0; i < cols.length; i++) cols[i].table = this;
200         for (int i = 0; i < pk.length; i++) pk[i].table = this;
201     }
202
203     /**
204      * Append part of a where clause for our primary key columns to us (e.g
205      * pk1 = ? and pk2 = ?).
206      */

207     public void appendWherePK(CharBuf s) {
208         JdbcColumn.appendEqualsParam(s, pkSimpleCols, sqlDriver);
209     }
210
211     /**
212      * Append part of an insert column name list for our primary key columns
213      * to s (e.g 'pk1, pk2').
214      */

215     public void appendInsertPKColumnList(CharBuf s) {
216         int nc = pkSimpleCols.length;
217         s.append(pkSimpleCols[0].name);
218         for (int i = 1; i < nc; i++) {
219             s.append(", ");
220             s.append(pkSimpleCols[i].name);
221         }
222     }
223
224     /**
225      * Append part of an insert value list for our primary key columns
226      * to s (e.g '?, ?').
227      */

228     public void appendInsertPKValueList(CharBuf s) {
229         s.append("?");
230         int nc = pkSimpleCols.length;
231         for (int i = 1; i < nc; i++) s.append(", ?");
232     }
233
234     /**
235      * Append part of an insert column name list for all our columns
236      * to s (e.g 'cola, colb, colc').
237      */

238     public void appendInsertColumnList(CharBuf s) {
239         int nc = cols.length;
240         s.append(cols[0].name);
241         for (int i = 1; i < nc; i++) {
242             s.append(", ");
243             s.append(cols[i].name);
244         }
245     }
246
247     /**
248      * Append part of an insert value list for all our columns
249      * to s (e.g '?, ?, ?').
250      */

251     public void appendInsertValueList(CharBuf s) {
252         s.append("?");
253         int nc = cols.length;
254         for (int i = 1; i < nc; i++) s.append(", ?");
255     }
256
257     /**
258      * Get a pk = ? expression for this table.
259      */

260     public SqlExp createPkEqualsParamExp(SelectExp se) {
261         int nc = pkSimpleCols.length;
262         if (nc == 1) {
263             return pkSimpleCols[0].createEqualsParamExp(se);
264         } else {
265             SqlExp list = pkSimpleCols[0].createEqualsParamExp(se);
266             SqlExp pos = list;
267             for (int i = 1; i < nc; i++) {
268                 pos = pos.next = pkSimpleCols[i].createEqualsParamExp(se);
269             }
270             return new AndExp(list);
271         }
272     }
273
274     /**
275      * Get an order by list to order by our primary key.
276      */

277     public SqlExp createOrderByPKList(SelectExp se) {
278         SqlExp ans = pkSimpleCols[0].toSqlExp(se);
279         int nc = pkSimpleCols.length;
280         if (nc > 1) {
281             SqlExp e = ans;
282             for (int i = 1; i < nc; i++) {
283                 e = e.next = pkSimpleCols[i].toSqlExp(se);
284             }
285         }
286         return ans;
287     }
288
289     /**
290      * Set the primary key of this table. This will fill in pkSimpleCols
291      * and pkSimpleColumnCount as well.
292      */

293     public void setPk(JdbcColumn[] pk) {
294         this.pk = pk;
295         pkSimpleCols = pk;
296         pkSimpleColumnCount = pkSimpleCols.length;
297     }
298
299     /**
300      * Is there a columnName in the primary key of this table?
301      */

302     public boolean isInPrimaryKey(String JavaDoc columnName) {
303         for (int i = pk.length - 1; i >= 0; i--) {
304             if (pk[i].name.equals(columnName)) return true;
305         }
306         return false;
307     }
308
309     /**
310      * Get columns for a create table statement. This will remove any
311      * duplicate and shared columns from cols. If there are multiple
312      * shared=false columns with the same name and one of them is a foreign
313      * key then it is used.
314      */

315     public JdbcColumn[] getColsForCreateTable() {
316         ArrayList a = new ArrayList(cols.length);
317         HashMap map = new HashMap();
318         for (int i = 0; i < cols.length; i++) {
319             JdbcColumn c = cols[i];
320             if (c.shared) continue;
321             JdbcColumn o = (JdbcColumn)map.get(c.name);
322             if (o != null && (o.foreignKey || !c.foreignKey)) continue;
323             map.put(c.name, c);
324             a.add(c);
325         }
326         JdbcColumn[] ans = new JdbcColumn[a.size()];
327         a.toArray(ans);
328         return ans;
329     }
330
331     /**
332      * Get the column that is the best choice for dummy update locking. This
333      * will choose a simple non-indexed non-primary key column if possible.
334      */

335     public JdbcColumn getLockRowColumn() {
336         if (lockRowColumn == null) {
337             lockRowColumn = pk[0];
338             for (int i = cols.length - 1; i >= 0; i--) {
339                 lockRowColumn = chooseLockRowCol(cols[i], lockRowColumn);
340             }
341         }
342         return lockRowColumn;
343     }
344
345     private static JdbcColumn chooseLockRowCol(JdbcColumn a, JdbcColumn b) {
346         // choose a non-primary key column
347
if (!a.pk && b.pk) return a;
348         if (a.pk && !b.pk) return b;
349
350         // choose an unindexed column
351
if (!a.partOfIndex && b.partOfIndex) return a;
352         if (a.partOfIndex && !b.partOfIndex) return b;
353
354         // choose a non-foreign key column
355
if (!a.foreignKey && b.foreignKey) return a;
356         if (a.foreignKey && !b.foreignKey) return b;
357
358         // choose the column that is cheapest to update
359
int diff = JdbcTypes.getUpdateCost(a.jdbcType) -
360                 JdbcTypes.getUpdateCost(b.jdbcType);
361         if (diff < 0) return a;
362         if (diff > 0) return b;
363
364         return b;
365     }
366
367     public void addConstraints(ArrayList cons) {
368         int length = constraints != null ? constraints.length : 0;
369         int size = cons.size();
370         HashSet set = new HashSet((length + size) * 2);
371         for (int i = 0; i < length; i++) {
372             JdbcConstraint constraint = constraints[i];
373             if (!set.contains(constraint)) {
374                 set.add(constraint);
375             }
376         }
377         for (int i = 0; i < size; i++) {
378             Object JavaDoc o = cons.get(i);
379             if (!set.contains(o)) {
380                 set.add(o);
381             }
382         }
383         constraints = new JdbcConstraint[set.size()];
384         set.toArray(constraints);
385     }
386
387     public void nameConstraints(JdbcNameGenerator nameGenerator) {
388         if (constraints != null) {
389             for (int i = 0; i < constraints.length; i++) {
390                 JdbcConstraint constraint = constraints[i];
391                 if (constraint.name == null) {
392                     constraint.generateName(nameGenerator);
393                 }
394             }
395         }
396     }
397 }
398
Popular Tags