1 //
2 // Copyright 1998 CDS Networks, Inc., Medford Oregon
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 1. Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // 3. All advertising materials mentioning features or use of this software
14 // must display the following acknowledgement:
15 // This product includes software developed by CDS Networks, Inc.
16 // 4. The name of CDS Networks, Inc. may not be used to endorse or promote
17 // products derived from this software without specific prior
18 // written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND
21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 // ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE
24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 // SUCH DAMAGE.
31 //
32
33
34 package com.internetcds.jdbc.tds;
35
36
37
38 import java.sql.*;
39
40
41 /***
42 * This class provides information about the database as a whole.
43 *
44 * <P>Many of the methods here return lists of information in ResultSets.
45 * You can use the normal ResultSet methods such as getString and getInt
46 * to retrieve the data from these ResultSets. If a given form of
47 * metadata is not available, these methods should throw a SQLException.
48 *
49 * <P>Some of these methods take arguments that are String patterns. These
50 * arguments all have names such as fooPattern. Within a pattern String, "%"
51 * means match any substring of 0 or more characters, and "_" means match
52 * any one character. Only metadata entries matching the search pattern
53 * are returned. If a search pattern argument is set to a null ref, it means
54 * that argument's criteria should be dropped from the search.
55 *
56 * <P>A SQLException will be thrown if a driver does not support a meta
57 * data method. In the case of methods that return a ResultSet,
58 * either a ResultSet (which may be empty) is returned or a
59 * SQLException is thrown.
60 *
61 * @author Craig Spannring
62 * @author The FreeTDS project
63 * @version $Id: DatabaseMetaData.html,v 1.1 2003/05/12 16:19:44 sinisa Exp $
64 *
65 */
66 public class DatabaseMetaData implements java.sql.DatabaseMetaData
67 {
68 public static final String cvsVersion = "$Id: DatabaseMetaData.html,v 1.1 2003/05/12 16:19:44 sinisa Exp $";
69
70 final boolean verbose = true;
71
72
73 /***
74 * PROCEDURE_TYPE - May return a result.
75 */
76 final int procedureResultUnknown = 0;
77 /***
78 * PROCEDURE_TYPE - Does not return a result.
79 */
80 final int procedureNoResult = 1;
81 /***
82 * PROCEDURE_TYPE - Returns a result.
83 */
84 final int procedureReturnsResult = 2;
85
86 /***
87 * COLUMN_TYPE - nobody knows.
88 */
89 final int procedureColumnUnknown = 0;
90
91 /***
92 * COLUMN_TYPE - IN parameter.
93 */
94 final int procedureColumnIn = 1;
95
96 /***
97 * COLUMN_TYPE - INOUT parameter.
98 */
99 final int procedureColumnInOut = 2;
100
101 /***
102 * COLUMN_TYPE - OUT parameter.
103 */
104 final int procedureColumnOut = 4;
105 /***
106 * COLUMN_TYPE - procedure return value.
107 */
108 final int procedureColumnReturn = 5;
109
110 /***
111 * COLUMN_TYPE - result column in ResultSet.
112 */
113 final int procedureColumnResult = 3;
114
115 /***
116 * TYPE NULLABLE - does not allow NULL values.
117 */
118 final int procedureNoNulls = 0;
119
120 /***
121 * TYPE NULLABLE - allows NULL values.
122 */
123 final int procedureNullable = 1;
124
125 /***
126 * TYPE NULLABLE - nullability unknown.
127 */
128 final int procedureNullableUnknown = 2;
129
130
131 /***
132 * COLUMN NULLABLE - might not allow NULL values.
133 */
134 final int columnNoNulls = 0;
135
136 /***
137 * COLUMN NULLABLE - definitely allows NULL values.
138 */
139 final int columnNullable = 1;
140
141 /***
142 * COLUMN NULLABLE - nullability unknown.
143 */
144 final int columnNullableUnknown = 2;
145
146 /***
147 * BEST ROW SCOPE - very temporary, while using row.
148 */
149 final int bestRowTemporary = 0;
150
151 /***
152 * BEST ROW SCOPE - valid for remainder of current transaction.
153 */
154 final int bestRowTransaction = 1;
155
156 /***
157 * BEST ROW SCOPE - valid for remainder of current session.
158 */
159 final int bestRowSession = 2;
160
161 /***
162 * BEST ROW PSEUDO_COLUMN - may or may not be pseudo column.
163 */
164 final int bestRowUnknown = 0;
165
166 /***
167 * BEST ROW PSEUDO_COLUMN - is NOT a pseudo column.
168 */
169 final int bestRowNotPseudo = 1;
170
171 /***
172 * BEST ROW PSEUDO_COLUMN - is a pseudo column.
173 */
174 final int bestRowPseudo = 2;
175
176 /***
177 * VERSION COLUMNS PSEUDO_COLUMN - may or may not be pseudo column.
178 */
179 final int versionColumnUnknown = 0;
180
181 /***
182 * VERSION COLUMNS PSEUDO_COLUMN - is NOT a pseudo column.
183 */
184 final int versionColumnNotPseudo = 1;
185
186 /***
187 * VERSION COLUMNS PSEUDO_COLUMN - is a pseudo column.
188 */
189 final int versionColumnPseudo = 2;
190
191 /***
192 * IMPORT KEY UPDATE_RULE and DELETE_RULE - for update, change
193 * imported key to agree with primary key update; for delete,
194 * delete rows that import a deleted key.
195 */
196 final int importedKeyCascade = 0;
197
198 /***
199 * IMPORT KEY UPDATE_RULE and DELETE_RULE - do not allow update or
200 * delete of primary key if it has been imported.
201 */
202 final int importedKeyRestrict = 1;
203
204 /***
205 * IMPORT KEY UPDATE_RULE and DELETE_RULE - change imported key to
206 * NULL if its primary key has been updated or deleted.
207 */
208 final int importedKeySetNull = 2;
209
210 /***
211 * IMPORT KEY UPDATE_RULE and DELETE_RULE - do not allow update or
212 * delete of primary key if it has been imported.
213 */
214 final int importedKeyNoAction = 3;
215
216 /***
217 * IMPORT KEY UPDATE_RULE and DELETE_RULE - change imported key to
218 * default values if its primary key has been updated or deleted.
219 */
220 final int importedKeySetDefault = 4;
221
222 /***
223 * IMPORT KEY DEFERRABILITY - see SQL92 for definition
224 */
225 final int importedKeyInitiallyDeferred = 5;
226
227 /***
228 * IMPORT KEY DEFERRABILITY - see SQL92 for definition
229 */
230 final int importedKeyInitiallyImmediate = 6;
231
232 /***
233 * IMPORT KEY DEFERRABILITY - see SQL92 for definition
234 */
235 final int importedKeyNotDeferrable = 7;
236
237 /***
238 * TYPE NULLABLE - does not allow NULL values.
239 */
240 final int typeNoNulls = 0;
241
242 /***
243 * TYPE NULLABLE - allows NULL values.
244 */
245 final int typeNullable = 1;
246
247 /***
248 * TYPE NULLABLE - nullability unknown.
249 */
250 final int typeNullableUnknown = 2;
251
252 /***
253 * TYPE INFO SEARCHABLE - No support.
254 */
255 final int typePredNone = 0;
256
257 /***
258 * TYPE INFO SEARCHABLE - Only supported with WHERE .. LIKE.
259 */
260 final int typePredChar = 1;
261
262 /***
263 * TYPE INFO SEARCHABLE - Supported except for WHERE .. LIKE.
264 */
265 final int typePredBasic = 2;
266
267 /***
268 * TYPE INFO SEARCHABLE - Supported for all WHERE ...
269 */
270 final int typeSearchable = 3;
271
272 /***
273 * INDEX INFO TYPE - this identifies table statistics that are
274 * returned in conjuction with a table's index descriptions
275 */
276 final short tableIndexStatistic = 0;
277
278 /***
279 * INDEX INFO TYPE - this identifies a clustered index
280 */
281 final short tableIndexClustered = 1;
282
283 /***
284 * INDEX INFO TYPE - this identifies a hashed index
285 */
286 final short tableIndexHashed = 2;
287
288 /***
289 * INDEX INFO TYPE - this identifies some other form of index
290 */
291 final short tableIndexOther = 3;
292
293
294 //
295 // now for the internal data needed by this implemention.
296 //
297 Tds tds;
298
299
300
301
302 java.sql.Connection connection;
303
304
305 private void debugPrintln(String s)
306 {
307 if (verbose)
308 {
309 System.out.println(s);
310 }
311 }
312
313 private void debugPrint(String s)
314 {
315 if (verbose)
316 {
317 System.out.print(s);
318 }
319 }
320
321
322 private void NotImplemented() throws SQLException
323 {
324 try
325 {
326 throw new SQLException("Not implemented");
327 }
328 catch (SQLException e)
329 {
330 e.printStackTrace();
331 }
332 throw new SQLException("Not implemented");
333 }
334
335
336 public DatabaseMetaData(
337 Object connection_,
338 Tds tds_)
339 {
340 connection = (java.sql.Connection)connection_;
341 tds = tds_;
342 }
343
344
345 //----------------------------------------------------------------------
346 // First, a variety of minor information about the target database.
347
348 /***
349 * Can all the procedures returned by getProcedures be called by the
350 * current user?
351 *
352 * @return true if so
353 * @exception SQLException if a database-access error occurs.
354 */
355 public boolean allProceduresAreCallable() throws SQLException
356 {
357 // XXX Need to check for Sybase
358
359 return true; // per "Programming ODBC for SQLServer" Appendix A
360 }
361
362
363 /***
364 * Can all the tables returned by getTable be SELECTed by the
365 * current user?
366 *
367 * @return true if so
368 * @exception SQLException if a database-access error occurs.
369 */
370 public boolean allTablesAreSelectable() throws SQLException
371 {
372 // XXX Need to check for Sybase
373
374 // XXX This is dependent on the way we are implementing getTables()
375 // it may change in the future.
376 return false;
377 }
378
379
380 /***
381 * Does a data definition statement within a transaction force the
382 * transaction to commit?
383 *
384 * @return true if so
385 * @exception SQLException if a database-access error occurs.
386 */
387 public boolean dataDefinitionCausesTransactionCommit()
388 throws SQLException
389 {
390 NotImplemented(); return false;
391 }
392
393
394 /***
395 * Is a data definition statement within a transaction ignored?
396 *
397 * @return true if so
398 * @exception SQLException if a database-access error occurs.
399 */
400 public boolean dataDefinitionIgnoredInTransactions()
401 throws SQLException
402 {
403 NotImplemented(); return false;
404 }
405
406
407
408 /***
409 * Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
410 * blobs?
411 *
412 * @return true if so
413 * @exception SQLException if a database-access error occurs.
414 */
415 public boolean doesMaxRowSizeIncludeBlobs() throws SQLException
416 {
417 return false;
418 }
419
420
421
422 /***
423 * Get a description of a table's optimal set of columns that
424 * uniquely identifies a row. They are ordered by SCOPE.
425 *
426 * <P>Each column description has the following columns:
427 * <OL>
428 * <LI><B>SCOPE</B> short => actual scope of result
429 * <UL>
430 * <LI> bestRowTemporary - very temporary, while using row
431 * <LI> bestRowTransaction - valid for remainder of current transaction
432 * <LI> bestRowSession - valid for remainder of current session
433 * </UL>
434 * <LI><B>COLUMN_NAME</B> String => column name
435 * <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
436 * <LI><B>TYPE_NAME</B> String => Data source dependent type name
437 * <LI><B>COLUMN_SIZE</B> int => precision
438 * <LI><B>BUFFER_LENGTH</B> int => not used
439 * <LI><B>DECIMAL_DIGITS</B> short => scale
440 * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
441 * like an Oracle ROWID
442 * <UL>
443 * <LI> bestRowUnknown - may or may not be pseudo column
444 * <LI> bestRowNotPseudo - is NOT a pseudo column
445 * <LI> bestRowPseudo - is a pseudo column
446 * </UL>
447 * </OL>
448 *
449 * @param catalog a catalog name; "" retrieves those without a
450 * catalog; null means drop catalog name from the selection criteria
451 * @param schema a schema name; "" retrieves those without a schema
452 * @param table a table name
453 * @param scope the scope of interest; use same values as SCOPE
454 * @param nullable include columns that are nullable?
455 * @return ResultSet - each row is a column description
456 * @exception SQLException if a database-access error occurs.
457 */
458 public java.sql.ResultSet getBestRowIdentifier(
459 String catalog,
460 String schema,
461 String table,
462 int scope,
463 boolean nullable)
464 throws SQLException
465 {
466 debugPrintln("Inside getBestRowIdentifier with catalog=|" + catalog
467 + "|, schema=|" + schema + "|, table=|" + table +"|, "
468 + " scope=" + scope + ", nullable=" + nullable);
469
470 NotImplemented(); return null;
471 }
472
473
474 /***
475 * Get the catalog names available in this database. The results
476 * are ordered by catalog name.
477 *
478 * <P>The catalog column is:
479 * <OL>
480 * <LI><B>TABLE_CAT</B> String => catalog name
481 * </OL>
482 *
483 * @return ResultSet - each row has a single String column that is a
484 * catalog name
485 * @exception SQLException if a database-access error occurs.
486 */
487 public java.sql.ResultSet getCatalogs()
488 throws SQLException
489 {
490 // XXX We should really clean up all these temporary tables.
491 String tmpName = "#t#" + UniqueId.getUniqueId();
492 final String sql =
493 " create table " + tmpName + " " +
494 " ( " +
495 " q char(30) not null, " +
496 " o char(30) null, " +
497 " n char(30) null, " +
498 " t char(30) null, " +
499 " r varchar(255) null " +
500 " ) " +
501 " " +
502 " insert into " + tmpName + " EXEC sp_tables ' ', ' ', '%', null " +
503 " " +
504 " select q from " + tmpName + " " +
505 "";
506 java.sql.Statement stmt = connection.createStatement();
507 java.sql.ResultSet rs;
508
509
510 if (stmt.execute(sql))
511 {
512 throw new SQLException("Internal error. Confused");
513 }
514
515
516 // Eat the data returned by the 'create table'
517 if (null != (rs = stmt.getResultSet()))
518 {
519 throw new SQLException("Internal error. Confused");
520 }
521
522 // Eat the data returned by the 'insert'
523 if (null != (rs = stmt.getResultSet()))
524 {
525 // RMK 2000-06-11: test t0051 gets the result set here.
526
527 // XXX we really need to figure out what the protocol is doing here.
528 // It appears that sometimes it returns an immediate result set
529 //and sometimes it doesn't.
530
531 return rs;
532 }
533
534 // now get the result set
535 if (null == (rs = stmt.getResultSet()))
536 {
537 throw new SQLException("Internal error. Confused");
538 }
539 return rs;
540 }
541
542
543
544 /***
545 * What's the separator between catalog and table name?
546 *
547 * @return the separator string
548 * @exception SQLException if a database-access error occurs.
549 */
550 public String getCatalogSeparator() throws SQLException
551 {
552 return ".";
553 }
554
555
556
557 /***
558 * What's the database vendor's preferred term for "catalog"?
559 *
560 * @return the vendor term
561 * @exception SQLException if a database-access error occurs.
562 */
563 public String getCatalogTerm() throws SQLException
564 {
565
566 return "database";
567 }
568
569
570
571 /***
572 * Get a description of the access rights for a table's columns.
573 *
574 * <P>Only privileges matching the column name criteria are
575 * returned. They are ordered by COLUMN_NAME and PRIVILEGE.
576 *
577 * <P>Each privilige description has the following columns:
578 * <OL>
579 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
580 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
581 * <LI><B>TABLE_NAME</B> String => table name
582 * <LI><B>COLUMN_NAME</B> String => column name
583 * <LI><B>GRANTOR</B> => grantor of access (may be null)
584 * <LI><B>GRANTEE</B> String => grantee of access
585 * <LI><B>PRIVILEGE</B> String => name of access (SELECT,
586 * INSERT, UPDATE, REFRENCES, ...)
587 * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
588 * to grant to others; "NO" if not; null if unknown
589 * </OL>
590 *
591 * @param catalog a catalog name; "" retrieves those without a
592 * catalog; null means drop catalog name from the selection criteria
593 * @param schema a schema name; "" retrieves those without a schema
594 * @param table a table name
595 * @param columnNamePattern a column name pattern
596 * @return ResultSet - each row is a column privilege description
597 * @exception SQLException if a database-access error occurs.
598 * @see #getSearchStringEscape
599 */
600 public java.sql.ResultSet getColumnPrivileges(String catalog, String schema,
601 String table, String columnNamePattern)
602 throws SQLException
603 {
604 NotImplemented(); return null;
605 }
606
607
608 /***
609 * Get a description of table columns available in a catalog.
610 *
611 * <P>Only column descriptions matching the catalog, schema, table
612 * and column name criteria are returned. They are ordered by
613 * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
614 *
615 * <P>Each column description has the following columns:
616 * <OL>
617 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
618 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
619 * <LI><B>TABLE_NAME</B> String => table name
620 * <LI><B>COLUMN_NAME</B> String => column name
621 * <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
622 * <LI><B>TYPE_NAME</B> String => Data source dependent type name
623 * <LI><B>COLUMN_SIZE</B> int => column size. For char or date
624 * types this is the maximum number of characters, for numeric or
625 * decimal types this is precision.
626 * <LI><B>BUFFER_LENGTH</B> is not used.
627 * <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
628 * <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
629 * <LI><B>NULLABLE</B> int => is NULL allowed?
630 * <UL>
631 * <LI> columnNoNulls - might not allow NULL values
632 * <LI> columnNullable - definitely allows NULL values
633 * <LI> columnNullableUnknown - nullability unknown
634 * </UL>
635 * <LI><B>REMARKS</B> String => comment describing column (may be null)
636 * <LI><B>COLUMN_DEF</B> String => default value (may be null)
637 * <LI><B>SQL_DATA_TYPE</B> int => unused
638 * <LI><B>SQL_DATETIME_SUB</B> int => unused
639 * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
640 * maximum number of bytes in the column
641 * <LI><B>ORDINAL_POSITION</B> int => index of column in table
642 * (starting at 1)
643 * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
644 * does not allow NULL values; "YES" means the column might
645 * allow NULL values. An empty string means nobody knows.
646 * </OL>
647 *
648 * @param catalog a catalog name; "" retrieves those without a
649 * catalog; null means drop catalog name from the selection criteria
650 * @param schemaPattern a schema name pattern; "" retrieves those
651 * without a schema
652 * @param tableNamePattern a table name pattern
653 * @param columnNamePattern a column name pattern
654 * @return ResultSet - each row is a column description
655 * @exception SQLException if a database-access error occurs.
656 * @see #getSearchStringEscape
657 */
658 public java.sql.ResultSet getColumns(String catalog, String schemaPattern,
659 String tableNamePattern, String columnNamePattern)
660 throws SQLException
661 {
662 debugPrintln("Inside of getColumn");
663 debugPrintln(" catalog is |" + catalog + "|");
664 debugPrintln(" schemaPattern is " + schemaPattern);
665 debugPrintln(" tableNamePattern is " + tableNamePattern);
666 debugPrintln(" columnNamePattern is " + columnNamePattern);
667
668 return getColumns_SQLServer65(catalog, schemaPattern,
669 tableNamePattern, columnNamePattern);
670 }
671
672
673 private java.sql.ResultSet getColumns_SQLServer65(
674 String catalog,
675 String schemaPattern,
676 String tableNamePattern,
677 String columnNamePattern)
678 throws SQLException
679 {
680 int i;
681
682 String sql = null;
683 java.sql.Statement tmpTableStmt = connection.createStatement();
684 String catalogCriteria;
685
686 // XXX We need to come up with something better than a global temporary
687 // table. It could cause problems if two people try to getColumns().
688 // (note- it is _unlikely_, not impossible)
689 String tmpTableName = "##t#" + UniqueId.getUniqueId();
690 String lookup = "#l#" + UniqueId.getUniqueId();
691
692 // create a temporary table
693 sql =
694 "create table " + tmpTableName + " ( " +
695 " TABLE_CAT char(32) null, " +
696 " TABLE_SCHEM char(32) null, " +
697 " TABLE_NAME char(32) null, " +
698 " COLUMN_NAME char(32) null, " +
699 " DATA_TYPE integer null, " +
700 " TYPE_NAME char(32) null, " +
701 " COLUMN_SIZE integer null, " +
702 " BUFFER_LENGTH integer null, " +
703 " DECIMAL_DIGITS integer null, " +
704 " NUM_PREC_RADIX integer null, " +
705 " NULLABLE integer null, " +
706 " REMARKS char(255) null, " +
707 " COLUMN_DEF char(255) null, " +
708 " SQL_DATA_TYPE integer null, " +
709 " SQL_DATETIME_SUB integer null, " +
710 " CHAR_OCTET_LENGTH integer null, " +
711 " ORDINAL_POSITION integer null, " +
712 " IS_NULLABLE char(3)) " +
713 "";
714 tmpTableStmt.execute(sql);
715
716 // Create a lookup table for mapping between native and jdbc types
717 sql =
718 "create table " + lookup + " ( " +
719 " native_type integer primary key, " +
720 " jdbc_type integer not null) ";
721 tmpTableStmt.execute(sql);
722
723 sql =
724 "insert into " + lookup + " values ( 31, 1111) " + // VOID
725 "insert into " + lookup + " values ( 34, 1111) " + // IMAGE
726 "insert into " + lookup + " values ( 35, -1) " + // TEXT
727 "insert into " + lookup + " values ( 37, -3) " + // VARBINARY
728 "insert into " + lookup + " values ( 38, 4) " + // INTN
729 "insert into " + lookup + " values ( 39, 12) " + // VARCHAR
730 "insert into " + lookup + " values ( 45, -2) " + // BINARY
731 "insert into " + lookup + " values ( 47, 1) " + // CHAR
732 "insert into " + lookup + " values ( 48, -6) " + // INT1
733 "insert into " + lookup + " values ( 50, -7) " + // BIT
734 "insert into " + lookup + " values ( 52, 5) " + // INT2
735 "insert into " + lookup + " values ( 56, 4) " + // INT4
736 "insert into " + lookup + " values ( 58, 93) " + // DATETIME4
737 "insert into " + lookup + " values ( 59, 7) " + // REAL
738 "insert into " + lookup + " values ( 60, 1111) " + // MONEY
739 "insert into " + lookup + " values ( 61, 93) " + // DATETIME
740 "insert into " + lookup + " values ( 62, 8) " + // FLT8
741 "insert into " + lookup + " values (106, 3) " + // DECIMAL
742 "insert into " + lookup + " values (108, 2) " + // NUMERIC
743 "insert into " + lookup + " values (109, 8) " + // FLTN
744 "insert into " + lookup + " values (110, 1111) " + // MONEYN
745 "insert into " + lookup + " values (111, 93) " + // DATETIMN
746 "insert into " + lookup + " values (112, 1111) " + // MONEY4
747 "";
748 tmpTableStmt.execute(sql);
749
750
751 // For each table in the system add its columns
752 // Note- We have to do them one at a time in case
753 // there are databases we don't have access to.
754 java.sql.ResultSet rs = getTables(null, "%", "%", null);
755 while(rs.next())
756 {
757 String cat = rs.getString(1);
758
759 // XXX Security risk. It 'might' be possible to create
760 // a catalog name that when inserted into this sql statement could
761 // do other commands.
762 sql =
763 "insert into " + tmpTableName + " " +
764 "select " +
765 " TABLE_CAT='" + cat + "', " +
766 " TABLE_SCHEM=USER_NAME(o.uid), " +
767 " TABLE_NAME=o.name, " +
768 " COLUMN_NAME=c.name, " +
769 " DATA_TYPE=l.jdbc_type, " +
770 " TYPE_NAME=t.name, " +
771 " COLUMN_SIZE=c.prec, " +
772 " BUFFER_LENGTH=0, " +
773 " DECIMAL_DIGITS=c.scale, " +
774 " NUM_PREC_RADIX=10, " +
775 " NULLABLE=convert(integer, " +
776 " convert(bit, c.status&8)), " +
777 " REMARKS=null, " +
778 " COLUMN_DEF=null, " +
779 " SQL_DATATYPE=c.type, " +
780 " SQL_DATETIME_SUB=0, " +
781 " CHAR_OCTET_LENGTH=c.length, " +
782 " ORDINAL_POSITION=c.colid, " +
783 " IS_NULLABLE= " +
784 " convert(char(3), rtrim(substring " +
785 " ('NO YES', " +
786 " (c.status&8)+1,3))) " +
787 "from " +
788 " " + cat + ".dbo.sysobjects o, " +
789 " " + cat + ".dbo.syscolumns c, " +
790 " " + lookup + " l, " +
791 " systypes t " +
792 "where o.type in ('V', 'U') and o.id=c.id " +
793 " and t.type=c.type " +
794 " and l.native_type=c.type " +
795 "";
796 // System.out.println("Executing \n" + sql + "\n");
797 try
798 {
799 tmpTableStmt.executeUpdate(sql);
800 }
801 catch (SQLException e)
802 {
803
804 }
805 }
806 rs.close();
807
808
809 if (catalog == null)
810 {
811 catalog = "";
812 catalogCriteria = " (TABLE_CAT like '%' or TABLE_CAT=?) ";
813 }
814 else
815 {
816 catalogCriteria = " TABLE_CAT=? ";
817 }
818
819 sql =
820 "select distinct * from " + tmpTableName + " where " +
821 catalogCriteria + " and " +
822 " TABLE_SCHEM like ? and TABLE_NAME like ? and " +
823 " COLUMN_NAME like ? " +
824 "order by TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION " ;
825
826 System.out.println("The query is \n" + sql);
827
828 java.sql.PreparedStatement ps = connection.prepareStatement(sql);
829
830 ps.setString(1, catalog);
831 ps.setString(2, schemaPattern);
832 ps.setString(3, tableNamePattern);
833 ps.setString(4, columnNamePattern);
834 rs = ps.executeQuery();
835
836 // We need to do something about deleting the global temporary table
837 tmpTableStmt.close();
838
839 return rs;
840 }
841
842
843 /***
844 * Get a description of the foreign key columns in the foreign key
845 * table that reference the primary key columns of the primary key
846 * table (describe how one table imports another's key.) This
847 * should normally return a single foreign key/primary key pair
848 * (most tables only import a foreign key from a table once.) They
849 * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
850 * KEY_SEQ.
851 *
852 * <P>Each foreign key column description has the following columns:
853 * <OL>
854 * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
855 * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
856 * <LI><B>PKTABLE_NAME</B> String => primary key table name
857 * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
858 * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
859 * being exported (may be null)
860 * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
861 * being exported (may be null)
862 * <LI><B>FKTABLE_NAME</B> String => foreign key table name
863 * being exported
864 * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
865 * being exported
866 * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
867 * <LI><B>UPDATE_RULE</B> short => What happens to
868 * foreign key when primary is updated:
869 * <UL>
870 * <LI> importedNoAction - do not allow update of primary
871 * key if it has been imported
872 * <LI> importedKeyCascade - change imported key to agree
873 * with primary key update
874 * <LI> importedKeySetNull - change imported key to NULL if
875 * its primary key has been updated
876 * <LI> importedKeySetDefault - change imported key to default values
877 * if its primary key has been updated
878 * <LI> importedKeyRestrict - same as importedKeyNoAction
879 * (for ODBC 2.x compatibility)
880 * </UL>
881 * <LI><B>DELETE_RULE</B> short => What happens to
882 * the foreign key when primary is deleted.
883 * <UL>
884 * <LI> importedKeyNoAction - do not allow delete of primary
885 * key if it has been imported
886 * <LI> importedKeyCascade - delete rows that import a deleted key
887 * <LI> importedKeySetNull - change imported key to NULL if
888 * its primary key has been deleted
889 * <LI> importedKeyRestrict - same as importedKeyNoAction
890 * (for ODBC 2.x compatibility)
891 * <LI> importedKeySetDefault - change imported key to default if
892 * its primary key has been deleted
893 * </UL>
894 * <LI><B>FK_NAME</B> String => foreign key name (may be null)
895 * <LI><B>PK_NAME</B> String => primary key name (may be null)
896 * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
897 * constraints be deferred until commit
898 * <UL>
899 * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
900 * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
901 * <LI> importedKeyNotDeferrable - see SQL92 for definition
902 * </UL>
903 * </OL>
904 *
905 * @param primaryCatalog a catalog name; "" retrieves those without a
906 * catalog; null means drop catalog name from the selection criteria
907 * @param primarySchema a schema name pattern; "" retrieves those
908 * without a schema
909 * @param primaryTable the table name that exports the key
910 * @param foreignCatalog a catalog name; "" retrieves those without a
911 * catalog; null means drop catalog name from the selection criteria
912 * @param foreignSchema a schema name pattern; "" retrieves those
913 * without a schema
914 * @param foreignTable the table name that imports the key
915 * @return ResultSet - each row is a foreign key column description
916 * @exception SQLException if a database-access error occurs.
917 * @see #getImportedKeys
918 */
919 public java.sql.ResultSet getCrossReference(
920 String primaryCatalog, String primarySchema, String primaryTable,
921 String foreignCatalog, String foreignSchema, String foreignTable
922 ) throws SQLException
923 {
924 NotImplemented(); return null;
925 }
926
927
928 /***
929 * What's the name of this database product?
930 *
931 * @return database product name
932 * @exception SQLException if a database-access error occurs.
933 */
934 public String getDatabaseProductName() throws SQLException
935 {
936 return tds.getDatabaseProductName();
937 }
938
939
940 /***
941 * What's the version of this database product?
942 *
943 * @return database version
944 * @exception SQLException if a database-access error occurs.
945 */
946 public String getDatabaseProductVersion() throws SQLException
947 {
948 return tds.getDatabaseProductVersion();
949 }
950
951
952 //----------------------------------------------------------------------
953
954 /***
955 * What's the database's default transaction isolation level? The
956 * values are defined in java.sql.Connection.
957 *
958 * @return the default isolation level
959 * @exception SQLException if a database-access error occurs.
960 * @see Connection
961 */
962 public int getDefaultTransactionIsolation() throws SQLException
963 {
964 // XXX need to check this for Sybase
965 return Connection.TRANSACTION_READ_COMMITTED;
966 }
967
968
969 /***
970 * What's this JDBC driver's major version number?
971 *
972 * @return JDBC driver major version
973 */
974 public int getDriverMajorVersion()
975 {
976 return DriverVersion.getDriverMajorVersion();
977 }
978
979
980 /***
981 * What's this JDBC driver's minor version number?
982 *
983 * @return JDBC driver minor version number
984 */
985 public int getDriverMinorVersion()
986 {
987 return DriverVersion.getDriverMinorVersion();
988 }
989
990
991 /***
992 * What's the name of this JDBC driver?
993 *
994 * @return JDBC driver name
995 * @exception SQLException if a database-access error occurs.
996 */
997 public String getDriverName() throws SQLException
998 {
999 return "InternetCDS Type 4 JDBC driver for MS SQLServer";
1000 }
1001
1002
1003 /***
1004 * What's the version of this JDBC driver?
1005 *
1006 * @return JDBC driver version
1007 * @exception SQLException if a database-access error occurs.
1008 */
1009 public String getDriverVersion() throws SQLException
1010 {
1011 return getDriverMajorVersion() + "." + getDriverMinorVersion();
1012 }
1013
1014
1015 /***
1016 * Get a description of the foreign key columns that reference a
1017 * table's primary key columns (the foreign keys exported by a
1018 * table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
1019 * FKTABLE_NAME, and KEY_SEQ.
1020 *
1021 * <P>Each foreign key column description has the following columns:
1022 * <OL>
1023 * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
1024 * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
1025 * <LI><B>PKTABLE_NAME</B> String => primary key table name
1026 * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
1027 * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
1028 * being exported (may be null)
1029 * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
1030 * being exported (may be null)
1031 * <LI><B>FKTABLE_NAME</B> String => foreign key table name
1032 * being exported
1033 * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
1034 * being exported
1035 * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
1036 * <LI><B>UPDATE_RULE</B> short => What happens to
1037 * foreign key when primary is updated:
1038 * <UL>
1039 * <LI> importedNoAction - do not allow update of primary
1040 * key if it has been imported
1041 * <LI> importedKeyCascade - change imported key to agree
1042 * with primary key update
1043 * <LI> importedKeySetNull - change imported key to NULL if
1044 * its primary key has been updated
1045 * <LI> importedKeySetDefault - change imported key to default values
1046 * if its primary key has been updated
1047 * <LI> importedKeyRestrict - same as importedKeyNoAction
1048 * (for ODBC 2.x compatibility)
1049 * </UL>
1050 * <LI><B>DELETE_RULE</B> short => What happens to
1051 * the foreign key when primary is deleted.
1052 * <UL>
1053 * <LI> importedKeyNoAction - do not allow delete of primary
1054 * key if it has been imported
1055 * <LI> importedKeyCascade - delete rows that import a deleted key
1056 * <LI> importedKeySetNull - change imported key to NULL if
1057 * its primary key has been deleted
1058 * <LI> importedKeyRestrict - same as importedKeyNoAction
1059 * (for ODBC 2.x compatibility)
1060 * <LI> importedKeySetDefault - change imported key to default if
1061 * its primary key has been deleted
1062 * </UL>
1063 * <LI><B>FK_NAME</B> String => foreign key name (may be null)
1064 * <LI><B>PK_NAME</B> String => primary key name (may be null)
1065 * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
1066 * constraints be deferred until commit
1067 * <UL>
1068 * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
1069 * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
1070 * <LI> importedKeyNotDeferrable - see SQL92 for definition
1071 * </UL>
1072 * </OL>
1073 *
1074 * @param catalog a catalog name; "" retrieves those without a
1075 * catalog; null means drop catalog name from the selection criteria
1076 * @param schema a schema name pattern; "" retrieves those
1077 * without a schema
1078 * @param table a table name
1079 * @return ResultSet - each row is a foreign key column description
1080 * @exception SQLException if a database-access error occurs.
1081 * @see #getImportedKeys
1082 */
1083 public java.sql.ResultSet getExportedKeys(String catalog, String schema,
1084 String table) throws SQLException
1085 {
1086 NotImplemented(); return null;
1087 }
1088
1089
1090 /***
1091 * Get all the "extra" characters that can be used in unquoted
1092 * identifier names (those beyond a-z, A-Z, 0-9 and _).
1093 *
1094 * @return the string containing the extra characters
1095 * @exception SQLException if a database-access error occurs.
1096 */
1097 public String getExtraNameCharacters() throws SQLException
1098 {
1099 return "#$";
1100 }
1101
1102
1103 /***
1104 * What's the string used to quote SQL identifiers?
1105 * This returns a space " " if identifier quoting isn't supported.
1106 *
1107 * A JDBC-Compliant driver always uses a double quote character.
1108 *
1109 * @return the quoting string
1110 * @exception SQLException if a database-access error occurs.
1111 */
1112 public String getIdentifierQuoteString() throws SQLException
1113 {
1114 return "\"";
1115 }
1116
1117
1118 /***
1119 * Get a description of the primary key columns that are
1120 * referenced by a table's foreign key columns (the primary keys
1121 * imported by a table). They are ordered by PKTABLE_CAT,
1122 * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
1123 *
1124 * <P>Each primary key column description has the following columns:
1125 * <OL>
1126 * <LI><B>PKTABLE_CAT</B> String => primary key table catalog
1127 * being imported (may be null)
1128 * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
1129 * being imported (may be null)
1130 * <LI><B>PKTABLE_NAME</B> String => primary key table name
1131 * being imported
1132 * <LI><B>PKCOLUMN_NAME</B> String => primary key column name
1133 * being imported
1134 * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
1135 * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
1136 * <LI><B>FKTABLE_NAME</B> String => foreign key table name
1137 * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
1138 * <LI><B>KEY_SEQ</B> short => sequence number within foreign key
1139 * <LI><B>UPDATE_RULE</B> short => What happens to
1140 * foreign key when primary is updated:
1141 * <UL>
1142 * <LI> importedNoAction - do not allow update of primary
1143 * key if it has been imported
1144 * <LI> importedKeyCascade - change imported key to agree
1145 * with primary key update
1146 * <LI> importedKeySetNull - change imported key to NULL if
1147 * its primary key has been updated
1148 * <LI> importedKeySetDefault - change imported key to default values
1149 * if its primary key has been updated
1150 * <LI> importedKeyRestrict - same as importedKeyNoAction
1151 * (for ODBC 2.x compatibility)
1152 * </UL>
1153 * <LI><B>DELETE_RULE</B> short => What happens to
1154 * the foreign key when primary is deleted.
1155 * <UL>
1156 * <LI> importedKeyNoAction - do not allow delete of primary
1157 * key if it has been imported
1158 * <LI> importedKeyCascade - delete rows that import a deleted key
1159 * <LI> importedKeySetNull - change imported key to NULL if
1160 * its primary key has been deleted
1161 * <LI> importedKeyRestrict - same as importedKeyNoAction
1162 * (for ODBC 2.x compatibility)
1163 * <LI> importedKeySetDefault - change imported key to default if
1164 * its primary key has been deleted
1165 * </UL>
1166 * <LI><B>FK_NAME</B> String => foreign key name (may be null)
1167 * <LI><B>PK_NAME</B> String => primary key name (may be null)
1168 * <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
1169 * constraints be deferred until commit
1170 * <UL>
1171 * <LI> importedKeyInitiallyDeferred - see SQL92 for definition
1172 * <LI> importedKeyInitiallyImmediate - see SQL92 for definition
1173 * <LI> importedKeyNotDeferrable - see SQL92 for definition
1174 * </UL>
1175 * </OL>
1176 *
1177 * @param catalog a catalog name; "" retrieves those without a
1178 * catalog; null means drop catalog name from the selection criteria
1179 * @param schema a schema name pattern; "" retrieves those
1180 * without a schema
1181 * @param table a table name
1182 * @return ResultSet - each row is a primary key column description
1183 * @exception SQLException if a database-access error occurs.
1184 * @see #getExportedKeys
1185 */
1186 public java.sql.ResultSet getImportedKeys(String catalog, String schema,
1187 String table) throws SQLException
1188 {
1189 NotImplemented(); return null;
1190 }
1191
1192
1193 /***
1194 * Get a description of a table's indices and statistics. They are
1195 * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
1196 *
1197 * <P>Each index column description has the following columns:
1198 * <OL>
1199 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1200 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1201 * <LI><B>TABLE_NAME</B> String => table name
1202 * <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
1203 * false when TYPE is tableIndexStatistic
1204 * <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
1205 * null when TYPE is tableIndexStatistic
1206 * <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
1207 * tableIndexStatistic
1208 * <LI><B>TYPE</B> short => index type:
1209 * <UL>
1210 * <LI> tableIndexStatistic - this identifies table statistics that are
1211 * returned in conjuction with a table's index descriptions
1212 * <LI> tableIndexClustered - this is a clustered index
1213 * <LI> tableIndexHashed - this is a hashed index
1214 * <LI> tableIndexOther - this is some other style of index
1215 * </UL>
1216 * <LI><B>ORDINAL_POSITION</B> short => column sequence number
1217 * within index; zero when TYPE is tableIndexStatistic
1218 * <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
1219 * tableIndexStatistic
1220 * <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
1221 * "D" => descending, may be null if sort sequence is not supported;
1222 * null when TYPE is tableIndexStatistic
1223 * <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
1224 * this is the number of rows in the table; otherwise, it is the
1225 * number of unique values in the index.
1226 * <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
1227 * this is the number of pages used for the table, otherwise it
1228 * is the number of pages used for the current index.
1229 * <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
1230 * (may be null)
1231 * </OL>
1232 *
1233 * @param catalog a catalog name; "" retrieves those without a
1234 * catalog; null means drop catalog name from the selection criteria
1235 * @param schema a schema name pattern; "" retrieves those without a schema
1236 * @param table a table name
1237 * @param unique when true, return only indices for unique values;
1238 * when false, return indices regardless of whether unique or not
1239 * @param approximate when true, result is allowed to reflect approximate
1240 * or out of data values; when false, results are requested to be
1241 * accurate
1242 * @return ResultSet - each row is an index column description
1243 * @exception SQLException if a database-access error occurs.
1244 */
1245 public java.sql.ResultSet getIndexInfo(String catalog, String schema, String table,
1246 boolean unique, boolean approximate)
1247 throws SQLException
1248 {
1249 NotImplemented(); return null;
1250 }
1251
1252
1253 //----------------------------------------------------------------------
1254 // The following group of methods exposes various limitations
1255 // based on the target database with the current driver.
1256 // Unless otherwise specified, a result of zero means there is no
1257 // limit, or the limit is not known.
1258
1259 /***
1260 * How many hex characters can you have in an inline binary literal?
1261 *
1262 * @return max literal length
1263 * @exception SQLException if a database-access error occurs.
1264 */
1265 public int getMaxBinaryLiteralLength() throws SQLException
1266 {
1267 // XXX Need to check for Sybase and SQLServer 7.0
1268
1269 return 131072; // per "Programming ODBC for SQLServer" Appendix A
1270 }
1271
1272
1273 /***
1274 * What's the maximum length of a catalog name?
1275 *
1276 * @return max name length in bytes
1277 * @exception SQLException if a database-access error occurs.
1278 */
1279 public int getMaxCatalogNameLength() throws SQLException
1280 {
1281 NotImplemented(); return 0;
1282 }
1283
1284
1285 /***
1286 * What's the max length for a character literal?
1287 *
1288 * @return max literal length
1289 * @exception SQLException if a database-access error occurs.
1290 */
1291 public int getMaxCharLiteralLength() throws SQLException
1292 {
1293 // XXX Need to check for Sybase
1294
1295 return 131072; // per "Programming ODBC for SQLServer" Appendix A
1296 }
1297
1298
1299 /***
1300 * What's the limit on column name length?
1301 *
1302 * @return max literal length
1303 * @exception SQLException if a database-access error occurs.
1304 */
1305 public int getMaxColumnNameLength() throws SQLException
1306 {
1307 // XXX Need to check for Sybase
1308
1309 return 30; // per "Programming ODBC for SQLServer" Appendix A
1310 }
1311
1312
1313 /***
1314 * What's the maximum number of columns in a "GROUP BY" clause?
1315 *
1316 * @return max number of columns
1317 * @exception SQLException if a database-access error occurs.
1318 */
1319 public int getMaxColumnsInGroupBy() throws SQLException
1320 {
1321 // XXX Need to check for Sybase
1322
1323 return 16; // per "Programming ODBC for SQLServer" Appendix A
1324 }
1325
1326
1327 /***
1328 * What's the maximum number of columns allowed in an index?
1329 *
1330 * @return max columns
1331 * @exception SQLException if a database-access error occurs.
1332 */
1333 public int getMaxColumnsInIndex() throws SQLException
1334 {
1335 // XXX need to find out if this is still true for SYBASE
1336
1337 // per SQL Server Books Online "Administrator's Companion",
1338 // Part 1, Chapter 1.
1339 return 16;
1340 }
1341
1342
1343 /***
1344 * What's the maximum number of columns in an "ORDER BY" clause?
1345 *
1346 * @return max columns
1347 * @exception SQLException if a database-access error occurs.
1348 */
1349 public int getMaxColumnsInOrderBy() throws SQLException
1350 {
1351 // XXX Need to check for Sybase
1352
1353 return 16; // per "Programming ODBC for SQLServer" Appendix A
1354 }
1355
1356
1357 /***
1358 * What's the maximum number of columns in a "SELECT" list?
1359 *
1360 * @return max columns
1361 * @exception SQLException if a database-access error occurs.
1362 */
1363 public int getMaxColumnsInSelect() throws SQLException
1364 {
1365 // XXX Need to check for Sybase
1366
1367 return 4000; // per "Programming ODBC for SQLServer" Appendix A
1368 }
1369
1370
1371 /***
1372 * What's the maximum number of columns in a table?
1373 *
1374 * @return max columns
1375 * @exception SQLException if a database-access error occurs.
1376 */
1377 public int getMaxColumnsInTable() throws SQLException
1378 {
1379 // XXX How do we find this out for Sybase?
1380 return 250; // per "Programming ODBC for SQLServer" Appendix A
1381 }
1382
1383
1384 /***
1385 * How many active connections can we have at a time to this database?
1386 *
1387 * @return max connections
1388 * @exception SQLException if a database-access error occurs.
1389 */
1390 public int getMaxConnections() throws SQLException
1391 {
1392 // XXX need to find out if this is still true for SYBASE
1393
1394 // per SQL Server Books Online "Administrator's Companion",
1395 // Part 1, Chapter 1.
1396 return 32767;
1397 }
1398
1399
1400 /***
1401 * What's the maximum cursor name length?
1402 *
1403 * @return max cursor name length in bytes
1404 * @exception SQLException if a database-access error occurs.
1405 */
1406 public int getMaxCursorNameLength() throws SQLException
1407 {
1408 // XXX Need to check for Sybase
1409
1410 return 30; // per "Programming ODBC for SQLServer" Appendix A
1411 }
1412
1413
1414 /***
1415 * What's the maximum length of an index (in bytes)?
1416 *
1417 * @return max index length in bytes
1418 * @exception SQLException if a database-access error occurs.
1419 */
1420 public int getMaxIndexLength() throws SQLException
1421 {
1422 // XXX Need to check for Sybase
1423
1424 return 900; // per "Programming ODBC for SQLServer" Appendix A
1425 }
1426
1427
1428 /***
1429 * What's the maximum length of a procedure name?
1430 *
1431 * @return max name length in bytes
1432 * @exception SQLException if a database-access error occurs.
1433 */
1434 public int getMaxProcedureNameLength() throws SQLException
1435 {
1436 // XXX Need to check for Sybase
1437
1438 return 36; // per "Programming ODBC for SQLServer" Appendix A
1439 }
1440
1441
1442 /***
1443 * What's the maximum length of a single row?
1444 *
1445 * @return max row size in bytes
1446 * @exception SQLException if a database-access error occurs.
1447 */
1448 public int getMaxRowSize() throws SQLException
1449 {
1450 // XXX need to find out if this is still true for SYBASE
1451
1452 // per SQL Server Books Online "Administrator's Companion",
1453 // Part 1, Chapter 1.
1454 return 1962;
1455 }
1456
1457
1458 /***
1459 * What's the maximum length allowed for a schema name?
1460 *
1461 * @return max name length in bytes
1462 * @exception SQLException if a database-access error occurs.
1463 */
1464 public int getMaxSchemaNameLength() throws SQLException
1465 {
1466 NotImplemented(); return 0;
1467 }
1468
1469
1470 /***
1471 * What's the maximum length of a SQL statement?
1472 *
1473 * @return max length in bytes
1474 * @exception SQLException if a database-access error occurs.
1475 */
1476 public int getMaxStatementLength() throws SQLException
1477 {
1478 // XXX Need to check for Sybase
1479
1480 // return 131072; // per "Programming ODBC for SQLServer" Appendix A
1481 //sinisa
1482 return 0x20000;
1483 }
1484
1485
1486 /***
1487 * How many active statements can we have open at one time to this
1488 * database?
1489 *
1490 * @return the maximum
1491 * @exception SQLException if a database-access error occurs.
1492 */
1493 public int getMaxStatements() throws SQLException
1494 {
1495 /*
1496 NotImplemented();
1497 return 0;
1498 */
1499 // return 128;
1500 //sinisa
1501 return 32767;
1502 }
1503
1504
1505 /***
1506 * What's the maximum length of a table name?
1507 *
1508 * @return max name length in bytes
1509 * @exception SQLException if a database-access error occurs.
1510 */
1511 public int getMaxTableNameLength() throws SQLException
1512 {
1513 // XXX Need to check for Sybase
1514
1515 return 30; // per "Programming ODBC for SQLServer" Appendix A
1516 }
1517
1518
1519 /***
1520 * What's the maximum number of tables in a SELECT?
1521 *
1522 * @return the maximum
1523 * @exception SQLException if a database-access error occurs.
1524 */
1525 public int getMaxTablesInSelect() throws SQLException
1526 {
1527 // XXX Need to check for Sybase
1528
1529 return 16; // per "Programming ODBC for SQLServer" Appendix A
1530 }
1531
1532
1533 /***
1534 * What's the maximum length of a user name?
1535 *
1536 * @return max name length in bytes
1537 * @exception SQLException if a database-access error occurs.
1538 */
1539 public int getMaxUserNameLength() throws SQLException
1540 {
1541 // XXX need to find out if this is still true for SYBASE
1542 return 30;
1543 }
1544
1545
1546 /***
1547 * Get a comma separated list of math functions.
1548 *
1549 * @return the list
1550 * @exception SQLException if a database-access error occurs.
1551 */
1552 public String getNumericFunctions() throws SQLException
1553 {
1554 // XXX need to find out if this is still true for SYBASE
1555 return "ABS,ACOS,ASIN,ATAN,ATN2,CEILING,COS,COT,"
1556 + "DEGREES,EXP,FLOOR,LOG,LOG10,PI,POWER,RADIANS,"
1557 + "RAND,ROUND,SIGN,SIN,SQRT,TAN";
1558 }
1559
1560
1561 /***
1562 * Get a description of a table's primary key columns. They
1563 * are ordered by COLUMN_NAME.
1564 *
1565 * <P>Each primary key column description has the following columns:
1566 * <OL>
1567 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1568 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1569 * <LI><B>TABLE_NAME</B> String => table name
1570 * <LI><B>COLUMN_NAME</B> String => column name
1571 * <LI><B>KEY_SEQ</B> short => sequence number within primary key
1572 * <LI><B>PK_NAME</B> String => primary key name (may be null)
1573 * </OL>
1574 *
1575 * @param catalog a catalog name; "" retrieves those without a
1576 * catalog; null means drop catalog name from the selection criteria
1577 * @param schema a schema name pattern; "" retrieves those
1578 * without a schema
1579 * @param table a table name
1580 * @return ResultSet - each row is a primary key column description
1581 * @exception SQLException if a database-access error occurs.
1582 */
1583 public java.sql.ResultSet getPrimaryKeys(String catalog, String schema,
1584 String table) throws SQLException
1585 {
1586 NotImplemented(); return null;
1587 }
1588
1589
1590 /***
1591 * Get a description of a catalog's stored procedure parameters
1592 * and result columns.
1593 *
1594 * <P>Only descriptions matching the schema, procedure and
1595 * parameter name criteria are returned. They are ordered by
1596 * PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1597 * if any, is first. Next are the parameter descriptions in call
1598 * order. The column descriptions follow in column number order.
1599 *
1600 * <P>Each row in the ResultSet is a parameter description or
1601 * column description with the following fields:
1602 * <OL>
1603 * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1604 * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1605 * <LI><B>PROCEDURE_NAME</B> String => procedure name
1606 * <LI><B>COLUMN_NAME</B> String => column/parameter name
1607 * <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1608 * <UL>
1609 * <LI> procedureColumnUnknown - nobody knows
1610 * <LI> procedureColumnIn - IN parameter
1611 * <LI> procedureColumnInOut - INOUT parameter
1612 * <LI> procedureColumnOut - OUT parameter
1613 * <LI> procedureColumnReturn - procedure return value
1614 * <LI> procedureColumnResult - result column in ResultSet
1615 * </UL>
1616 * <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1617 * <LI><B>TYPE_NAME</B> String => SQL type name
1618 * <LI><B>PRECISION</B> int => precision
1619 * <LI><B>LENGTH</B> int => length in bytes of data
1620 * <LI><B>SCALE</B> short => scale
1621 * <LI><B>RADIX</B> short => radix
1622 * <LI><B>NULLABLE</B> short => can it contain NULL?
1623 * <UL>
1624 * <LI> procedureNoNulls - does not allow NULL values
1625 * <LI> procedureNullable - allows NULL values
1626 * <LI> procedureNullableUnknown - nullability unknown
1627 * </UL>
1628 * <LI><B>REMARKS</B> String => comment describing parameter/column
1629 * </OL>
1630 *
1631 * <P><B>Note:</B> Some databases may not return the column
1632 * descriptions for a procedure. Additional columns beyond
1633 * REMARKS can be defined by the database.
1634 *
1635 * @param catalog a catalog name; "" retrieves those without a
1636 * catalog; null means drop catalog name from the selection criteria
1637 * @param schemaPattern a schema name pattern; "" retrieves those
1638 * without a schema
1639 * @param procedureNamePattern a procedure name pattern
1640 * @param columnNamePattern a column name pattern
1641 * @return ResultSet - each row is a stored procedure parameter or
1642 * column description
1643 * @exception SQLException if a database-access error occurs.
1644 * @see #getSearchStringEscape
1645 */
1646 public java.sql.ResultSet getProcedureColumns(
1647 String catalog,
1648 String schemaPattern,
1649 String procedureNamePattern,
1650 String columnNamePattern)
1651 throws SQLException
1652 {
1653 NotImplemented(); return null;
1654 }
1655
1656
1657 /***
1658 * Get a description of stored procedures available in a
1659 * catalog.
1660 *
1661 * <P>Only procedure descriptions matching the schema and
1662 * procedure name criteria are returned. They are ordered by
1663 * PROCEDURE_SCHEM, and PROCEDURE_NAME.
1664 *
1665 * <P>Each procedure description has the the following columns:
1666 * <OL>
1667 * <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1668 * <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1669 * <LI><B>PROCEDURE_NAME</B> String => procedure name
1670 * <LI> reserved for future use
1671 * <LI> reserved for future use
1672 * <LI> reserved for future use
1673 * <LI><B>REMARKS</B> String => explanatory comment on the procedure
1674 * <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1675 * <UL>
1676 * <LI> procedureResultUnknown - May return a result
1677 * <LI> procedureNoResult - Does not return a result
1678 * <LI> procedureReturnsResult - Returns a result
1679 * </UL>
1680 * </OL>
1681 *
1682 * @param catalog a catalog name; "" retrieves those without a
1683 * catalog; null means drop catalog name from the selection criteria
1684 * @param schemaPattern a schema name pattern; "" retrieves those
1685 * without a schema
1686 * @param procedureNamePattern a procedure name pattern
1687 * @return ResultSet - each row is a procedure description
1688 * @exception SQLException if a database-access error occurs.
1689 * @see #getSearchStringEscape
1690 */
1691 public java.sql.ResultSet getProcedures(String catalog,
1692 String schemaPattern,
1693 String procedureNamePattern)
1694 throws SQLException
1695 {
1696 debugPrintln("Inside of getProcedures");
1697 debugPrintln(" catalog is |" + catalog + "|");
1698 debugPrintln(" schemaPattern is " + schemaPattern);
1699 debugPrintln(" procedurePattern is " + procedureNamePattern);
1700
1701 schemaPattern = schemaPattern.trim();
1702
1703 if (tds.getDatabaseProductName().indexOf("Microsoft") >= 0
1704 && tds.getDatabaseProductVersion().startsWith("7."))
1705 {
1706 String query;
1707
1708 query = ("select PROCEDURE_CAT=?, "
1709 + " PROCEDURE_SCHEM=substring(u.name, 1, 32), "
1710 + " PROCEDURE_NAME=substring(o.name, 1, 32), "
1711 + " '', '', '', "
1712 + " REMARKS='', PROCEDURE_TYPE="
1713 + java.sql.DatabaseMetaData.procedureResultUnknown
1714 + " from ");
1715 if (catalog != null && (!catalog.equals("")))
1716 {
1717 // XXX need to make sure user doesn't pass in funky strings
1718 query = query + catalog + ".";
1719 }
1720 query = query + "dbo.sysobjects o, ";
1721
1722 if (catalog != null && (!catalog.equals("")))
1723 {
1724 // XXX need to make sure user doesn't pass in funky strings
1725 query = query + catalog + ".";
1726 }
1727 query = query + "dbo.sysusers u ";
1728
1729 query = query + " where o.uid=u.uid and xtype='P' ";
1730 query = query + " and u.name like ? "; // schema name
1731 query = query + " and o.name like ? "; // procedure name
1732
1733 debugPrintln("Query is |" + query + "|");
1734
1735 java.sql.PreparedStatement ps = connection.prepareStatement(query);
1736
1737 debugPrintln("ps.setString(1, \"" + catalog + "\")");
1738 ps.setString(1, catalog);
1739 if (schemaPattern==null || schemaPattern.equals(""))
1740 {
1741 debugPrintln("ps.setString(2, \"%\");");
1742 ps.setString(2, "%");
1743 }
1744 else
1745 {
1746 debugPrintln("ps.setString(2, \"" + schemaPattern + "\")");
1747 ps.setString(2, schemaPattern);
1748 }
1749 if (procedureNamePattern==null || procedureNamePattern.equals(""))
1750 {
1751 debugPrintln("ps.setString(3, \"%\");");
1752 ps.setString(3, "%");
1753 }
1754 else
1755 {
1756 debugPrintln("ps.setString(3, \"" + procedureNamePattern + "\")");
1757 ps.setString(3, procedureNamePattern);
1758 }
1759
1760 java.sql.ResultSet rs = ps.executeQuery();
1761
1762 return rs;
1763 }
1764 else
1765 {
1766 NotImplemented(); return null;
1767 }
1768 }
1769
1770
1771 /***
1772 * What's the database vendor's preferred term for "procedure"?
1773 *
1774 * @return the vendor term
1775 * @exception SQLException if a database-access error occurs.
1776 */
1777 public String getProcedureTerm() throws SQLException
1778 {
1779 // XXX Need to check for Sybase
1780
1781 // per "Programming ODBC for SQLServer" Appendix A
1782 return "stored procedure";
1783 }
1784
1785
1786 /***
1787 * Get the schema names available in this database. The results
1788 * are ordered by schema name.
1789 *
1790 * <P>The schema column is:
1791 * <OL>
1792 * <LI><B>TABLE_SCHEM</B> String => schema name
1793 * </OL>
1794 *
1795 * @return ResultSet - each row has a single String column that is a
1796 * schema name
1797 * @exception SQLException if a database-access error occurs.
1798 */
1799 public java.sql.ResultSet getSchemas() throws SQLException
1800 {
1801 // XXX We should really clean up all these temporary tables.
1802 String tmpName = "#t#" + UniqueId.getUniqueId();
1803 final String sql =
1804 " create table " + tmpName + " " +
1805 " ( " +
1806 " q char(30) null, " +
1807 " o char(30) not null, " +
1808 " n char(30) null, " +
1809 " t char(30) null, " +
1810 " r varchar(255) null " +
1811 " ) " +
1812 " " +
1813 " insert into " + tmpName + " EXEC sp_tables ' ', '%', ' ', null " +
1814 " " +
1815 " select TABLE_SCHEM=o from " + tmpName + " " +
1816 "";
1817 java.sql.Statement stmt = connection.createStatement();
1818 java.sql.ResultSet rs;
1819
1820
1821 if (stmt.execute(sql))
1822 {
1823 throw new SQLException("Internal error. "
1824 + "Unexpected result from stmt.execute(sql) "
1825 + "inside of getSchemas");
1826 }
1827
1828 if (stmt.getMoreResults())
1829 {
1830 throw new SQLException("Internal error. "
1831 + "Was expecting an update count "
1832 + "inside of getSchemas");
1833 }
1834 else
1835 {
1836 int updateCount = stmt.getUpdateCount();
1837 }
1838
1839 if (! stmt.getMoreResults())
1840 {
1841 throw new SQLException("Internal error. "
1842 + "Was expecting an result set "
1843 + "inside of getSchemas");
1844 }
1845 else
1846 {
1847 rs = stmt.getResultSet();
1848 }
1849
1850 return rs;
1851 }
1852
1853
1854 /***
1855 * What's the database vendor's preferred term for "schema"?
1856 *
1857 * @return the vendor term
1858 * @exception SQLException if a database-access error occurs.
1859 */
1860 public String getSchemaTerm() throws SQLException
1861 {
1862 // need to check this for Sybase
1863 return "owner";
1864 }
1865
1866
1867 /***
1868 * This is the string that can be used to escape '_' or '%' in
1869 * the string pattern style catalog search parameters.
1870 *
1871 * <P>The '_' character represents any single character.
1872 * <P>The '%' character represents any sequence of zero or
1873 * more characters.
1874 *
1875 * @return the string used to escape wildcard characters
1876 * @exception SQLException if a database-access error occurs.
1877 */
1878 public String getSearchStringEscape() throws SQLException
1879 {
1880 // XXX Need to check for Sybase
1881
1882 return "//"; // per "Programming ODBC for SQLServer" Appendix A
1883 }
1884
1885
1886 /***
1887 * Get a comma separated list of all a database's SQL keywords
1888 * that are NOT also SQL92 keywords.
1889 *
1890 * @return the list
1891 * @exception SQLException if a database-access error occurs.
1892 */
1893 public String getSQLKeywords() throws SQLException
1894 {
1895 NotImplemented(); return null;
1896 }
1897
1898
1899 /***
1900 * Get a comma separated list of string functions.
1901 *
1902 * @return the list
1903 * @exception SQLException if a database-access error occurs.
1904 */
1905 public String getStringFunctions() throws SQLException
1906 {
1907 return "LTRIM,SOUNDEX,ASCII,PATINDEX,SPACE,CHAR,REPLICATE,"
1908 + "STR,CHARINDEX,REVERSE,STUFF,DIFFERENCE,RIGHT,"
1909 + "SUBSTRING,LOWER,RTRIM,UPPER";
1910 }
1911
1912
1913 /***
1914 * Get a comma separated list of system functions.
1915 *
1916 * @return the list
1917 * @exception SQLException if a database-access error occurs.
1918 */
1919 public String getSystemFunctions() throws SQLException
1920 {
1921 return
1922 "COALESCE," +
1923 "COL_LENGTH," +
1924 "COL_NAME," +
1925 "DATALENGTH," +
1926 "DB_ID," +
1927 "DB_NAME," +
1928 "GETANSINULL," +
1929 "HOST_ID," +
1930 "HOST_NAME," +
1931 "IDENT_INCR," +
1932 "IDENT_SEED," +
1933 "INDEX_COL," +
1934 "ISNULL," +
1935 "NULLIF," +
1936 "OBJECT_ID," +
1937 "OBJECT_NAME," +
1938 "STATS_DATE," +
1939 "SUSER_ID," +
1940 "SUSER_NAME," +
1941 "USER_ID," +
1942 "USER_NAME";
1943 }
1944
1945
1946 /***
1947 * Get a description of the access rights for each table available
1948 * in a catalog. Note that a table privilege applies to one or
1949 * more columns in the table. It would be wrong to assume that
1950 * this priviledge applies to all columns (this may be true for
1951 * some systems but is not true for all.)
1952 *
1953 * <P>Only privileges matching the schema and table name
1954 * criteria are returned. They are ordered by TABLE_SCHEM,
1955 * TABLE_NAME, and PRIVILEGE.
1956 *
1957 * <P>Each privilige description has the following columns:
1958 * <OL>
1959 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1960 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1961 * <LI><B>TABLE_NAME</B> String => table name
1962 * <LI><B>GRANTOR</B> => grantor of access (may be null)
1963 * <LI><B>GRANTEE</B> String => grantee of access
1964 * <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1965 * INSERT, UPDATE, REFRENCES, ...)
1966 * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1967 * to grant to others; "NO" if not; null if unknown
1968 * </OL>
1969 *
1970 * @param catalog a catalog name; "" retrieves those without a
1971 * catalog; null means drop catalog name from the selection criteria
1972 * @param schemaPattern a schema name pattern; "" retrieves those
1973 * without a schema
1974 * @param tableNamePattern a table name pattern
1975 * @return ResultSet - each row is a table privilege description
1976 * @exception SQLException if a database-access error occurs.
1977 * @see #getSearchStringEscape
1978 */
1979 public java.sql.ResultSet getTablePrivileges(
1980 String catalog,
1981 String schemaPattern,
1982 String tableNamePattern) throws SQLException
1983 {
1984 NotImplemented(); return null;
1985 }
1986
1987
1988 /***
1989 * Get a description of tables available in a catalog.
1990 *
1991 * <P>Only table descriptions matching the catalog, schema, table
1992 * name and type criteria are returned. They are ordered by
1993 * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1994 *
1995 * <P>Each table description has the following columns:
1996 * <OL>
1997 * <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1998 * <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1999 * <LI><B>TABLE_NAME</B> String => table name
2000 * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
2001 * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
2002 * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
2003 * <LI><B>REMARKS</B> String => explanatory comment on the table
2004 * </OL>
2005 *
2006 * <P><B>Note:</B> Some databases may not return information for
2007 * all tables.
2008 *
2009 * @param catalog a catalog name; "" retrieves those without a
2010 * catalog; null means drop catalog name from the selection criteria
2011 * @param schemaPattern a schema name pattern; "" retrieves those
2012 * without a schema
2013 * @param tableNamePattern a table name pattern
2014 * @param types a list of table types to include; null returns all types
2015 * @return ResultSet - each row is a table description
2016 * @exception SQLException if a database-access error occurs.
2017 * @see #getSearchStringEscape
2018 */
2019 public java.sql.ResultSet getTables(
2020 String catalog,
2021 String schemaPattern,
2022 String tableNamePattern,
2023 String types[])
2024 throws SQLException
2025 {
2026 int paramIndex;
2027 int i;
2028
2029
2030 String sql = null;
2031 java.sql.Statement tmpTableStmt = connection.createStatement();
2032
2033 // XXX We need to come up with something better than a global temporary
2034 // table. It could cause problems if two people try to getTables().
2035 // (note- it is unlikely to cause any problems, but it is possible)
2036 String tmpTableName = "##t#" + UniqueId.getUniqueId();
2037 String catalogCriteria;
2038 String schemaCriteria;
2039 String tableCriteria;
2040 String typesCriteria;
2041
2042 if (schemaPattern != null)
2043 {
2044 schemaPattern = schemaPattern.trim();
2045 }
2046 if (tableNamePattern != null)
2047 {
2048 tableNamePattern = tableNamePattern.trim();
2049 }
2050
2051 debugPrintln("inside getTables");
2052 debugPrintln(" catalog is |" + catalog + "|");
2053 debugPrintln(" schemaPattern is |" + schemaPattern + "|");
2054 debugPrintln(" tableNamePattern is |" + tableNamePattern + "|");
2055 if (types == null)
2056 {
2057 System.out.println("types is null");
2058 }
2059 else
2060 {
2061 for(i=0; i<types.length; i++)
2062 {
2063 debugPrintln(" types[" + i + "] is |" + types[i]);
2064 }
2065 }
2066
2067
2068 // create a temporary table
2069 sql =
2070 "create table " + tmpTableName + " ( " +
2071 " cat char(32) null, " +
2072 " schem char(32) null, " +
2073 " name char(32) null, " +
2074 " type char(32) null, " +
2075 " rem char(255) null) ";
2076 tmpTableStmt.execute(sql);
2077
2078 // For each database in the system add its tables
2079 // Note- We have to do them one at a time in case
2080 // there are databases we don't have access to.
2081 java.sql.ResultSet rs = getCatalogs();
2082 while(rs.next())
2083 {
2084 String cat = rs.getString(1);
2085
2086 sql =
2087 "insert into " + tmpTableName + " " +
2088 " select '" + cat + "', USER_NAME(uid), name, type, null " +
2089 " from " + cat + ".dbo.sysobjects " +
2090 " where type in ('S', 'U', 'V') ";
2091 try
2092 {
2093 tmpTableStmt.executeUpdate(sql);
2094 }
2095 catch (SQLException e)
2096 {
2097 // We might not have access to certain tables. Just ignore the
2098 // error if this is the case.
2099 }
2100 }
2101 rs.close();
2102
2103 sql =
2104 "update " + tmpTableName + " " +
2105 " set type='SYSTEM TABLE' where type='S'";
2106 tmpTableStmt.executeUpdate(sql);
2107
2108 sql =
2109 "update " + tmpTableName + " " +
2110 " set type='TABLE' where type='U'";
2111 tmpTableStmt.executeUpdate(sql);
2112
2113 sql =
2114 "update " + tmpTableName + " " +
2115 " set type='VIEW' where type='V'";
2116 tmpTableStmt.executeUpdate(sql);
2117
2118 if (catalog == null)
2119 {
2120 catalog = "";
2121 catalogCriteria = " (cat like '%' or cat=?) ";
2122 }
2123 else
2124 {
2125 catalogCriteria = " cat=? ";
2126 }
2127 if (schemaPattern == null)
2128 {
2129 schemaPattern = "%";
2130 }
2131 if (tableNamePattern == null)
2132 {
2133 tableNamePattern = "%";
2134 }
2135
2136
2137 sql =
2138 "select TABLE_CAT=cat, TABLE_SCHEM=schem, "
2139 + " TABLE_NAME=name, TABLE_TYPE=type, "
2140 + " REMARKS=rem "
2141 + " from " + tmpTableName
2142 + " where " + catalogCriteria + " and "
2143 + " schem like ? and "
2144 + " name like ? ";
2145 if (types != null && types.length>0)
2146 {
2147 sql = sql + " and ( type = ? ";
2148
2149 for(i=1; i<types.length; i++)
2150 {
2151 sql = sql + " or type=? ";
2152 }
2153 sql = sql + " )";
2154 }
2155
2156 java.sql.PreparedStatement ps = connection.prepareStatement(sql);
2157
2158
2159 ps.setString(1, catalog);
2160 ps.setString(2, schemaPattern);
2161 ps.setString(3, tableNamePattern);
2162 for(i=0; types!=null && i<types.length; i++)
2163 {
2164 ps.setString(i+4, types[i]);
2165 }
2166 rs = ps.executeQuery();
2167
2168 // We need to do something about deleting the global temporary table
2169 tmpTableStmt.close();
2170
2171 return rs;
2172 }
2173
2174
2175 /***
2176 * Get the table types available in this database. The results
2177 * are ordered by table type.
2178 *
2179 * <P>The table type is:
2180 * <OL>
2181 * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
2182 * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
2183 * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
2184 * </OL>
2185 *
2186 * @return ResultSet - each row has a single String column that is a
2187 * table type
2188 * @exception SQLException if a database-access error occurs.
2189 */
2190 public java.sql.ResultSet getTableTypes() throws SQLException
2191 {
2192 // XXX see if this is still true for Sybase
2193 String sql =
2194 "select 'TABLE' TABLE_TYPE " +
2195 "union select 'VIEW' TABLE_TYPE " +
2196 "union select 'SYSTEM TABLE' TABLE_TYPE ";
2197 java.sql.Statement stmt = connection.createStatement();
2198 java.sql.ResultSet rs = stmt.executeQuery(sql);
2199
2200 return rs;
2201 }
2202
2203
2204 /***
2205 * Get a comma separated list of time and date functions.
2206 *
2207 * @return the list
2208 * @exception SQLException if a database-access error occurs.
2209 */
2210 public String getTimeDateFunctions() throws SQLException
2211 {
2212 return "GETDATE,DATEPART,DATENAME,DATEDIFF,DATEADD";
2213 }
2214
2215
2216 /***
2217 * Get a description of all the standard SQL types supported by
2218 * this database. They are ordered by DATA_TYPE and then by how
2219 * closely the data type maps to the corresponding JDBC SQL type.
2220 *
2221 * <P>Each type description has the following columns:
2222 * <OL>
2223 * <LI><B>TYPE_NAME</B> String => Type name
2224 * <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2225 * <LI><B>PRECISION</B> int => maximum precision
2226 * <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
2227 * (may be null)
2228 * <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
2229 (may be null)
2230 * <LI><B>CREATE_PARAMS</B> String => parameters used in creating
2231 * the type (may be null)
2232 * <LI><B>NULLABLE</B> short => can you use NULL for this type?
2233 * <UL>
2234 * <LI> typeNoNulls - does not allow NULL values
2235 * <LI> typeNullable - allows NULL values
2236 * <LI> typeNullableUnknown - nullability unknown
2237 * </UL>
2238 * <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
2239 * <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
2240 * <UL>
2241 * <LI> typePredNone - No support
2242 * <LI> typePredChar - Only supported with WHERE .. LIKE
2243 * <LI> typePredBasic - Supported except for WHERE .. LIKE
2244 * <LI> typeSearchable - Supported for all WHERE ..
2245 * </UL>
2246 * <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
2247 * <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
2248 * <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
2249 * auto-increment value?
2250 * <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
2251 * (may be null)
2252 * <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
2253 * <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
2254 * <LI><B>SQL_DATA_TYPE</B> int => unused
2255 * <LI><B>SQL_DATETIME_SUB</B> int => unused
2256 * <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
2257 * </OL>
2258 *
2259 * @return ResultSet - each row is a SQL type description
2260 * @exception SQLException if a database-access error occurs.
2261 */
2262 public java.sql.ResultSet getTypeInfo() throws SQLException
2263 {
2264 NotImplemented(); return null;
2265 }
2266
2267
2268 /***
2269 * What's the url for this database?
2270 *
2271 * @return the url or null if it can't be generated
2272 * @exception SQLException if a database-access error occurs.
2273 */
2274 public String getURL() throws SQLException
2275 {
2276 return ((ConnectionHelper)connection).getUrl();
2277 }
2278
2279
2280 /***
2281 * What's our user name as known to the database?
2282 *
2283 * @return our database user name
2284 * @exception SQLException if a database-access error occurs.
2285 */
2286 public String getUserName() throws SQLException
2287 {
2288 java.sql.Statement s = null;
2289 java.sql.ResultSet rs = null;
2290 String result = "";
2291
2292 try
2293 {
2294 s = connection.createStatement();
2295 // XXX Need to check this for Sybase
2296 rs = s.executeQuery("select USER_NAME()");
2297
2298 if (! rs.next())
2299 {
2300 throw new SQLException("Couldn't determine user name");
2301 }
2302 result = rs.getString(1);
2303 }
2304 finally
2305 {
2306 if (rs != null)
2307 {
2308 rs.close();
2309 }
2310 if (s != null)
2311 {
2312 s.close();
2313 }
2314 }
2315 return result;
2316 }
2317
2318
2319 /***
2320 * Get a description of a table's columns that are automatically
2321 * updated when any value in a row is updated. They are
2322 * unordered.
2323 *
2324 * <P>Each column description has the following columns:
2325 * <OL>
2326 * <LI><B>SCOPE</B> short => is not used
2327 * <LI><B>COLUMN_NAME</B> String => column name
2328 * <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2329 * <LI><B>TYPE_NAME</B> String => Data source dependent type name
2330 * <LI><B>COLUMN_SIZE</B> int => precision
2331 * <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
2332 * <LI><B>DECIMAL_DIGITS</B> short => scale
2333 * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
2334 * like an Oracle ROWID
2335 * <UL>
2336 * <LI> versionColumnUnknown - may or may not be pseudo column
2337 * <LI> versionColumnNotPseudo - is NOT a pseudo column
2338 * <LI> versionColumnPseudo - is a pseudo column
2339 * </UL>
2340 * </OL>
2341 *
2342 * @param catalog a catalog name; "" retrieves those without a
2343 * catalog; null means drop catalog name from the selection criteria
2344 * @param schema a schema name; "" retrieves those without a schema
2345 * @param table a table name
2346 * @return ResultSet - each row is a column description
2347 * @exception SQLException if a database-access error occurs.
2348 */
2349 public java.sql.ResultSet getVersionColumns(String catalog, String schema,
2350 String table) throws SQLException
2351 {
2352 NotImplemented(); return null;
2353 }
2354
2355
2356 /***
2357 * Does a catalog appear at the start of a qualified table name?
2358 * (Otherwise it appears at the end)
2359 *
2360 * @return true if it appears at the start
2361 * @exception SQLException if a database-access error occurs.
2362 */
2363 public boolean isCatalogAtStart() throws SQLException
2364 {
2365 return true;
2366 }
2367
2368
2369 /***
2370 * Is the database in read-only mode?
2371 *
2372 * @return true if so
2373 * @exception SQLException if a database-access error occurs.
2374 */
2375 public boolean isReadOnly() throws SQLException
2376 {
2377 NotImplemented(); return false;
2378 }
2379
2380
2381 /***
2382 * Are concatenations between NULL and non-NULL values NULL?
2383 *
2384 * A JDBC-Compliant driver always returns true.
2385 *
2386 * @return true if so
2387 * @exception SQLException if a database-access error occurs.
2388 */
2389 public boolean nullPlusNonNullIsNull() throws SQLException
2390 {
2391 // XXX Need to check for Sybase.
2392
2393 // MS SQLServer seems to break with the SQL standard here.
2394 // maybe there is an option to make null behavior comply
2395 return false;
2396 }
2397
2398
2399 /***
2400 * Are NULL values sorted at the end regardless of sort order?
2401 *
2402 * @return true if so
2403 * @exception SQLException if a database-access error occurs.
2404 */
2405 public boolean nullsAreSortedAtEnd() throws SQLException
2406 {
2407 // XXX Need to check for Sybase
2408
2409 // This contradicts "Programming ODBC for SQLServer" Appendix A
2410 return false;
2411 }
2412
2413
2414 /***
2415 * Are NULL values sorted at the start regardless of sort order?
2416 *
2417 * @return true if so
2418 * @exception SQLException if a database-access error occurs.
2419 */
2420 public boolean nullsAreSortedAtStart() throws SQLException
2421 {
2422 // XXX Need to check for Sybase
2423
2424 // This contradicts "Programming ODBC for SQLServer" Appendix A
2425 return true;
2426 }
2427
2428
2429 /***
2430 * Are NULL values sorted high?
2431 *
2432 * @return true if so
2433 * @exception SQLException if a database-access error occurs.
2434 */
2435 public boolean nullsAreSortedHigh() throws SQLException
2436 {
2437 // XXX Need to check for Sybase
2438
2439 // This contradicts "Programming ODBC for SQLServer" Appendix A
2440 return false;
2441 }
2442
2443
2444 /***
2445 * Are NULL values sorted low?
2446 *
2447 * @return true if so
2448 * @exception SQLException if a database-access error occurs.
2449 */
2450 public boolean nullsAreSortedLow() throws SQLException
2451 {
2452 // XXX Need to check for Sybase
2453
2454 // This contradicts "Programming ODBC for SQLServer" Appendix A
2455 return false;
2456 }
2457
2458
2459 /***
2460 * Does the database treat mixed case unquoted SQL identifiers as
2461 * case insensitive and store them in lower case?
2462 *
2463 * @return true if so
2464 * @exception SQLException if a database-access error occurs.
2465 */
2466 public boolean storesLowerCaseIdentifiers() throws SQLException
2467 {
2468 // according to "Programming ODBC for SQLServer" Appendix A this
2469 // depends on how the SQLServer was installed.
2470 NotImplemented(); return false;
2471 }
2472
2473
2474 /***
2475 * Does the database treat mixed case quoted SQL identifiers as
2476 * case insensitive and store them in lower case?
2477 *
2478 * @return true if so
2479 * @exception SQLException if a database-access error occurs.
2480 */
2481 public boolean storesLowerCaseQuotedIdentifiers() throws SQLException
2482 {
2483 NotImplemented(); return false;
2484 }
2485
2486
2487 /***
2488 * Does the database treat mixed case unquoted SQL identifiers as
2489 * case insensitive and store them in mixed case?
2490 *
2491 * @return true if so
2492 * @exception SQLException if a database-access error occurs.
2493 */
2494 public boolean storesMixedCaseIdentifiers() throws SQLException
2495 {
2496 NotImplemented(); return false;
2497 }
2498
2499
2500 /***
2501 * Does the database treat mixed case quoted SQL identifiers as
2502 * case insensitive and store them in mixed case?
2503 *
2504 * @return true if so
2505 * @exception SQLException if a database-access error occurs.
2506 */
2507 public boolean storesMixedCaseQuotedIdentifiers() throws SQLException
2508 {
2509 NotImplemented(); return false;
2510 }
2511
2512
2513 /***
2514 * Does the database treat mixed case unquoted SQL identifiers as
2515 * case insensitive and store them in upper case?
2516 *
2517 * @return true if so
2518 * @exception SQLException if a database-access error occurs.
2519 */
2520 public boolean storesUpperCaseIdentifiers() throws SQLException
2521 {
2522 NotImplemented(); return false;
2523 }
2524
2525
2526 /***
2527 * Does the database treat mixed case quoted SQL identifiers as
2528 * case insensitive and store them in upper case?
2529 *
2530 * @return true if so
2531 * @exception SQLException if a database-access error occurs.
2532 */
2533 public boolean storesUpperCaseQuotedIdentifiers() throws SQLException
2534 {
2535 NotImplemented(); return false;
2536 }
2537
2538
2539 //--------------------------------------------------------------------
2540 // Functions describing which features are supported.
2541
2542 /***
2543 * Is "ALTER TABLE" with add column supported?
2544 *
2545 * @return true if so
2546 * @exception SQLException if a database-access error occurs.
2547 */
2548 public boolean supportsAlterTableWithAddColumn() throws SQLException
2549 {
2550 return true;
2551 }
2552
2553
2554 /***
2555 * Is "ALTER TABLE" with drop column supported?
2556 *
2557 * @return true if so
2558 * @exception SQLException if a database-access error occurs.
2559 */
2560 public boolean supportsAlterTableWithDropColumn() throws SQLException
2561 {
2562 return false;
2563 }
2564
2565
2566 /***
2567 * Is the ANSI92 entry level SQL grammar supported?
2568 *
2569 * All JDBC-Compliant drivers must return true.
2570 *
2571 * @return true if so
2572 * @exception SQLException if a database-access error occurs.
2573 */
2574 public boolean supportsANSI92EntryLevelSQL() throws SQLException
2575 {
2576 NotImplemented(); return false;
2577 }
2578
2579
2580 /***
2581 * Is the ANSI92 full SQL grammar supported?
2582 *
2583 * @return true if so
2584 * @exception SQLException if a database-access error occurs.
2585 */
2586 public boolean supportsANSI92FullSQL() throws SQLException
2587 {
2588 NotImplemented(); return false;
2589 }
2590
2591
2592 /***
2593 * Is the ANSI92 intermediate SQL grammar supported?
2594 *
2595 * @return true if so
2596 * @exception SQLException if a database-access error occurs.
2597 */
2598 public boolean supportsANSI92IntermediateSQL() throws SQLException
2599 {
2600 NotImplemented(); return false;
2601 }
2602
2603
2604 /***
2605 * Can a catalog name be used in a data manipulation statement?
2606 *
2607 * @return true if so
2608 * @exception SQLException if a database-access error occurs.
2609 */
2610 public boolean supportsCatalogsInDataManipulation() throws SQLException
2611 {
2612 NotImplemented(); return false;
2613 }
2614
2615
2616 /***
2617 * Can a catalog name be used in an index definition statement?
2618 *
2619 * @return true if so
2620 * @exception SQLException if a database-access error occurs.
2621 */
2622 public boolean supportsCatalogsInIndexDefinitions() throws SQLException
2623 {
2624 NotImplemented(); return false;
2625 }
2626
2627
2628 /***
2629 * Can a catalog name be used in a privilege definition statement?
2630 *
2631 * @return true if so
2632 * @exception SQLException if a database-access error occurs.
2633 */
2634 public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException
2635 {
2636 NotImplemented(); return false;
2637 }
2638
2639
2640 /***
2641 * Can a catalog name be used in a procedure call statement?
2642 *
2643 * @return true if so
2644 * @exception SQLException if a database-access error occurs.
2645 */
2646 public boolean supportsCatalogsInProcedureCalls() throws SQLException
2647 {
2648 NotImplemented(); return false;
2649 }
2650
2651
2652 /***
2653 * Can a catalog name be used in a table definition statement?
2654 *
2655 * @return true if so
2656 * @exception SQLException if a database-access error occurs.
2657 */
2658 public boolean supportsCatalogsInTableDefinitions() throws SQLException
2659 {
2660 NotImplemented(); return false;
2661 }
2662
2663
2664 /***
2665 * Is column aliasing supported?
2666 *
2667 * <P>If so, the SQL AS clause can be used to provide names for
2668 * computed columns or to provide alias names for columns as
2669 * required.
2670 *
2671 * A JDBC-Compliant driver always returns true.
2672 *
2673 * @return true if so
2674 * @exception SQLException if a database-access error occurs.
2675 */
2676 public boolean supportsColumnAliasing() throws SQLException
2677 {
2678 return true;
2679 }
2680
2681
2682 /***
2683 * Is the CONVERT function between SQL types supported?
2684 *
2685 * @return true if so
2686 * @exception SQLException if a database-access error occurs.
2687 */
2688 public boolean supportsConvert() throws SQLException
2689 {
2690 return true;
2691 }
2692
2693
2694 /***
2695 * Is CONVERT between the given SQL types supported?
2696 *
2697 * @param fromType the type to convert from
2698 * @param toType the type to convert to
2699 * @return true if so
2700 * @exception SQLException if a database-access error occurs.
2701 * @see Types
2702 */
2703 public boolean supportsConvert(int fromType, int toType) throws SQLException
2704 {
2705 NotImplemented(); return false;
2706 }
2707
2708
2709 /***
2710 * Is the ODBC Core SQL grammar supported?
2711 *
2712 * @return true if so
2713 * @exception SQLException if a database-access error occurs.
2714 */
2715 public boolean supportsCoreSQLGrammar() throws SQLException
2716 {
2717 NotImplemented(); return false;
2718 }
2719
2720
2721 /***
2722 * Are correlated subqueries supported?
2723 *
2724 * A JDBC-Compliant driver always returns true.
2725 *
2726 * @return true if so
2727 * @exception SQLException if a database-access error occurs.
2728 */
2729 public boolean supportsCorrelatedSubqueries() throws SQLException
2730 {
2731 NotImplemented(); return false;
2732 }
2733
2734
2735 /***
2736 * Are both data definition and data manipulation statements
2737 * within a transaction supported?
2738 *
2739 * @return true if so
2740 * @exception SQLException if a database-access error occurs.
2741 */
2742 public boolean supportsDataDefinitionAndDataManipulationTransactions()
2743 throws SQLException
2744 {
2745 NotImplemented(); return false;
2746 }
2747
2748
2749 /***
2750 * Are only data manipulation statements within a transaction
2751 * supported?
2752 *
2753 * @return true if so
2754 * @exception SQLException if a database-access error occurs.
2755 */
2756 public boolean supportsDataManipulationTransactionsOnly()
2757 throws SQLException
2758 {
2759 NotImplemented(); return false;
2760 }
2761
2762
2763 /***
2764 * If table correlation names are supported, are they restricted
2765 * to be different from the names of the tables?
2766 *
2767 * @return true if so
2768 * @exception SQLException if a database-access error occurs.
2769 */
2770 public boolean supportsDifferentTableCorrelationNames() throws SQLException
2771 {
2772 NotImplemented(); return false;
2773 }
2774
2775
2776 /***
2777 * Are expressions in "ORDER BY" lists supported?
2778 *
2779 * @return true if so
2780 * @exception SQLException if a database-access error occurs.
2781 */
2782 public boolean supportsExpressionsInOrderBy() throws SQLException
2783 {
2784 NotImplemented(); return false;
2785 }
2786
2787
2788 /***
2789 * Is the ODBC Extended SQL grammar supported?
2790 *
2791 * @return true if so
2792 * @exception SQLException if a database-access error occurs.
2793 */
2794 public boolean supportsExtendedSQLGrammar() throws SQLException
2795 {
2796 NotImplemented(); return false;
2797 }
2798
2799
2800 /***
2801 * Are full nested outer joins supported?
2802 *
2803 * @return true if so
2804 * @exception SQLException if a database-access error occurs.
2805 */
2806 public boolean supportsFullOuterJoins() throws SQLException
2807 {
2808 // XXX Need to check for Sybase
2809
2810 return true; // per "Programming ODBC for SQLServer" Appendix A
2811 }
2812
2813
2814 /***
2815 * Is some form of "GROUP BY" clause supported?
2816 *
2817 * @return true if so
2818 * @exception SQLException if a database-access error occurs.
2819 */
2820 public boolean supportsGroupBy() throws SQLException
2821 {
2822 return true;
2823 }
2824
2825
2826 /***
2827 * Can a "GROUP BY" clause add columns not in the SELECT
2828 * provided it specifies all the columns in the SELECT?
2829 *
2830 * @return true if so
2831 * @exception SQLException if a database-access error occurs.
2832 */
2833 public boolean supportsGroupByBeyondSelect() throws SQLException
2834 {
2835 // XXX Need to check for Sybase
2836
2837 return true; // per "Programming ODBC for SQLServer" Appendix A
2838 }
2839
2840
2841 /***
2842 * Can a "GROUP BY" clause use columns not in the SELECT?
2843 *
2844 * @return true if so
2845 * @exception SQLException if a database-access error occurs.
2846 */
2847 public boolean supportsGroupByUnrelated() throws SQLException
2848 {
2849 // XXX need to check this for Sybase
2850 return true;
2851 }
2852
2853
2854 /***
2855 * Is the SQL Integrity Enhancement Facility supported?
2856 *
2857 * @return true if so
2858 * @exception SQLException if a database-access error occurs.
2859 */
2860 public boolean supportsIntegrityEnhancementFacility() throws SQLException
2861 {
2862 NotImplemented(); return false;
2863 }
2864
2865
2866 /***
2867 * Is the escape character in "LIKE" clauses supported?
2868 *
2869 * A JDBC-Compliant driver always returns true.
2870 *
2871 * @return true if so
2872 * @exception SQLException if a database-access error occurs.
2873 */
2874 public boolean supportsLikeEscapeClause() throws SQLException
2875 {
2876 // XXX Need to check for Sybase
2877
2878 return true; // per "Programming ODBC for SQLServer" Appendix A
2879 }
2880
2881
2882 /***
2883 * Is there limited support for outer joins? (This will be true
2884 * if supportFullOuterJoins is true.)
2885 *
2886 * @return true if so
2887 * @exception SQLException if a database-access error occurs.
2888 */
2889 public boolean supportsLimitedOuterJoins() throws SQLException
2890 {
2891 return true;
2892 }
2893
2894
2895 /***
2896 * Is the ODBC Minimum SQL grammar supported?
2897 *
2898 * All JDBC-Compliant drivers must return true.
2899 *
2900 * @return true if so
2901 * @exception SQLException if a database-access error occurs.
2902 */
2903 public boolean supportsMinimumSQLGrammar() throws SQLException
2904 {
2905 NotImplemented(); return false;
2906 }
2907
2908
2909 /***
2910 * Does the database treat mixed case unquoted SQL identifiers as
2911 * case sensitive and as a result store them in mixed case?
2912 *
2913 * A JDBC-Compliant driver will always return false.
2914 *
2915 * @return true if so
2916 * @exception SQLException if a database-access error occurs.
2917 */
2918 public boolean supportsMixedCaseIdentifiers() throws SQLException
2919 {
2920 NotImplemented(); return false;
2921 }
2922
2923
2924 /***
2925 * Does the database treat mixed case quoted SQL identifiers as
2926 * case sensitive and as a result store them in mixed case?
2927 *
2928 * A JDBC-Compliant driver will always return true.
2929 *
2930 * @return true if so
2931 * @exception SQLException if a database-access error occurs.
2932 */
2933 public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException
2934 {
2935 NotImplemented(); return false;
2936 }
2937
2938
2939 /***
2940 * Are multiple ResultSets from a single execute supported?
2941 *
2942 * @return true if so
2943 * @exception SQLException if a database-access error occurs.
2944 */
2945 public boolean supportsMultipleResultSets() throws SQLException
2946 {
2947 return true;
2948 }
2949
2950
2951 /***
2952 * Can we have multiple transactions open at once (on different
2953 * connections)?
2954 *
2955 * @return true if so
2956 * @exception SQLException if a database-access error occurs.
2957 */
2958 public boolean supportsMultipleTransactions() throws SQLException
2959 {
2960 return true;
2961 }
2962
2963
2964 /***
2965 * Can columns be defined as non-nullable?
2966 *
2967 * A JDBC-Compliant driver always returns true.
2968 *
2969 * @return true if so
2970 * @exception SQLException if a database-access error occurs.
2971 */
2972 public boolean supportsNonNullableColumns() throws SQLException
2973 {
2974 return true;
2975 }
2976
2977
2978 /***
2979 * Can cursors remain open across commits?
2980 *
2981 * @return true if cursors always remain open; false if they might not remain open
2982 * @exception SQLException if a database-access error occurs.
2983 */
2984 public boolean supportsOpenCursorsAcrossCommit() throws SQLException
2985 {
2986 NotImplemented(); return false;
2987 }
2988
2989
2990 /***
2991 * Can cursors remain open across rollbacks?
2992 *
2993 * @return true if cursors always remain open; false if they might not remain open
2994 * @exception SQLException if a database-access error occurs.
2995 */
2996 public boolean supportsOpenCursorsAcrossRollback() throws SQLException
2997 {
2998 NotImplemented(); return false;
2999 }
3000
3001
3002 /***
3003 * Can statements remain open across commits?
3004 *
3005 * @return true if statements always remain open; false if they might
3006 * not remain open
3007 * @exception SQLException if a database-access error occurs.
3008 */
3009 public boolean supportsOpenStatementsAcrossCommit() throws SQLException
3010 {
3011 NotImplemented(); return false;
3012 }
3013
3014
3015 /***
3016 * Can statements remain open across rollbacks?
3017 *
3018 * @return true if statements always remain open; false if they might
3019 * not remain open
3020 * @exception SQLException if a database-access error occurs.
3021 */
3022 public boolean supportsOpenStatementsAcrossRollback() throws SQLException
3023 {
3024 NotImplemented(); return false;
3025 }
3026
3027
3028 /***
3029 * Can an "ORDER BY" clause use columns not in the SELECT?
3030 *
3031 * @return true if so
3032 * @exception SQLException if a database-access error occurs.
3033 */
3034 public boolean supportsOrderByUnrelated() throws SQLException
3035 {
3036 // XXX need to verify for Sybase
3037 return true;
3038 }
3039
3040
3041 /***
3042 * Is some form of outer join supported?
3043 *
3044 * @return true if so
3045 * @exception SQLException if a database-access error occurs.
3046 */
3047 public boolean supportsOuterJoins() throws SQLException
3048 {
3049 return true;
3050 }
3051
3052
3053 /***
3054 * Is positioned DELETE supported?
3055 *
3056 * @return true if so
3057 * @exception SQLException if a database-access error occurs.
3058 */
3059 public boolean supportsPositionedDelete() throws SQLException
3060 {
3061 // XXX Could we support it in the future?
3062 return false;
3063 }
3064
3065
3066 /***
3067 * Is positioned UPDATE supported?
3068 *
3069 * @return true if so
3070 * @exception SQLException if a database-access error occurs.
3071 */
3072 public boolean supportsPositionedUpdate() throws SQLException
3073 {
3074 // XXX Could we support it in the future?
3075 return false;
3076 }
3077
3078
3079 /***
3080 * Can a schema name be used in a data manipulation statement?
3081 *
3082 * @return true if so
3083 * @exception SQLException if a database-access error occurs.
3084 */
3085 public boolean supportsSchemasInDataManipulation() throws SQLException
3086 {
3087 NotImplemented(); return false;
3088 }
3089
3090
3091 /***
3092 * Can a schema name be used in an index definition statement?
3093 *
3094 * @return true if so
3095 * @exception SQLException if a database-access error occurs.
3096 */
3097 public boolean supportsSchemasInIndexDefinitions() throws SQLException
3098 {
3099 NotImplemented(); return false;
3100 }
3101
3102
3103 /***
3104 * Can a schema name be used in a privilege definition statement?
3105 *
3106 * @return true if so
3107 * @exception SQLException if a database-access error occurs.
3108 */
3109 public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException
3110 {
3111 NotImplemented(); return false;
3112 }
3113
3114
3115 /***
3116 * Can a schema name be used in a procedure call statement?
3117 *
3118 * @return true if so
3119 * @exception SQLException if a database-access error occurs.
3120 */
3121 public boolean supportsSchemasInProcedureCalls() throws SQLException
3122 {
3123 NotImplemented(); return false;
3124 }
3125
3126
3127 /***
3128 * Can a schema name be used in a table definition statement?
3129 *
3130 * @return true if so
3131 * @exception SQLException if a database-access error occurs.
3132 */
3133 public boolean supportsSchemasInTableDefinitions() throws SQLException
3134 {
3135 NotImplemented(); return false;
3136 }
3137
3138
3139 /***
3140 * Is SELECT for UPDATE supported?
3141 *
3142 * @return true if so
3143 * @exception SQLException if a database-access error occurs.
3144 */
3145 public boolean supportsSelectForUpdate() throws SQLException
3146 {
3147 NotImplemented(); return false;
3148 }
3149
3150
3151 /***
3152 * Are stored procedure calls using the stored procedure escape
3153 * syntax supported?
3154 *
3155 * @return true if so
3156 * @exception SQLException if a database-access error occurs.
3157 */
3158 public boolean supportsStoredProcedures() throws SQLException
3159 {
3160 NotImplemented(); return false;
3161 }
3162
3163
3164 /***
3165 * Are subqueries in comparison expressions supported?
3166 *
3167 * A JDBC-Compliant driver always returns true.
3168 *
3169 * @return true if so
3170 * @exception SQLException if a database-access error occurs.
3171 */
3172 public boolean supportsSubqueriesInComparisons() throws SQLException
3173 {
3174 return true;
3175 }
3176
3177
3178 /***
3179 * Are subqueries in 'exists' expressions supported?
3180 *
3181 * A JDBC-Compliant driver always returns true.
3182 *
3183 * @return true if so
3184 * @exception SQLException if a database-access error occurs.
3185 */
3186 public boolean supportsSubqueriesInExists() throws SQLException
3187 {
3188 return true;
3189 }
3190
3191
3192 /***
3193 * Are subqueries in 'in' statements supported?
3194 *
3195 * A JDBC-Compliant driver always returns true.
3196 *
3197 * @return true if so
3198 * @exception SQLException if a database-access error occurs.
3199 */
3200 public boolean supportsSubqueriesInIns() throws SQLException
3201 {
3202 return true;
3203 }
3204
3205
3206 /***
3207 * Are subqueries in quantified expressions supported?
3208 *
3209 * A JDBC-Compliant driver always returns true.
3210 *
3211 * @return true if so
3212 * @exception SQLException if a database-access error occurs.
3213 */
3214 public boolean supportsSubqueriesInQuantifieds() throws SQLException
3215 {
3216 NotImplemented(); return false;
3217 }
3218
3219
3220 /***
3221 * Are table correlation names supported?
3222 *
3223 * A JDBC-Compliant driver always returns true.
3224 *
3225 * @return true if so
3226 * @exception SQLException if a database-access error occurs.
3227 */
3228 public boolean supportsTableCorrelationNames() throws SQLException
3229 {
3230 return true;
3231 }
3232
3233
3234 /***
3235 * Does the database support the given transaction isolation level?
3236 *
3237 * @param level the values are defined in java.sql.Connection
3238 * @return true if so
3239 * @exception SQLException if a database-access error occurs.
3240 * @see Connection
3241 */
3242 public boolean supportsTransactionIsolationLevel(int level)
3243 throws SQLException
3244 {
3245 return true;
3246 }
3247
3248
3249 /***
3250 * Are transactions supported? If not, commit is a noop and the
3251 * isolation level is TRANSACTION_NONE.
3252 *
3253 * @return true if transactions are supported
3254 * @exception SQLException if a database-access error occurs.
3255 */
3256 public boolean supportsTransactions() throws SQLException
3257 {
3258 return true;
3259 }
3260
3261
3262 /***
3263 * Is SQL UNION supported?
3264 *
3265 * @return true if so
3266 * @exception SQLException if a database-access error occurs.
3267 */
3268 public boolean supportsUnion() throws SQLException
3269 {
3270 return true;
3271 }
3272
3273
3274 /***
3275 * Is SQL UNION ALL supported?
3276 *
3277 * @return true if so
3278 * @exception SQLException if a database-access error occurs.
3279 */
3280 public boolean supportsUnionAll() throws SQLException
3281 {
3282 return true;
3283 }
3284
3285
3286 /***
3287 * Does the database use a file for each table?
3288 *
3289 * @return true if the database uses a local file for each table
3290 * @exception SQLException if a database-access error occurs.
3291 */
3292 public boolean usesLocalFilePerTable() throws SQLException
3293 {
3294 return false;
3295 }
3296
3297
3298 /***
3299 * Does the database store tables in a local file?
3300 *
3301 * @return true if so
3302 * @exception SQLException if a database-access error occurs.
3303 */
3304 public boolean usesLocalFiles() throws SQLException
3305 {
3306 return false;
3307 }
3308
3309 //--------------------------JDBC 2.0-----------------------------
3310
3311 /***
3312 * JDBC 2.0
3313 *
3314 * Does the database support the given result set type?
3315 *
3316 * @param type defined in <code>java.sql.ResultSet</code>
3317 * @return <code>true</code> if so; <code>false</code> otherwise
3318 * @exception SQLException if a database access error occurs
3319 * @see Connection
3320 */
3321 public boolean supportsResultSetType(int type) throws SQLException
3322 {
3323 NotImplemented();
3324 return false;
3325 }
3326
3327
3328 /***
3329 * JDBC 2.0
3330 *
3331 * Does the database support the concurrency type in combination
3332 * with the given result set type?
3333 *
3334 * @param type defined in <code>java.sql.ResultSet</code>
3335 * @param concurrency type defined in <code>java.sql.ResultSet</code>
3336 * @return <code>true</code> if so; <code>false</code> otherwise
3337 * @exception SQLException if a database access error occurs
3338 * @see Connection
3339 */
3340 public boolean supportsResultSetConcurrency(int type, int concurrency)
3341 throws SQLException
3342 {
3343 NotImplemented();
3344 return false;
3345 }
3346
3347 /***
3348 * JDBC 2.0
3349 *
3350 * Indicates whether a result set's own updates are visible.
3351 *
3352 * @param result set type, i.e. ResultSet.TYPE_XXX
3353 * @return <code>true</code> if updates are visible for the result set type;
3354 * <code>false</code> otherwise
3355 * @exception SQLException if a database access error occurs
3356 */
3357 public boolean ownUpdatesAreVisible(int type) throws SQLException
3358 {
3359 NotImplemented();
3360 return false;
3361 }
3362
3363 /***
3364 * JDBC 2.0
3365 *
3366 * Indicates whether a result set's own deletes are visible.
3367 *
3368 * @param result set type, i.e. ResultSet.TYPE_XXX
3369 * @return <code>true</code> if deletes are visible for the result set type;
3370 * <code>false</code> otherwise
3371 * @exception SQLException if a database access error occurs
3372 */
3373 public boolean ownDeletesAreVisible(int type) throws SQLException
3374 {
3375 NotImplemented();
3376 return false;
3377 }
3378 /***
3379 * JDBC 2.0
3380 *
3381 * Indicates whether a result set's own inserts are visible.
3382 *
3383 * @param result set type, i.e. ResultSet.TYPE_XXX
3384 * @return <code>true</code> if inserts are visible for the result set type;
3385 * <code>false</code> otherwise
3386 * @exception SQLException if a database access error occurs
3387 */
3388 public boolean ownInsertsAreVisible(int type) throws SQLException
3389 {
3390 NotImplemented();
3391 return false;
3392 }
3393
3394 /***
3395 * JDBC 2.0
3396 *
3397 * Indicates whether updates made by others are visible.
3398 *
3399 * @param result set type, i.e. ResultSet.TYPE_XXX
3400 * @return <code>true</code> if updates made by others
3401 * are visible for the result set type;
3402 * <code>false</code> otherwise
3403 * @exception SQLException if a database access error occurs
3404 */
3405 public boolean othersUpdatesAreVisible(int type) throws SQLException
3406 {
3407 NotImplemented();
3408 return false;
3409 }
3410
3411 /***
3412 * JDBC 2.0
3413 *
3414 * Indicates whether deletes made by others are visible.
3415 *
3416 * @param result set type, i.e. ResultSet.TYPE_XXX
3417 * @return <code>true</code> if deletes made by others
3418 * are visible for the result set type;
3419 * <code>false</code> otherwise
3420 * @exception SQLException if a database access error occurs
3421 */
3422 public boolean othersDeletesAreVisible(int type) throws SQLException
3423 {
3424 NotImplemented();
3425 return false;
3426 }
3427
3428 /***
3429 * JDBC 2.0
3430 *
3431 * Indicates whether inserts made by others are visible.
3432 *
3433 * @param result set type, i.e. ResultSet.TYPE_XXX
3434 * @return true if updates are visible for the result set type
3435 * @return <code>true</code> if inserts made by others
3436 * are visible for the result set type;
3437 * <code>false</code> otherwise
3438 * @exception SQLException if a database access error occurs
3439 */
3440 public boolean othersInsertsAreVisible(int type) throws SQLException
3441 {
3442 NotImplemented();
3443 return false;
3444 }
3445
3446 /***
3447 * JDBC 2.0
3448 *
3449 * Indicates whether or not a visible row update can be detected by
3450 * calling the method <code>ResultSet.rowUpdated</code>.
3451 *
3452 * @param result set type, i.e. ResultSet.TYPE_XXX
3453 * @return <code>true</code> if changes are detected by the result set type;
3454 * <code>false</code> otherwise
3455 * @exception SQLException if a database access error occurs
3456 */
3457 public boolean updatesAreDetected(int type) throws SQLException
3458 {
3459 NotImplemented();
3460 return false;
3461 }
3462
3463 /***
3464 * JDBC 2.0
3465 *
3466 * Indicates whether or not a visible row delete can be detected by
3467 * calling ResultSet.rowDeleted(). If deletesAreDetected()
3468 * returns false, then deleted rows are removed from the result set.
3469 *
3470 * @param result set type, i.e. ResultSet.TYPE_XXX
3471 * @return true if changes are detected by the resultset type
3472 * @exception SQLException if a database access error occurs
3473 */
3474 public boolean deletesAreDetected(int type) throws SQLException
3475 {
3476 NotImplemented();
3477 return false;
3478 }
3479
3480 /***
3481 * JDBC 2.0
3482 *
3483 * Indicates whether or not a visible row insert can be detected
3484 * by calling ResultSet.rowInserted().
3485 *
3486 * @param result set type, i.e. ResultSet.TYPE_XXX
3487 * @return true if changes are detected by the resultset type
3488 * @exception SQLException if a database access error occurs
3489 */
3490 public boolean insertsAreDetected(int type) throws SQLException
3491 {
3492 NotImplemented();
3493 return false;
3494 }
3495
3496 /***
3497 * JDBC 2.0
3498 *
3499 * Indicates whether the driver supports batch updates.
3500 * @return true if the driver supports batch updates; false otherwise
3501 */
3502 public boolean supportsBatchUpdates() throws SQLException
3503 {
3504 NotImplemented();
3505 return false;
3506 }
3507
3508 /***
3509 * JDBC 2.0
3510 *
3511 * Gets a description of the user-defined types defined in a particular
3512 * schema. Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,
3513 * or DISTINCT.
3514 *
3515 * <P>Only types matching the catalog, schema, type name and type
3516 * criteria are returned. They are ordered by DATA_TYPE, TYPE_SCHEM
3517 * and TYPE_NAME. The type name parameter may be a fully-qualified
3518 * name. In this case, the catalog and schemaPattern parameters are
3519 * ignored.
3520 *
3521 * <P>Each type description has the following columns:
3522 * <OL>
3523 * <LI><B>TYPE_CAT</B> String => the type's catalog (may be null)
3524 * <LI><B>TYPE_SCHEM</B> String => type's schema (may be null)
3525 * <LI><B>TYPE_NAME</B> String => type name
3526 * <LI><B>CLASS_NAME</B> String => Java class name
3527 * <LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.
3528 * One of JAVA_OBJECT, STRUCT, or DISTINCT
3529 * <LI><B>REMARKS</B> String => explanatory comment on the type
3530 * </OL>
3531 *
3532 * <P><B>Note:</B> If the driver does not support UDTs, an empty
3533 * result set is returned.
3534 *
3535 * @param catalog a catalog name; "" retrieves those without a
3536 * catalog; null means drop catalog name from the selection criteria
3537 * @param schemaPattern a schema name pattern; "" retrieves those
3538 * without a schema
3539 * @param typeNamePattern a type name pattern; may be a fully-qualified
3540 * name
3541 * @param types a list of user-named types to include (JAVA_OBJECT,
3542 * STRUCT, or DISTINCT); null returns all types
3543 * @return ResultSet - each row is a type description
3544 * @exception SQLException if a database access error occurs
3545 */
3546 public java.sql.ResultSet getUDTs(String catalog, String schemaPattern,
3547 String typeNamePattern, int[] types)
3548 throws SQLException
3549 {
3550 NotImplemented();
3551 return null;
3552 }
3553
3554 /***
3555 * JDBC 2.0
3556 * Retrieves the connection that produced this metadata object.
3557 *
3558 * @return the connection that produced this metadata object
3559 */
3560 public java.sql.Connection getConnection() throws SQLException
3561 {
3562 return connection;
3563 }
3564
3565
3566 public boolean supportsSavepoints() throws SQLException {
3567 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3568 }
3569
3570 public boolean supportsNamedParameters() throws SQLException {
3571 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3572 }
3573
3574 public boolean supportsMultipleOpenResults() throws SQLException {
3575 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3576 }
3577
3578 public boolean supportsGetGeneratedKeys() throws SQLException {
3579 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3580 }
3581
3582 public ResultSet getSuperTypes(java.lang.String str1,java.lang.String str2,java.lang.String str3) throws SQLException {
3583 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3584 }
3585
3586 public ResultSet getSuperTables(java.lang.String str1,java.lang.String str2,java.lang.String str3) throws SQLException {
3587 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3588 }
3589
3590 public ResultSet getAttributes(java.lang.String str1,java.lang.String str2,java.lang.String str3, String str4) throws SQLException {
3591 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3592 }
3593
3594 public boolean supportsResultSetHoldability(int x) throws SQLException {
3595 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3596 }
3597
3598 public boolean supportsResultSetHoldability() throws SQLException {
3599 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3600 }
3601
3602 public int getResultSetHoldability() throws SQLException {
3603 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3604 }
3605
3606 public int getDatabaseMajorVersion() throws SQLException {
3607 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3608 }
3609
3610 public int getDatabaseMinorVersion() throws SQLException {
3611 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3612 }
3613
3614 public int getJDBCMajorVersion() throws SQLException {
3615 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3616 }
3617
3618 public int getJDBCMinorVersion() throws SQLException {
3619 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3620 }
3621
3622 public int getSQLStateType() throws SQLException {
3623 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3624 }
3625
3626 public boolean locatorsUpdateCopy() throws SQLException {
3627 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3628 }
3629
3630 public boolean supportsStatementPooling() throws SQLException {
3631 throw new UnsupportedOperationException("ResultSet.updateArray(String,java.sql.Array) unsupported");
3632 }
3633
3634
3635 public static void main(String args[])
3636 throws java.lang.ClassNotFoundException,
3637 java.sql.SQLException,
3638 java.lang.IllegalAccessException,
3639 java.lang.InstantiationException
3640 {
3641 String url = "jdbc:freetds://kap/jdbctest";
3642 String user = "testuser";
3643 String password = "password";
3644
3645 Class.forName("com.internetcds.jdbc.tds.Driver").newInstance();
3646 java.sql.Connection cx = DriverManager.getConnection(url, user, password);
3647 java.sql.DatabaseMetaData m = cx.getMetaData();
3648 java.sql.ResultSet rs;
3649
3650 System.out.println("Connected to " + url + " as " + user);
3651
3652 System.out.println("url is " + m.getURL());
3653 System.out.println("username is " + m.getUserName());
3654
3655 System.out.println(m.getDriverName());
3656
3657 System.out.println("Getting columns");
3658 rs = m.getColumns(null, "%", "%", "%");
3659 System.out.println("Got columns");
3660 while(rs.next())
3661 {
3662 System.out.println(
3663 "TABLE_CAT: " + rs.getString("TABLE_CAT") + "\n" +
3664 "TABLE_SCHEM: " + rs.getString("TABLE_SCHEM") + "\n" +
3665 "TABLE_NAME: " + rs.getString("TABLE_NAME") + "\n" +
3666 "COLUMN_NAME: " + rs.getString("COLUMN_NAME") + "\n" +
3667 "DATA_TYPE: " + rs.getString("DATA_TYPE") + "\n" +
3668 "TYPE_NAME: " + rs.getString("TYPE_NAME") + "\n" +
3669 "COLUMN_SIZE: " + rs.getString("COLUMN_SIZE") + "\n" +
3670 "BUFFER_LENGTH: " + rs.getString("BUFFER_LENGTH") + "\n" +
3671 "DECIMAL_DIGITS: " + rs.getString("DECIMAL_DIGITS") + "\n" +
3672 "NUM_PREC_RADIX: " + rs.getString("NUM_PREC_RADIX") + "\n" +
3673 "NULLABLE: " + rs.getString("NULLABLE") + "\n" +
3674 "REMARKS: " + rs.getString("REMARKS") + "\n" +
3675 "COLUMN_DEF: " + rs.getString("COLUMN_DEF") + "\n" +
3676 "SQL_DATA_TYPE: " + rs.getString("SQL_DATA_TYPE") + "\n" +
3677 "SQL_DATETIME_SUB: " + rs.getString("SQL_DATETIME_SUB") + "\n" +
3678 "CHAR_OCTET_LENGTH: " + rs.getString("CHAR_OCTET_LENGTH") + "\n" +
3679 "ORDINAL_POSITION: " + rs.getString("ORDINAL_POSITION") + "\n" +
3680 "IS_NULLABLE: " + rs.getString("IS_NULLABLE") + "\n" +
3681 "\n");
3682 }
3683 System.out.println("\n");
3684 rs.close();
3685
3686 System.out.println("Catalog term- " + m.getCatalogTerm());
3687 System.out.println("Catalog separator- " + m.getCatalogSeparator());
3688 System.out.println("Catalog is "
3689 + (m.isCatalogAtStart() ? "" : "not ")
3690 + "at start");
3691 System.out.println("Catalogs-");
3692 rs = m.getCatalogs();
3693 while(rs.next())
3694 {
3695 System.out.println(" " + rs.getString(1));
3696 }
3697 System.out.println("\n");
3698 rs.close();
3699
3700 System.out.println("Schema term- " + m.getSchemaTerm());
3701 rs = m.getSchemas();
3702 while(rs.next())
3703 {
3704 System.out.println(" " + rs.getString(1));
3705 }
3706 System.out.println("\n");
3707 rs.close();
3708
3709 System.out.println("Table types-");
3710 rs = m.getTableTypes();
3711 while(rs.next())
3712 {
3713 System.out.println(" " + rs.getString(1));
3714 }
3715 System.out.println("\n");
3716 rs.close();
3717
3718 System.out.println("Tables- ");
3719 rs = m.getTables(null, "%", "%", null);
3720 while(rs.next())
3721 {
3722 System.out.println(" " +
3723 rs.getString(1) +
3724 "." +
3725 rs.getString(2) +
3726 "." +
3727 rs.getString(3) +
3728 "." +
3729 rs.getString(4) +
3730 "." +
3731 rs.getString(5) +
3732 "");
3733 }
3734 System.out.println("\n");
3735 rs.close();
3736
3737 System.out.println("Tables for pubs- ");
3738 String tables[] = {"SYSTEM TABLE", "VIEW"};
3739 rs = m.getTables("pubs", "%", "%", tables);
3740 while(rs.next())
3741 {
3742 System.out.println(" " +
3743 rs.getString(1) +
3744 "." +
3745 rs.getString(2) +
3746 "." +
3747 rs.getString(3) +
3748 "." +
3749 rs.getString(4) +
3750 "." +
3751 rs.getString(5) +
3752 "");
3753 }
3754 System.out.println("\n");
3755 rs.close();
3756
3757
3758 System.out.println("Columns- ");
3759 rs = m.getColumns(null, "%", "%", "%");
3760 while(rs.next())
3761 {
3762 System.out.println(
3763 "TABLE_CAT: " + rs.getString("TABLE_CAT") + "\n" +
3764 "TABLE_SCHEM: " + rs.getString("TABLE_SCHEM") + "\n" +
3765 "TABLE_NAME: " + rs.getString("TABLE_NAME") + "\n" +
3766 "COLUMN_NAME: " + rs.getString("COLUMN_NAME") + "\n" +
3767 "DATA_TYPE: " + rs.getString("DATA_TYPE") + "\n" +
3768 "TYPE_NAME: " + rs.getString("TYPE_NAME") + "\n" +
3769 "COLUMN_SIZE: " + rs.getString("COLUMN_SIZE") + "\n" +
3770 "BUFFER_LENGTH: " + rs.getString("BUFFER_LENGTH") + "\n" +
3771 "DECIMAL_DIGITS: " + rs.getString("DECIMAL_DIGITS") + "\n" +
3772 "NUM_PREC_RADIX: " + rs.getString("NUM_PREC_RADIX") + "\n" +
3773 "NULLABLE: " + rs.getString("NULLABLE") + "\n" +
3774 "REMARKS: " + rs.getString("REMARKS") + "\n" +
3775 "COLUMN_DEF: " + rs.getString("COLUMN_DEF") + "\n" +
3776 "SQL_DATA_TYPE: " + rs.getString("SQL_DATA_TYPE") + "\n" +
3777 "SQL_DATETIME_SUB: " + rs.getString("SQL_DATETIME_SUB") + "\n" +
3778 "CHAR_OCTET_LENGTH: " + rs.getString("CHAR_OCTET_LENGTH") + "\n" +
3779 "ORDINAL_POSITION: " + rs.getString("ORDINAL_POSITION") + "\n" +
3780 "IS_NULLABLE: " + rs.getString("IS_NULLABLE") + "\n" +
3781 "\n");
3782 }
3783 System.out.println("\n");
3784 rs.close();
3785
3786 System.out.println("Done");
3787 }
3788 }
This page automatically generated by Maven