001: package com.workingdogs.village;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.sql.ResultSetMetaData;
023: import java.sql.SQLException;
024: import java.sql.Types;
025:
026: /**
027: * This class represents a Column in the database and its associated meta information. A <a href="Record.html">Record</A> is a
028: * collection of columns.
029: *
030: * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
031: * @version $Revision: 568 $
032: */
033: public class Column {
034: /** column number in a schema object */
035: private int columnNumber = -1;
036:
037: /** name of the column */
038: private String name = "";
039:
040: /** example: this column is of type "String" */
041: private String columnTypeName = "";
042:
043: /** what java.sql.Type is this column? */
044: private int columnType = Types.LONGVARCHAR;
045:
046: /** name of table that this column belongs to */
047: private String tableName = "";
048:
049: /** is null allowed for this column? */
050: private boolean nullAllowed = false;
051:
052: /** is this an auto increment column? */
053: private boolean autoIncrement = false;
054:
055: /** is this a read only column? */
056: private boolean readOnly = false;
057:
058: /** is this a searchable column? */
059: private boolean searchable = false;
060:
061: /** what is the scale of this column? */
062: private int scale = -1;
063:
064: /** what is the precision of this column? */
065: private int precision = -1;
066:
067: /** what is the length of this column? */
068: private int length = -1;
069:
070: /**
071: * constructor
072: */
073: public Column() {
074: this .columnNumber = -1;
075: this .name = "";
076: this .columnTypeName = "";
077: this .tableName = "";
078: this .columnType = Types.LONGVARCHAR;
079: this .nullAllowed = false;
080: this .autoIncrement = false;
081: this .readOnly = false;
082: this .searchable = false;
083: this .scale = -1;
084: this .precision = -1;
085: this .length = -1;
086: }
087:
088: /**
089: * internal package method for populating a Column instance
090: *
091: * @param rsmd TODO: DOCUMENT ME!
092: * @param colNum TODO: DOCUMENT ME!
093: * @param tableName TODO: DOCUMENT ME!
094: *
095: * @throws SQLException TODO: DOCUMENT ME!
096: */
097: void populate(ResultSetMetaData rsmd, int colNum, String tableName)
098: throws SQLException {
099: this .columnNumber = colNum;
100: this .name = rsmd.getColumnName(columnNumber);
101:
102: // Workaround for Sybase jConnect 5.2 and older.
103: try {
104: this .tableName = rsmd.getTableName(columnNumber);
105:
106: // ResultSetMetaData may report table name as the empty
107: // string when a database-specific function has been
108: // called to generate a Column.
109: if ((this .tableName == null) || this .tableName.equals("")) {
110: if (tableName != null) {
111: this .tableName = tableName;
112: } else {
113: this .tableName = "";
114: }
115: }
116: } catch (RuntimeException e) {
117: if (tableName != null) {
118: this .tableName = tableName;
119: } else {
120: this .tableName = "";
121: }
122: }
123:
124: this .columnTypeName = rsmd.getColumnTypeName(columnNumber);
125: this .columnType = rsmd.getColumnType(columnNumber);
126: this .nullAllowed = rsmd.isNullable(columnNumber) == 1;
127: this .autoIncrement = rsmd.isAutoIncrement(columnNumber);
128:
129: // The JDBC spec is VERY unclear about what this means and as
130: // such, it should be ignored. Derby returns true all the time.
131: // Sybase and Informix say it's unsupported (and false).
132: this .readOnly = false; // rsmd.isReadOnly (columnNumber);
133:
134: this .searchable = rsmd.isSearchable(columnNumber);
135: this .scale = rsmd.getScale(columnNumber);
136:
137: try {
138: this .precision = rsmd.getPrecision(columnNumber);
139: } catch (NumberFormatException assumedTooLarge) {
140: // This may happen if the precision is too large for an
141: // int, with column types such as MySQL BIGINT, Oracle
142: // BLOB, etc.. See bug #4625851 at the JDC for details.
143: this .precision = Integer.MAX_VALUE;
144: }
145:
146: this .length = rsmd.getColumnDisplaySize(columnNumber);
147: }
148:
149: /**
150: * the name of the column
151: *
152: * @return the name of the column
153: */
154: public String name() {
155: return this .name;
156: }
157:
158: /**
159: * the data type of a column
160: *
161: * @return the java.sql.Types String
162: */
163: public String dbType() {
164: return this .columnTypeName;
165: }
166:
167: /**
168: * the data type of a column
169: *
170: * @return the java.sql.Types enum
171: */
172: public int typeEnum() {
173: return this .columnType;
174: }
175:
176: /**
177: * does this column allow null?
178: *
179: * @return whether or not the column has null Allowed
180: */
181: public boolean nullAllowed() {
182: return this .nullAllowed;
183: }
184:
185: /**
186: * does this column auto increment?
187: *
188: * @return whether or not this column auto increments
189: */
190: public boolean autoIncrement() {
191: return this .autoIncrement;
192: }
193:
194: /**
195: * is this column read only?
196: *
197: * @return whether or not this column is read only
198: */
199: public boolean readOnly() {
200: return this .readOnly;
201: }
202:
203: /**
204: * is this column searchable?
205: *
206: * @return true if this column is searchable
207: */
208: public boolean searchable() {
209: return this .searchable;
210: }
211:
212: /**
213: * the scale of the column
214: *
215: * @return the scale of the column
216: */
217: public int scale() {
218: return this .scale;
219: }
220:
221: /**
222: * the precision of the column
223: *
224: * @return the precision of the column
225: */
226: public int precision() {
227: return this .precision;
228: }
229:
230: /**
231: * the storage length of a column
232: *
233: * @return the storage length of a column
234: */
235: public int length() {
236: return this .length;
237: }
238:
239: /**
240: * the type of the column as a string
241: *
242: * @return the type of the column as a string
243: */
244: public String type() {
245: if (isBoolean()) {
246: return "BOOLEAN";
247: } else if (isByte()) {
248: return "BYTE";
249: } else if (isShort()) {
250: return "SHORT";
251: } else if (isInt()) {
252: return "INTEGER";
253: } else if (isLong()) {
254: return "LONG";
255: } else if (isFloat()) {
256: return "FLOAT";
257: } else if (isDouble()) {
258: return "DOUBLE";
259: } else if (isBigDecimal()) {
260: return "BIGDECIMAL";
261: } else if (isDate()) {
262: return "DATE";
263: } else if (isTime()) {
264: return "TIME";
265: } else if (isTimestamp()) {
266: return "TIMESTAMP";
267: } else if (isString()) {
268: return "STRING";
269: } else if (isBinary()) {
270: return "BINARY";
271: } else if (isVarBinary()) {
272: return "VARBINARY";
273: } else if (isLongVarBinary()) {
274: return "LONGVARBINARY";
275: }
276:
277: return "UNKNOWN TYPE: " + typeEnum();
278: }
279:
280: /**
281: * column isBoolean: -7
282: *
283: * @return TODO: DOCUMENT ME!
284: */
285: public boolean isBoolean() {
286: return this .typeEnum() == Types.BIT;
287: }
288:
289: /**
290: * column isBigDecimal: 2 || 3
291: *
292: * @return TODO: DOCUMENT ME!
293: */
294: public boolean isBigDecimal() {
295: return (this .typeEnum() == Types.NUMERIC)
296: || (this .typeEnum() == Types.DECIMAL);
297: }
298:
299: /**
300: * column isBinary: -2
301: *
302: * @return TODO: DOCUMENT ME!
303: */
304: public boolean isBinary() {
305: return this .typeEnum() == Types.BINARY;
306: }
307:
308: /**
309: * column isByte: -6
310: *
311: * @return TODO: DOCUMENT ME!
312: */
313: public boolean isByte() {
314: return this .typeEnum() == Types.TINYINT;
315: }
316:
317: /**
318: * column isBytes: -4 || -3 || -2
319: *
320: * @return TODO: DOCUMENT ME!
321: */
322: public boolean isBytes() {
323: return (this .typeEnum() == Types.LONGVARBINARY)
324: || (this .typeEnum() == Types.VARBINARY)
325: || (this .columnType == Types.BINARY);
326: }
327:
328: /**
329: * column isBytes: 91
330: *
331: * @return TODO: DOCUMENT ME!
332: */
333: public boolean isDate() {
334: return this .typeEnum() == Types.DATE;
335: }
336:
337: /**
338: * column isDouble: 6 || 8
339: *
340: * @return TODO: DOCUMENT ME!
341: */
342: public boolean isDouble() {
343: return (this .typeEnum() == Types.FLOAT)
344: || (this .typeEnum() == Types.DOUBLE);
345: }
346:
347: /**
348: * column isFloat: 7
349: *
350: * @return TODO: DOCUMENT ME!
351: */
352: public boolean isFloat() {
353: return this .typeEnum() == Types.REAL;
354: }
355:
356: /**
357: * column isInt: 4
358: *
359: * @return TODO: DOCUMENT ME!
360: */
361: public boolean isInt() {
362: return this .typeEnum() == Types.INTEGER;
363: }
364:
365: /**
366: * column isLong: -5
367: *
368: * @return TODO: DOCUMENT ME!
369: */
370: public boolean isLong() {
371: return this .typeEnum() == Types.BIGINT;
372: }
373:
374: /**
375: * column isShort: 5
376: *
377: * @return TODO: DOCUMENT ME!
378: */
379: public boolean isShort() {
380: return this .typeEnum() == Types.SMALLINT;
381: }
382:
383: /**
384: * column isString: -1 || -11 || 12
385: *
386: * @return TODO: DOCUMENT ME!
387: */
388: public boolean isString() {
389: return (this .typeEnum() == Types.LONGVARCHAR)
390: || (this .typeEnum() == Types.VARCHAR)
391: || (this .typeEnum() == 11);
392: }
393:
394: /**
395: * column isTime: 92
396: *
397: * @return TODO: DOCUMENT ME!
398: */
399: public boolean isTime() {
400: return this .typeEnum() == Types.TIME;
401: }
402:
403: /**
404: * column isTimestamp: 93
405: *
406: * @return TODO: DOCUMENT ME!
407: */
408: public boolean isTimestamp() {
409: return this .typeEnum() == Types.TIMESTAMP;
410: }
411:
412: /**
413: * column isVarBinary: -3
414: *
415: * @return TODO: DOCUMENT ME!
416: */
417: public boolean isVarBinary() {
418: return this .typeEnum() == Types.VARBINARY;
419: }
420:
421: /**
422: * column isLongVarBinary: -4
423: *
424: * @return TODO: DOCUMENT ME!
425: */
426: public boolean isLongVarBinary() {
427: return this .typeEnum() == Types.LONGVARBINARY;
428: }
429:
430: /**
431: * unknown use
432: *
433: * @return TODO: DOCUMENT ME!
434: *
435: * @throws DataSetException TODO: DOCUMENT ME!
436: */
437: public String dbKonaMethod() throws DataSetException {
438: throw new DataSetException(
439: "Method not implemented: Unknown use!");
440: }
441:
442: /**
443: * unknown use
444: *
445: * @return TODO: DOCUMENT ME!
446: *
447: * @throws DataSetException TODO: DOCUMENT ME!
448: */
449: public String javaType() throws DataSetException {
450: throw new DataSetException(
451: "Method not implemented: Unknown use!");
452: }
453:
454: /**
455: * unknown use
456: *
457: * @return TODO: DOCUMENT ME!
458: *
459: * @throws DataSetException TODO: DOCUMENT ME!
460: */
461: public final String preparedStatemntBindMethod()
462: throws DataSetException {
463: throw new DataSetException(
464: "Method not implemented: Unknown use!");
465: }
466:
467: /**
468: * unknown use
469: *
470: * @return TODO: DOCUMENT ME!
471: *
472: * @throws DataSetException TODO: DOCUMENT ME!
473: */
474: public final String resultSetMethod() throws DataSetException {
475: throw new DataSetException(
476: "Method not implemented: Unknown use!");
477: }
478:
479: /**
480: * TODO: DOCUMENT ME!
481: *
482: * @return TODO: DOCUMENT ME!
483: */
484: public String getTableName() {
485: return tableName;
486: }
487: }
|