001: /*
002: * Copyright 2003 (C) TJDO.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the TJDO License version 1.0.
006: * See the terms of the TJDO License in the documentation provided with this software.
007: *
008: * $Id: ForeignKeyInfo.java,v 1.2 2003/02/05 18:15:20 jackknifebarber Exp $
009: */
010:
011: package com.triactive.jdo.store;
012:
013: import java.io.PrintWriter;
014: import java.io.StringWriter;
015: import java.sql.DatabaseMetaData;
016: import java.sql.ResultSet;
017: import java.sql.SQLException;
018: import java.sql.Types;
019: import javax.jdo.JDOFatalDataStoreException;
020:
021: /**
022: * Represents the metadata of a specific foreign key column. This class is
023: * basically a data structure that makes accessing the JDBC foreign key metadata
024: * easier. Each of the items returned by
025: * {@link DatabaseMetaData#getImportedKeys(String,String,String)} or
026: * {@link DatabaseMetaData#getExportedKeys(String,String,String)}
027: * is represented by a public field in this class.
028: *
029: * Subclasses of ForeignKeyInfo can be created on a per-DBMS basis to supply
030: * missing metadata or correct faulty metadata obtained from that DBMS's JDBC
031: * driver(s).
032: *
033: * @author <a href="mailto:mmartin5@austin.rr.com">Mike Martin</a>
034: * @version $Revision: 1.2 $
035: *
036: * @see StoreManager#getForeignKeyInfo
037: * @see DatabaseAdapter#newForeignKeyInfo
038: */
039:
040: class ForeignKeyInfo {
041: /**
042: * The primary key table catalog, which may be <tt>null</tt>.
043: */
044: public String pkTableCat;
045:
046: /**
047: * The primary key table schema, which may be <tt>null</tt>.
048: */
049: public String pkTableSchem;
050:
051: /**
052: * The primary key table name.
053: */
054: public String pkTableName;
055:
056: /**
057: * The primary key column name.
058: */
059: public String pkColumnName;
060:
061: /**
062: * The foreign key table catalog, which may be <tt>null</tt>.
063: */
064: public String fkTableCat;
065:
066: /**
067: * The foreign key table schema, which may be <tt>null</tt>.
068: */
069: public String fkTableSchem;
070:
071: /**
072: * The foreign key table name.
073: */
074: public String fkTableName;
075:
076: /**
077: * The foreign key column name.
078: */
079: public String fkColumnName;
080:
081: /**
082: * The sequence number within the foreign key, base 1.
083: */
084: public short keySeq;
085:
086: /**
087: * What happens to a foreign key when the primary key is updated.
088: *
089: * @see DatabaseMetaData#importedKeyNoAction
090: * @see DatabaseMetaData#importedKeyCascade
091: * @see DatabaseMetaData#importedKeySetNull
092: * @see DatabaseMetaData#importedKeySetDefault
093: * @see DatabaseMetaData#importedKeyRestrict
094: */
095: public short updateRule;
096:
097: /**
098: * What happens to a foreign key when the primary key is deleted.
099: *
100: * @see DatabaseMetaData#importedKeyNoAction
101: * @see DatabaseMetaData#importedKeyCascade
102: * @see DatabaseMetaData#importedKeySetNull
103: * @see DatabaseMetaData#importedKeySetDefault
104: * @see DatabaseMetaData#importedKeyRestrict
105: */
106: public short deleteRule;
107:
108: /**
109: * The foreign key name.
110: */
111: public String fkName;
112:
113: /**
114: * The primary key name.
115: */
116: public String pkName;
117:
118: /**
119: * Indicates whether the evaluation of the foreign key constraint can be
120: * deferred until commit time.
121: *
122: * @see DatabaseMetaData#importedKeyInitiallyDeferred
123: * @see DatabaseMetaData#importedKeyInitiallyImmediate
124: * @see DatabaseMetaData#importedKeyNotDeferrable
125: */
126: public short deferrability;
127:
128: private int hash = 0;
129:
130: /**
131: * Constructs a foreign key information object from the current row of the
132: * given result set.
133: * The {@link ResultSet} object passed must have been obtained from a call
134: * to DatabaseMetaData.getImportedKeys() or
135: * DatabaseMetaData.getImportedKeys().
136: *
137: * <p>This method only retrieves the values from the current row; the caller
138: * is required to advance to the next row with {@link ResultSet#next}.
139: *
140: * @param rs The result set returned from DatabaseMetaData.get??portedKeys().
141: *
142: * @exception JDOFatalDataStoreException
143: * if a column of foreign key information could not be retrieved from the
144: * result set.
145: */
146:
147: public ForeignKeyInfo(ResultSet rs)
148: throws JDOFatalDataStoreException {
149: try {
150: pkTableCat = rs.getString(1);
151: pkTableSchem = rs.getString(2);
152: pkTableName = rs.getString(3);
153: pkColumnName = rs.getString(4);
154: fkTableCat = rs.getString(5);
155: fkTableSchem = rs.getString(6);
156: fkTableName = rs.getString(7);
157: fkColumnName = rs.getString(8);
158: keySeq = rs.getShort(9);
159: updateRule = rs.getShort(10);
160: deleteRule = rs.getShort(11);
161: fkName = rs.getString(12);
162: pkName = rs.getString(13);
163: deferrability = rs.getShort(14);
164: } catch (SQLException e) {
165: throw new JDOFatalDataStoreException(
166: "Can't read JDBC metadata from result set", e);
167: }
168: }
169:
170: /**
171: * Constructs a foreign key information object from its individual
172: * attributes.
173: *
174: * <p>This can be useful to subclasses and/or custom DatabaseAdapters that
175: * need to modify and/or correct the metadata returned by the JDBC driver.
176: */
177:
178: public ForeignKeyInfo(String pkTableCat, String pkTableSchem,
179: String pkTableName, String pkColumnName, String fkTableCat,
180: String fkTableSchem, String fkTableName,
181: String fkColumnName, short keySeq, short updateRule,
182: short deleteRule, String fkName, String pkName,
183: short deferrability) {
184: this .pkTableCat = pkTableCat;
185: this .pkTableSchem = pkTableSchem;
186: this .pkTableName = pkTableName;
187: this .pkColumnName = pkColumnName;
188: this .fkTableCat = fkTableCat;
189: this .fkTableSchem = fkTableSchem;
190: this .fkTableName = fkTableName;
191: this .fkColumnName = fkColumnName;
192: this .keySeq = keySeq;
193: this .updateRule = updateRule;
194: this .deleteRule = deleteRule;
195: this .fkName = fkName;
196: this .pkName = pkName;
197: this .deferrability = deferrability;
198: }
199:
200: /**
201: * Indicates whether some object is "equal to" this one.
202: * Two <tt>ForeignKeyInfo</tt> objects are considered equal if their
203: * catalog, schema, table, and column names, both primary and foreign, are
204: * all equal.
205: *
206: * @param obj the reference object with which to compare
207: *
208: * @return <tt>true</tt> if this object is equal to the obj argument;
209: * <tt>false</tt> otherwise.
210: */
211:
212: public final boolean equals(Object obj) {
213: if (obj == this )
214: return true;
215:
216: if (!(obj instanceof ForeignKeyInfo))
217: return false;
218:
219: ForeignKeyInfo ci = (ForeignKeyInfo) obj;
220:
221: return (pkTableCat == null ? ci.pkTableCat == null : pkTableCat
222: .equals(ci.pkTableCat))
223: && (pkTableSchem == null ? ci.pkTableSchem == null
224: : pkTableSchem.equals(ci.pkTableSchem))
225: && pkTableName.equals(ci.pkTableName)
226: && pkColumnName.equals(ci.pkColumnName)
227: && (fkTableCat == null ? ci.fkTableCat == null
228: : fkTableCat.equals(ci.fkTableCat))
229: && (fkTableSchem == null ? ci.fkTableSchem == null
230: : fkTableSchem.equals(ci.fkTableSchem))
231: && fkTableName.equals(ci.fkTableName)
232: && fkColumnName.equals(ci.fkColumnName);
233: }
234:
235: /**
236: * Returns a hash code value for this object.
237: *
238: * @return a hash code value for this object.
239: */
240:
241: public final int hashCode() {
242: if (hash == 0) {
243: hash = (pkTableCat == null ? 0 : pkTableCat.hashCode())
244: ^ (pkTableSchem == null ? 0 : pkTableSchem
245: .hashCode())
246: ^ pkTableName.hashCode()
247: ^ pkColumnName.hashCode()
248: ^ (fkTableCat == null ? 0 : fkTableCat.hashCode())
249: ^ (fkTableSchem == null ? 0 : fkTableSchem
250: .hashCode()) ^ fkTableName.hashCode()
251: ^ fkColumnName.hashCode();
252: }
253:
254: return hash;
255: }
256:
257: /**
258: * Returns the string representation of this object.
259: *
260: * @return string representation of this object.
261: */
262:
263: public String toString() {
264: StringWriter sw = new StringWriter();
265: PrintWriter pw = new PrintWriter(sw);
266:
267: pw.println(this .getClass().getName());
268: pw.print(" pkTableCat = ");
269: pw.println(pkTableCat);
270: pw.print(" pkTableSchem = ");
271: pw.println(pkTableSchem);
272: pw.print(" pkTableName = ");
273: pw.println(pkTableName);
274: pw.print(" pkColumnName = ");
275: pw.println(pkColumnName);
276: pw.print(" fkTableCat = ");
277: pw.println(fkTableCat);
278: pw.print(" fkTableSchem = ");
279: pw.println(fkTableSchem);
280: pw.print(" fkTableName = ");
281: pw.println(fkTableName);
282: pw.print(" fkColumnName = ");
283: pw.println(fkColumnName);
284: pw.print(" keySeq = ");
285: pw.println(keySeq);
286: pw.print(" updateRule = ");
287: pw.println(updateRule);
288: pw.print(" deleteRule = ");
289: pw.println(deleteRule);
290: pw.print(" fkName = ");
291: pw.println(fkName);
292: pw.print(" pkName = ");
293: pw.println(pkName);
294: pw.print(" deferrability = ");
295: pw.println(deferrability);
296: pw.close();
297:
298: return sw.toString();
299: }
300: }
|