View Javadoc
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