2
Copyright (C) 2002 MySQL AB
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
package com.mysql.jdbc;
21
import java.sql.SQLException;
22
import java.sql.Types;
26
* A ResultSetMetaData object can be used to find out about the types and
27
* properties of the columns in a ResultSet
29
* @see java.sql.ResultSetMetaData
30
* @author Mark Matthews
31
* @version $Id: ResultSetMetaData.java,v 1.12.2.3 2003/03/10 13:02:48 mmatthew Exp $
33
public class ResultSetMetaData implements java.sql.ResultSetMetaData {
37
* Initialise for a result with a tuple set and
38
* a field descriptor set
40
* @param fields the array of field descriptors
43
public ResultSetMetaData(Field[] fields) {
48
* Is the column automatically numbered (and thus read-only)
50
* MySQL Auto-increment columns are not read only,
51
* so to conform to the spec, this method returns false.
53
* @param column the first column is 1, the second is 2...
55
* @throws java.sql.SQLException if a database access error occurs
57
public boolean isAutoIncrement(int column) throws java.sql.SQLException {
58
Field f = getField(column);
60
return f.isAutoIncrement();
64
* Does a column's case matter? ASSUMPTION: Any field that is
65
* not obviously case insensitive is assumed to be case sensitive
67
* @param column the first column is 1, the second is 2...
69
* @throws java.sql.SQLException if a database access error occurs
71
public boolean isCaseSensitive(int column) throws java.sql.SQLException {
72
int sqlType = getField(column).getSQLType();
94
* What's a column's table's catalog name?
96
* @param column the first column is 1, the second is 2...
97
* @return catalog name, or "" if not applicable
98
* @throws java.sql.SQLException if a database access error occurs
100
public String getCatalogName(int column) throws java.sql.SQLException {
101
Field f = getField(column);
103
String database = f.getDatabaseName();
105
return (database == null) ? "" : database;
108
//--------------------------JDBC 2.0-----------------------------------
113
* <p>Return the fully qualified name of the Java class whose instances
114
* are manufactured if ResultSet.getObject() is called to retrieve a value
115
* from the column. ResultSet.getObject() may return a subClass of the
116
* class returned by this method.
118
* @param column the column number to retrieve information for
119
* @return the fully qualified name of the Java class whose instances
120
* are manufactured if ResultSet.getObject() is called to retrieve a value
123
* @throws SQLException if an error occurs
125
public String getColumnClassName(int column) throws SQLException {
126
Field f = getField(column);
128
switch (f.getSQLType()) {
130
return "java.lang.Boolean";
134
if (f.isUnsigned()) {
135
return "java.lang.Integer";
137
return "java.lang.Byte";
142
if (f.isUnsigned()) {
143
return "java.lang.Integer";
145
return "java.lang.Short";
150
if (f.isUnsigned()) {
151
return "java.lang.Long";
153
return "java.lang.Integer";
157
return "java.lang.Long";
161
return "java.math.BigDecimal";
165
return "java.lang.Float";
168
return "java.lang.Double";
172
case Types.LONGVARCHAR:
173
return "java.lang.String";
176
case Types.VARBINARY:
177
case Types.LONGVARBINARY:
180
return "java.lang.String";
181
} else if (!f.isBinary()) {
182
return "java.lang.String";
184
return "java.lang.Object";
188
return "java.sql.Date";
191
return "java.sql.Time";
193
case Types.TIMESTAMP:
194
return "java.sql.Timestamp";
197
return "java.lang.Object";
202
* Whats the number of columns in the ResultSet?
205
* @throws java.sql.SQLException if a database access error occurs
207
public int getColumnCount() throws java.sql.SQLException {
208
return fields.length;
212
* What is the column's normal maximum width in characters?
214
* @param column the first column is 1, the second is 2, etc.
215
* @return the maximum width
216
* @throws java.sql.SQLException if a database access error occurs
218
public int getColumnDisplaySize(int column) throws java.sql.SQLException {
219
return getField(column).getLength();
223
* What is the suggested column title for use in printouts and
226
* @param column the first column is 1, the second is 2, etc.
227
* @return the column label
228
* @throws java.sql.SQLException if a database access error occurs
230
public String getColumnLabel(int column) throws java.sql.SQLException {
231
return getColumnName(column);
235
* What's a column's name?
237
* @param column the first column is 1, the second is 2, etc.
238
* @return the column name
239
* @throws java.sql.SQLException if a databvase access error occurs
241
public String getColumnName(int column) throws java.sql.SQLException {
242
return getField(column).getName();
246
* What is a column's SQL Type? (java.sql.Type int)
248
* @param column the first column is 1, the second is 2, etc.
249
* @return the java.sql.Type value
250
* @throws java.sql.SQLException if a database access error occurs
251
* @see java.sql.Types
253
public int getColumnType(int column) throws java.sql.SQLException {
254
return getField(column).getSQLType();
258
* Whats is the column's data source specific type name?
260
* @param column the first column is 1, the second is 2, etc.
261
* @return the type name
262
* @throws java.sql.SQLException if a database access error occurs
264
public String getColumnTypeName(int column) throws java.sql.SQLException {
265
int mysqlType = getField(column).getMysqlType();
268
case MysqlDefs.FIELD_TYPE_DECIMAL:
271
case MysqlDefs.FIELD_TYPE_TINY:
274
case MysqlDefs.FIELD_TYPE_SHORT:
277
case MysqlDefs.FIELD_TYPE_LONG:
280
case MysqlDefs.FIELD_TYPE_FLOAT:
283
case MysqlDefs.FIELD_TYPE_DOUBLE:
286
case MysqlDefs.FIELD_TYPE_NULL:
289
case MysqlDefs.FIELD_TYPE_TIMESTAMP:
292
case MysqlDefs.FIELD_TYPE_LONGLONG:
295
case MysqlDefs.FIELD_TYPE_INT24:
298
case MysqlDefs.FIELD_TYPE_DATE:
301
case MysqlDefs.FIELD_TYPE_TIME:
304
case MysqlDefs.FIELD_TYPE_DATETIME:
307
case MysqlDefs.FIELD_TYPE_TINY_BLOB:
310
case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
313
case MysqlDefs.FIELD_TYPE_LONG_BLOB:
316
case MysqlDefs.FIELD_TYPE_BLOB:
318
if (getField(column).isBinary()) {
324
case MysqlDefs.FIELD_TYPE_VAR_STRING:
327
case MysqlDefs.FIELD_TYPE_STRING:
330
case MysqlDefs.FIELD_TYPE_ENUM:
333
case MysqlDefs.FIELD_TYPE_SET:
336
case MysqlDefs.FIELD_TYPE_YEAR:
345
* Is the column a cash value?
347
* @param column the first column is 1, the second is 2...
348
* @return true if its a cash column
349
* @throws java.sql.SQLException if a database access error occurs
351
public boolean isCurrency(int column) throws java.sql.SQLException {
356
* Will a write on this column definately succeed?
358
* @param column the first column is 1, the second is 2, etc..
360
* @throws java.sql.SQLException if a database access error occurs
362
public boolean isDefinitelyWritable(int column)
363
throws java.sql.SQLException {
364
return isWritable(column);
368
* Can you put a NULL in this column?
370
* @param column the first column is 1, the second is 2...
371
* @return one of the columnNullable values
372
* @throws java.sql.SQLException if a database access error occurs
374
public int isNullable(int column) throws java.sql.SQLException {
375
if (!getField(column).isNotNull()) {
376
return java.sql.ResultSetMetaData.columnNullable;
378
return java.sql.ResultSetMetaData.columnNoNulls;
383
* What is a column's number of decimal digits.
385
* @param column the first column is 1, the second is 2...
386
* @return the precision
387
* @throws java.sql.SQLException if a database access error occurs
389
public int getPrecision(int column) throws java.sql.SQLException {
390
Field f = getField(column);
392
if (isDecimalType(f.getSQLType())) {
393
if (f.getDecimals() > 0) {
394
return f.getLength() - 1 + f.getPrecisionAdjustFactor();
397
return f.getLength() + f.getPrecisionAdjustFactor();
404
* Is the column definitely not writable?
406
* @param column the first column is 1, the second is 2, etc.
408
* @throws java.sql.SQLException if a database access error occurs
410
public boolean isReadOnly(int column) throws java.sql.SQLException {
415
* What is a column's number of digits to the right of the
418
* @param column the first column is 1, the second is 2...
420
* @throws java.sql.SQLException if a database access error occurs
422
public int getScale(int column) throws java.sql.SQLException {
423
Field f = getField(column);
425
if (isDecimalType(f.getSQLType())) {
426
return f.getDecimals();
433
* What is a column's table's schema? This relies on us knowing
436
* The JDBC specification allows us to return "" if this is not
439
* @param column the first column is 1, the second is 2...
441
* @throws java.sql.SQLException if a database access error occurs
443
public String getSchemaName(int column) throws java.sql.SQLException {
448
* Can the column be used in a WHERE clause? Basically for
449
* this, I split the functions into two types: recognised
450
* types (which are always useable), and OTHER types (which
451
* may or may not be useable). The OTHER types, for now, I
452
* will assume they are useable. We should really query the
453
* catalog to see if they are useable.
455
* @param column the first column is 1, the second is 2...
456
* @return true if they can be used in a WHERE clause
457
* @throws java.sql.SQLException if a database access error occurs
459
public boolean isSearchable(int column) throws java.sql.SQLException {
464
* Is the column a signed number?
466
* @param column the first column is 1, the second is 2...
468
* @throws java.sql.SQLException if a database access error occurs
470
public boolean isSigned(int column) throws java.sql.SQLException {
471
Field f = getField(column);
472
int sqlType = f.getSQLType();
484
return !f.isUnsigned();
488
case Types.TIMESTAMP:
497
* Whats a column's table's name?
499
* @param column the first column is 1, the second is 2...
500
* @return column name, or "" if not applicable
501
* @throws java.sql.SQLException if a database access error occurs
503
public String getTableName(int column) throws java.sql.SQLException {
504
return getField(column).getTableName();
508
* Is it possible for a write on the column to succeed?
510
* @param column the first column is 1, the second is 2, etc.
512
* @throws java.sql.SQLException if a database access error occurs
514
public boolean isWritable(int column) throws java.sql.SQLException {
515
return !isReadOnly(column);
518
// *********************************************************************
520
// END OF PUBLIC INTERFACE
522
// *********************************************************************
525
* Returns the field instance for the given column index
527
* @param columnIndex the column number to retrieve a field instance for
528
* @return the field instance for the given column index
530
* @throws java.sql.SQLException if an error occurs
532
protected Field getField(int columnIndex) throws java.sql.SQLException {
533
if ((columnIndex < 1) || (columnIndex > fields.length)) {
534
throw new java.sql.SQLException("Column index out of range.",
538
return fields[columnIndex - 1];
542
* Checks if the SQL Type is a Decimal/Number Type
543
* @param type SQL Type
545
private static final boolean isDecimalType(int type) {