~ubuntu-branches/ubuntu/gutsy/libpgjava/gutsy

« back to all changes in this revision

Viewing changes to src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Vandyck
  • Date: 2005-04-21 14:25:11 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050421142511-wibh5vc31fkrorx7
Tags: 7.4.7-3
Built with sources...

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.postgresql.jdbc1;
 
2
 
 
3
 
 
4
import org.postgresql.core.Field;
 
5
import org.postgresql.util.PSQLException;
 
6
import org.postgresql.util.PSQLState;
 
7
import java.sql.SQLException;
 
8
import java.sql.Types;
 
9
import java.util.Vector;
 
10
 
 
11
public abstract class AbstractJdbc1ResultSetMetaData
 
12
{
 
13
 
 
14
        protected Vector rows;
 
15
        protected Field[] fields;
 
16
 
 
17
        /*
 
18
         *      Initialise for a result with a tuple set and
 
19
         *      a field descriptor set
 
20
         *
 
21
         * @param rows the Vector of rows returned by the ResultSet
 
22
         * @param fields the array of field descriptors
 
23
         */
 
24
        public AbstractJdbc1ResultSetMetaData(Vector rows, Field[] fields)
 
25
        {
 
26
                this.rows = rows;
 
27
                this.fields = fields;
 
28
        }
 
29
 
 
30
        /*
 
31
         * Whats the number of columns in the ResultSet?
 
32
         *
 
33
         * @return the number
 
34
         * @exception SQLException if a database access error occurs
 
35
         */
 
36
        public int getColumnCount() throws SQLException
 
37
        {
 
38
                return fields.length;
 
39
        }
 
40
 
 
41
        /*
 
42
         * Is the column automatically numbered (and thus read-only)
 
43
         * I believe that PostgreSQL does not support this feature.
 
44
         *
 
45
         * @param column the first column is 1, the second is 2...
 
46
         * @return true if so
 
47
         * @exception SQLException if a database access error occurs
 
48
         */
 
49
        public boolean isAutoIncrement(int column) throws SQLException
 
50
        {
 
51
                return false;
 
52
        }
 
53
 
 
54
        /*
 
55
         * Does a column's case matter? ASSUMPTION: Any field that is
 
56
         * not obviously case insensitive is assumed to be case sensitive
 
57
         *
 
58
         * @param column the first column is 1, the second is 2...
 
59
         * @return true if so
 
60
         * @exception SQLException if a database access error occurs
 
61
         */
 
62
        public boolean isCaseSensitive(int column) throws SQLException
 
63
        {
 
64
                int sql_type = getField(column).getSQLType();
 
65
 
 
66
                switch (sql_type)
 
67
                {
 
68
                        case Types.SMALLINT:
 
69
                        case Types.INTEGER:
 
70
                        case Types.FLOAT:
 
71
                        case Types.REAL:
 
72
                        case Types.DOUBLE:
 
73
                        case Types.DATE:
 
74
                        case Types.TIME:
 
75
                        case Types.TIMESTAMP:
 
76
                                return false;
 
77
                        default:
 
78
                                return true;
 
79
                }
 
80
        }
 
81
 
 
82
        /*
 
83
         * Can the column be used in a WHERE clause?  Basically for
 
84
         * this, I split the functions into two types: recognised
 
85
         * types (which are always useable), and OTHER types (which
 
86
         * may or may not be useable).  The OTHER types, for now, I
 
87
         * will assume they are useable.  We should really query the
 
88
         * catalog to see if they are useable.
 
89
         *
 
90
         * @param column the first column is 1, the second is 2...
 
91
         * @return true if they can be used in a WHERE clause
 
92
         * @exception SQLException if a database access error occurs
 
93
         */
 
94
        public boolean isSearchable(int column) throws SQLException
 
95
        {
 
96
                int sql_type = getField(column).getSQLType();
 
97
 
 
98
                // This switch is pointless, I know - but it is a set-up
 
99
                // for further expansion.
 
100
                switch (sql_type)
 
101
                {
 
102
                        case Types.OTHER:
 
103
                                return true;
 
104
                        default:
 
105
                                return true;
 
106
                }
 
107
        }
 
108
 
 
109
        /*
 
110
         * Is the column a cash value?  6.1 introduced the cash/money
 
111
         * type, which haven't been incorporated as of 970414, so I
 
112
         * just check the type name for both 'cash' and 'money'
 
113
         *
 
114
         * @param column the first column is 1, the second is 2...
 
115
         * @return true if its a cash column
 
116
         * @exception SQLException if a database access error occurs
 
117
         */
 
118
        public boolean isCurrency(int column) throws SQLException
 
119
        {
 
120
                String type_name = getField(column).getPGType();
 
121
 
 
122
                return type_name.equals("cash") || type_name.equals("money");
 
123
        }
 
124
 
 
125
        /*
 
126
         * Indicates the nullability of values in the designated column.
 
127
         *
 
128
         * @param column the first column is 1, the second is 2...
 
129
         * @return one of the columnNullable values
 
130
         * @exception SQLException if a database access error occurs
 
131
         */
 
132
        public int isNullable(int column) throws SQLException
 
133
        {
 
134
                /*
 
135
                 * TODO This needs a real implementation, taking into account columns
 
136
                 * defined with NOT NULL or PRIMARY KEY, CHECK constraints, views,
 
137
                 * functions etc.
 
138
                 */
 
139
                return java.sql.ResultSetMetaData.columnNullableUnknown;
 
140
        }
 
141
 
 
142
        /*
 
143
         * Is the column a signed number? In PostgreSQL, all numbers
 
144
         * are signed, so this is trivial.      However, strings are not
 
145
         * signed (duh!)
 
146
         *
 
147
         * @param column the first column is 1, the second is 2...
 
148
         * @return true if so
 
149
         * @exception SQLException if a database access error occurs
 
150
         */
 
151
        public boolean isSigned(int column) throws SQLException
 
152
        {
 
153
                int sql_type = getField(column).getSQLType();
 
154
 
 
155
                switch (sql_type)
 
156
                {
 
157
                        case Types.SMALLINT:
 
158
                        case Types.INTEGER:
 
159
                        case Types.FLOAT:
 
160
                        case Types.REAL:
 
161
                        case Types.DOUBLE:
 
162
                                return true;
 
163
                        case Types.DATE:
 
164
                        case Types.TIME:
 
165
                        case Types.TIMESTAMP:
 
166
                                return false;   // I don't know about these?
 
167
                        default:
 
168
                                return false;
 
169
                }
 
170
        }
 
171
 
 
172
        /*
 
173
         * What is the column's normal maximum width in characters?
 
174
         *
 
175
         * @param column the first column is 1, the second is 2, etc.
 
176
         * @return the maximum width
 
177
         * @exception SQLException if a database access error occurs
 
178
         */
 
179
        public int getColumnDisplaySize(int column) throws SQLException
 
180
        {
 
181
                Field f = getField(column);
 
182
                String type_name = f.getPGType();
 
183
                int typmod = f.getMod();
 
184
 
 
185
                // I looked at other JDBC implementations and couldn't find a consistent
 
186
                // interpretation of the "display size" for numeric values, so this is our's
 
187
                // FIXME: currently, only types with a SQL92 or SQL3 pendant are implemented - jens@jens.de
 
188
 
 
189
                // fixed length data types
 
190
                if (type_name.equals( "int2" ))
 
191
                        return 6;  // -32768 to +32768 (5 digits and a sign)
 
192
                if (type_name.equals( "int4" )
 
193
                                || type_name.equals( "oid" ))
 
194
                        return 11; // -2147483648 to +2147483647
 
195
                if (type_name.equals( "int8" ))
 
196
                        return 20; // -9223372036854775808 to +9223372036854775807
 
197
                if (type_name.equals( "money" ))
 
198
                        return 12; // MONEY = DECIMAL(9,2)
 
199
                if (type_name.equals( "float4" ))
 
200
                        return 11; // i checked it out ans wasn't able to produce more than 11 digits
 
201
                if (type_name.equals( "float8" ))
 
202
                        return 20; // dito, 20
 
203
                if (type_name.equals( "char" ))
 
204
                        return 1;
 
205
                if (type_name.equals( "bool" ))
 
206
                        return 1;
 
207
                if (type_name.equals( "date" ))
 
208
                        return 14; // "01/01/4713 BC" - "31/12/32767 AD"
 
209
                if (type_name.equals( "time" ))
 
210
                        return 8;  // 00:00:00-23:59:59
 
211
                if (type_name.equals( "timestamp" ))
 
212
                        return 22; // hhmmm ... the output looks like this: 1999-08-03 22:22:08+02
 
213
 
 
214
                // variable length fields
 
215
                typmod -= 4;
 
216
                if (type_name.equals( "bpchar" )
 
217
                                || type_name.equals( "varchar" ))
 
218
                        return typmod; // VARHDRSZ=sizeof(int32)=4
 
219
                if (type_name.equals( "numeric" ))
 
220
                        return ( (typmod >> 16) & 0xffff )
 
221
                                   + 1 + ( typmod & 0xffff ); // DECIMAL(p,s) = (p digits).(s digits)
 
222
 
 
223
                // if we don't know better
 
224
                return f.getLength();
 
225
        }
 
226
 
 
227
        /*
 
228
         * What is the suggested column title for use in printouts and
 
229
         * displays?  We suggest the ColumnName!
 
230
         *
 
231
         * @param column the first column is 1, the second is 2, etc.
 
232
         * @return the column label
 
233
         * @exception SQLException if a database access error occurs
 
234
         */
 
235
        public String getColumnLabel(int column) throws SQLException
 
236
        {
 
237
                return getColumnName(column);
 
238
        }
 
239
 
 
240
        /*
 
241
         * What's a column's name?
 
242
         *
 
243
         * @param column the first column is 1, the second is 2, etc.
 
244
         * @return the column name
 
245
         * @exception SQLException if a database access error occurs
 
246
         */
 
247
        public String getColumnName(int column) throws SQLException
 
248
        {
 
249
                Field f = getField(column);
 
250
                if (f != null)
 
251
                        return f.getName();
 
252
                return "field" + column;
 
253
        }
 
254
 
 
255
        /*
 
256
         * What is a column's table's schema?  This relies on us knowing
 
257
         * the table name....which I don't know how to do as yet.  The 
 
258
         * JDBC specification allows us to return "" if this is not
 
259
         * applicable.
 
260
         *
 
261
         * @param column the first column is 1, the second is 2...
 
262
         * @return the Schema
 
263
         * @exception SQLException if a database access error occurs
 
264
         */
 
265
        public String getSchemaName(int column) throws SQLException
 
266
        {
 
267
                return "";
 
268
        }
 
269
 
 
270
        /*
 
271
         * What is a column's number of decimal digits.
 
272
         *
 
273
         * @param column the first column is 1, the second is 2...
 
274
         * @return the precision
 
275
         * @exception SQLException if a database access error occurs
 
276
         */
 
277
        public int getPrecision(int column) throws SQLException
 
278
        {
 
279
                int sql_type = getField(column).getSQLType();
 
280
 
 
281
                switch (sql_type)
 
282
                {
 
283
                        case Types.SMALLINT:
 
284
                                return 5;
 
285
                        case Types.INTEGER:
 
286
                                return 10;
 
287
                        case Types.REAL:
 
288
                                return 8;
 
289
                        case Types.FLOAT:
 
290
                                return 16;
 
291
                        case Types.DOUBLE:
 
292
                                return 16;
 
293
                        case Types.VARCHAR:
 
294
                                return 0;
 
295
                        case Types.NUMERIC:
 
296
                                Field f = getField(column);
 
297
                                if (f != null)
 
298
                                        return ((0xFFFF0000)&f.getMod()) >> 16;
 
299
                                else
 
300
                                        return 0;
 
301
                        default:
 
302
                                return 0;
 
303
                }
 
304
        }
 
305
 
 
306
        /*
 
307
         * What is a column's number of digits to the right of the
 
308
         * decimal point?
 
309
         *
 
310
         * @param column the first column is 1, the second is 2...
 
311
         * @return the scale
 
312
         * @exception SQLException if a database access error occurs
 
313
         */
 
314
        public int getScale(int column) throws SQLException
 
315
        {
 
316
                int sql_type = getField(column).getSQLType();
 
317
 
 
318
                switch (sql_type)
 
319
                {
 
320
                        case Types.SMALLINT:
 
321
                                return 0;
 
322
                        case Types.INTEGER:
 
323
                                return 0;
 
324
                        case Types.REAL:
 
325
                                return 8;
 
326
                        case Types.FLOAT:
 
327
                                return 16;
 
328
                        case Types.DOUBLE:
 
329
                                return 16;
 
330
                        case Types.VARCHAR:
 
331
                                return 0;
 
332
                        case Types.NUMERIC:
 
333
                                Field f = getField(column);
 
334
                                if (f != null)
 
335
                                        return (((0x0000FFFF)&f.getMod()) - 4);
 
336
                                else
 
337
                                        return 0;
 
338
                        default:
 
339
                                return 0;
 
340
                }
 
341
        }
 
342
 
 
343
        /*
 
344
         * Whats a column's table's name?  How do I find this out?      Both
 
345
         * getSchemaName() and getCatalogName() rely on knowing the table
 
346
         * Name, so we need this before we can work on them.
 
347
         *
 
348
         * @param column the first column is 1, the second is 2...
 
349
         * @return column name, or "" if not applicable
 
350
         * @exception SQLException if a database access error occurs
 
351
         */
 
352
        public String getTableName(int column) throws SQLException
 
353
        {
 
354
                return "";
 
355
        }
 
356
 
 
357
        /*
 
358
         * What's a column's table's catalog name?  As with getSchemaName(),
 
359
         * we can say that if getTableName() returns n/a, then we can too -
 
360
         * otherwise, we need to work on it.
 
361
         *
 
362
         * @param column the first column is 1, the second is 2...
 
363
         * @return catalog name, or "" if not applicable
 
364
         * @exception SQLException if a database access error occurs
 
365
         */
 
366
        public String getCatalogName(int column) throws SQLException
 
367
        {
 
368
                return "";
 
369
        }
 
370
 
 
371
        /*
 
372
         * What is a column's SQL Type? (java.sql.Type int)
 
373
         *
 
374
         * @param column the first column is 1, the second is 2, etc.
 
375
         * @return the java.sql.Type value
 
376
         * @exception SQLException if a database access error occurs
 
377
         * @see org.postgresql.Field#getSQLType
 
378
         * @see java.sql.Types
 
379
         */
 
380
        public int getColumnType(int column) throws SQLException
 
381
        {
 
382
                return getField(column).getSQLType();
 
383
        }
 
384
 
 
385
        /*
 
386
         * Whats is the column's data source specific type name?
 
387
         *
 
388
         * @param column the first column is 1, the second is 2, etc.
 
389
         * @return the type name
 
390
         * @exception SQLException if a database access error occurs
 
391
         */
 
392
        public String getColumnTypeName(int column) throws SQLException
 
393
        {
 
394
                return getField(column).getPGType();
 
395
        }
 
396
 
 
397
        /*
 
398
         * Is the column definitely not writable?  In reality, we would
 
399
         * have to check the GRANT/REVOKE stuff for this to be effective,
 
400
         * and I haven't really looked into that yet, so this will get
 
401
         * re-visited.
 
402
         *
 
403
         * @param column the first column is 1, the second is 2, etc.
 
404
         * @return true if so
 
405
         * @exception SQLException if a database access error occurs
 
406
         */
 
407
        public boolean isReadOnly(int column) throws SQLException
 
408
        {
 
409
                return false;
 
410
        }
 
411
 
 
412
        /*
 
413
         * Is it possible for a write on the column to succeed?  Again, we
 
414
         * would in reality have to check the GRANT/REVOKE stuff, which
 
415
         * I haven't worked with as yet.  However, if it isn't ReadOnly, then
 
416
         * it is obviously writable.
 
417
         *
 
418
         * @param column the first column is 1, the second is 2, etc.
 
419
         * @return true if so
 
420
         * @exception SQLException if a database access error occurs
 
421
         */
 
422
        public boolean isWritable(int column) throws SQLException
 
423
        {
 
424
                return !isReadOnly(column);
 
425
        }
 
426
 
 
427
        /*
 
428
         * Will a write on this column definately succeed?      Hmmm...this
 
429
         * is a bad one, since the two preceding functions have not been
 
430
         * really defined.      I cannot tell is the short answer.      I thus
 
431
         * return isWritable() just to give us an idea.
 
432
         *
 
433
         * @param column the first column is 1, the second is 2, etc..
 
434
         * @return true if so
 
435
         * @exception SQLException if a database access error occurs
 
436
         */
 
437
        public boolean isDefinitelyWritable(int column) throws SQLException
 
438
        {
 
439
                return false;
 
440
        }
 
441
 
 
442
        // ********************************************************
 
443
        //      END OF PUBLIC INTERFACE
 
444
        // ********************************************************
 
445
 
 
446
        /*
 
447
         * For several routines in this package, we need to convert
 
448
         * a columnIndex into a Field[] descriptor.  Rather than do
 
449
         * the same code several times, here it is.
 
450
         *
 
451
         * @param columnIndex the first column is 1, the second is 2...
 
452
         * @return the Field description
 
453
         * @exception SQLException if a database access error occurs
 
454
         */
 
455
        private Field getField(int columnIndex) throws SQLException
 
456
        {
 
457
                if (columnIndex < 1 || columnIndex > fields.length)
 
458
                        throw new PSQLException("postgresql.res.colrange", PSQLState.INVALID_PARAMETER_VALUE);
 
459
                return fields[columnIndex - 1];
 
460
        }
 
461
}
 
462