| 1 19 package com.mysql.jdbc; 20 21 import java.sql.ResultSet ; 22 import java.sql.SQLException ; 23 import java.sql.Statement ; 24 import java.sql.Types ; 25 26 import java.util.ArrayList ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.StringTokenizer ; 30 import java.util.TreeMap ; 31 32 33 57 public class DatabaseMetaData implements java.sql.DatabaseMetaData { 58 private static final byte[] TABLE_AS_BYTES = "TABLE".getBytes(); 59 60 61 private static final String SUPPORTS_FK = "SUPPORTS_FK"; 62 63 private static final int PKTABLE_CAT = 0; 68 private static final int PKTABLE_SCHEM = 1; 69 private static final int PKTABLE_NAME = 2; 70 private static final int PKCOLUMN_NAME = 3; 71 private static final int FKTABLE_CAT = 4; 72 private static final int FKTABLE_SCHEM = 5; 73 private static final int FKTABLE_NAME = 6; 74 private static final int FKCOLUMN_NAME = 7; 75 private static final int KEY_SEQ = 8; 76 private static final int UPDATE_RULE = 9; 77 private static final int DELETE_RULE = 10; 78 private static final int FK_NAME = 11; 79 private static final int PK_NAME = 12; 80 private static final int DEFERRABILITY = 13; 81 82 83 private Connection conn; 84 85 86 private String database = null; 87 88 89 private String quotedId = null; 90 91 97 public DatabaseMetaData(Connection conn, String database) { 98 this.conn = conn; 99 this.database = database; 100 101 try { 102 this.quotedId = this.conn.supportsQuotedIdentifiers() 103 ? getIdentifierQuoteString() : ""; 104 } catch (SQLException sqlEx) { 105 AssertionFailedException.shouldNotHappen(sqlEx); 108 } 109 } 110 111 114 public java.sql.ResultSet getAttributes(String arg0, String arg1, 115 String arg2, String arg3) throws SQLException { 116 Field[] fields = new Field[21]; 117 fields[0] = new Field("", "TYPE_CAT", Types.CHAR, 32); 118 fields[1] = new Field("", "TYPE_SCHEM", Types.CHAR, 32); 119 fields[2] = new Field("", "TYPE_NAME", Types.CHAR, 32); 120 fields[3] = new Field("", "ATTR_NAME", Types.CHAR, 32); 121 fields[4] = new Field("", "DATA_TYPE", Types.SMALLINT, 32); 122 fields[5] = new Field("", "ATTR_TYPE_NAME", Types.CHAR, 32); 123 fields[6] = new Field("", "ATTR_SIZE", Types.INTEGER, 32); 124 fields[7] = new Field("", "DECIMAL_DIGITS", Types.INTEGER, 32); 125 fields[8] = new Field("", "NUM_PREC_RADIX", Types.INTEGER, 32); 126 fields[9] = new Field("", "NULLABLE ", Types.INTEGER, 32); 127 fields[10] = new Field("", "REMARKS", Types.CHAR, 32); 128 fields[11] = new Field("", "ATTR_DEF", Types.CHAR, 32); 129 fields[12] = new Field("", "SQL_DATA_TYPE", Types.INTEGER, 32); 130 fields[13] = new Field("", "SQL_DATETIME_SUB", Types.INTEGER, 32); 131 fields[14] = new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, 32); 132 fields[15] = new Field("", "ORDINAL_POSITION", Types.INTEGER, 32); 133 fields[16] = new Field("", "IS_NULLABLE", Types.CHAR, 32); 134 fields[17] = new Field("", "SCOPE_CATALOG", Types.CHAR, 32); 135 fields[18] = new Field("", "SCOPE_SCHEMA", Types.CHAR, 32); 136 fields[19] = new Field("", "SCOPE_TABLE", Types.CHAR, 32); 137 fields[20] = new Field("", "SOURCE_DATA_TYPE", Types.SMALLINT, 32); 138 139 return buildResultSet(fields, new ArrayList ()); 140 } 141 142 214 public java.sql.ResultSet getBestRowIdentifier(String catalog, 215 String schema, String table, int scope, boolean nullable) 216 throws java.sql.SQLException { 217 Field[] fields = new Field[8]; 218 fields[0] = new Field("", "SCOPE", Types.SMALLINT, 5); 219 fields[1] = new Field("", "COLUMN_NAME", Types.CHAR, 32); 220 fields[2] = new Field("", "DATA_TYPE", Types.SMALLINT, 32); 221 fields[3] = new Field("", "TYPE_NAME", Types.CHAR, 32); 222 fields[4] = new Field("", "COLUMN_SIZE", Types.INTEGER, 10); 223 fields[5] = new Field("", "BUFFER_LENGTH", Types.INTEGER, 10); 224 fields[6] = new Field("", "DECIMAL_DIGITS", Types.INTEGER, 10); 225 fields[7] = new Field("", "PSEUDO_COLUMN", Types.SMALLINT, 5); 226 227 String databasePart = ""; 228 229 if (catalog != null) { 230 if (!catalog.equals("")) { 231 databasePart = " FROM " + this.quotedId + catalog 232 + this.quotedId; 233 } 234 } else { 235 databasePart = " FROM " + this.quotedId + this.database 236 + this.quotedId; 237 } 238 239 if (table == null) { 240 throw new java.sql.SQLException ("Table not specified.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); 241 } 242 243 ResultSet results = null; 244 Statement stmt = null; 245 246 try { 247 stmt = this.conn.createStatement(); 248 249 if (stmt.getMaxRows() != 0) { 250 stmt.setMaxRows(0); 251 } 252 253 StringBuffer queryBuf = new StringBuffer ("SHOW COLUMNS FROM "); 254 queryBuf.append(this.quotedId); 255 queryBuf.append(table); 256 queryBuf.append(this.quotedId); 257 queryBuf.append(databasePart); 258 259 results = stmt.executeQuery(queryBuf.toString()); 260 261 ArrayList tuples = new ArrayList (); 262 263 while (results.next()) { 264 String keyType = results.getString("Key"); 265 266 if (keyType != null) { 267 if (StringUtils.startsWithIgnoreCase(keyType, "PRI")) { 268 byte[][] rowVal = new byte[8][]; 269 rowVal[0] = Integer.toString(java.sql.DatabaseMetaData.bestRowSession) 270 .getBytes(); 271 rowVal[1] = results.getBytes("Field"); 272 273 String type = results.getString("Type"); 274 int size = MysqlIO.getMaxBuf(); 275 int decimals = 0; 276 277 280 if (type.indexOf("enum") != -1) { 281 String temp = type.substring(type.indexOf("("), 282 type.indexOf(")")); 283 java.util.StringTokenizer tokenizer = new java.util.StringTokenizer (temp, 284 ","); 285 int maxLength = 0; 286 287 while (tokenizer.hasMoreTokens()) { 288 maxLength = Math.max(maxLength, 289 (tokenizer.nextToken().length() - 2)); 290 } 291 292 size = maxLength; 293 decimals = 0; 294 type = "enum"; 295 } else if (type.indexOf("(") != -1) { 296 if (type.indexOf(",") != -1) { 297 size = Integer.parseInt(type.substring(type 298 .indexOf("(") + 1, type.indexOf(","))); 299 decimals = Integer.parseInt(type.substring(type 300 .indexOf(",") + 1, type.indexOf(")"))); 301 } else { 302 size = Integer.parseInt(type.substring(type 303 .indexOf("(") + 1, type.indexOf(")"))); 304 } 305 306 type = type.substring(type.indexOf("(")); 307 } 308 309 rowVal[2] = new byte[0]; rowVal[3] = s2b(type); 311 rowVal[4] = Integer.toString(size + decimals).getBytes(); 312 rowVal[5] = Integer.toString(size + decimals).getBytes(); 313 rowVal[6] = Integer.toString(decimals).getBytes(); 314 rowVal[7] = Integer.toString(java.sql.DatabaseMetaData.bestRowNotPseudo) 315 .getBytes(); 316 tuples.add(rowVal); 317 } 318 } 319 } 320 321 return buildResultSet(fields, tuples); 322 } finally { 323 if (results != null) { 324 try { 325 results.close(); 326 } catch (Exception ex) { 327 ; 328 } 329 330 results = null; 331 } 332 333 if (stmt != null) { 334 try { 335 stmt.close(); 336 } catch (Exception ex) { 337 ; 338 } 339 340 stmt = null; 341 } 342 } 343 } 344 345 353 public boolean isCatalogAtStart() throws java.sql.SQLException { 354 return true; 355 } 356 357 364 public String getCatalogSeparator() throws java.sql.SQLException { 365 return "."; 366 } 367 368 375 public String getCatalogTerm() throws java.sql.SQLException { 376 return "database"; 377 } 378 379 398 public java.sql.ResultSet getCatalogs() throws java.sql.SQLException { 399 java.sql.ResultSet results = null; 400 java.sql.Statement stmt = null; 401 402 try { 403 stmt = this.conn.createStatement(); 404 405 if (stmt.getMaxRows() != 0) { 406 stmt.setMaxRows(0); 407 } 408 409 results = stmt.executeQuery("SHOW DATABASES"); 410 411 java.sql.ResultSetMetaData resultsMD = results.getMetaData(); 412 Field[] fields = new Field[1]; 413 fields[0] = new Field("", "TABLE_CAT", Types.VARCHAR, 414 resultsMD.getColumnDisplaySize(1)); 415 416 ArrayList tuples = new ArrayList (); 417 418 while (results.next()) { 419 byte[][] rowVal = new byte[1][]; 420 rowVal[0] = results.getBytes(1); 421 tuples.add(rowVal); 422 } 423 424 return buildResultSet(fields, tuples); 425 } finally { 426 if (results != null) { 427 try { 428 results.close(); 429 } catch (SQLException sqlEx) { 430 AssertionFailedException.shouldNotHappen(sqlEx); 431 } 432 433 results = null; 434 } 435 436 if (stmt != null) { 437 try { 438 stmt.close(); 439 } catch (SQLException sqlEx) { 440 AssertionFailedException.shouldNotHappen(sqlEx); 441 } 442 443 stmt = null; 444 } 445 } 446 } 447 448 500 public java.sql.ResultSet getColumnPrivileges(String catalog, 501 String schema, String table, String columnNamePattern) 502 throws java.sql.SQLException { 503 Field[] fields = new Field[8]; 504 fields[0] = new Field("", "TABLE_CAT", Types.CHAR, 64); 505 fields[1] = new Field("", "TABLE_SCHEM", Types.CHAR, 1); 506 fields[2] = new Field("", "TABLE_NAME", Types.CHAR, 64); 507 fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 64); 508 fields[4] = new Field("", "GRANTOR", Types.CHAR, 77); 509 fields[5] = new Field("", "GRANTEE", Types.CHAR, 77); 510 fields[6] = new Field("", "PRIVILEGE", Types.CHAR, 64); 511 fields[7] = new Field("", "IS_GRANTABLE", Types.CHAR, 3); 512 513 StringBuffer grantQuery = new StringBuffer ( 514 "SELECT c.host, c.db, t.grantor, c.user, " 515 + "c.table_name, c.column_name, c.column_priv " 516 + "from mysql.columns_priv c, mysql.tables_priv t " 517 + "where c.host = t.host and c.db = t.db and " 518 + "c.table_name = t.table_name "); 519 520 if ((catalog != null) && (catalog.length() != 0)) { 521 grantQuery.append(" AND c.db='"); 522 grantQuery.append(catalog); 523 grantQuery.append("' "); 524 ; 525 } 526 527 grantQuery.append(" AND c.table_name ='"); 528 grantQuery.append(table); 529 grantQuery.append("' AND c.column_name like '"); 530 grantQuery.append(columnNamePattern); 531 grantQuery.append("'"); 532 533 Statement stmt = null; 534 ResultSet results = null; 535 ArrayList grantRows = new ArrayList (); 536 537 try { 538 stmt = this.conn.createStatement(); 539 540 if (stmt.getMaxRows() != 0) { 541 stmt.setMaxRows(0); 542 } 543 544 results = stmt.executeQuery(grantQuery.toString()); 545 546 while (results.next()) { 547 String host = results.getString(1); 548 String database = results.getString(2); 549 String grantor = results.getString(3); 550 String user = results.getString(4); 551 552 if ((user == null) || (user.length() == 0)) { 553 user = "%"; 554 } 555 556 StringBuffer fullUser = new StringBuffer (user); 557 558 if ((host != null) && this.conn.useHostsInPrivileges()) { 559 fullUser.append("@"); 560 fullUser.append(host); 561 } 562 563 String columnName = results.getString(6); 564 String allPrivileges = results.getString(7); 565 566 if (allPrivileges != null) { 567 allPrivileges = allPrivileges.toUpperCase(); 568 569 StringTokenizer st = new StringTokenizer (allPrivileges, ","); 570 571 while (st.hasMoreTokens()) { 572 String privilege = st.nextToken().trim(); 573 byte[][] tuple = new byte[8][]; 574 tuple[0] = s2b(database); 575 tuple[1] = null; 576 tuple[2] = s2b(table); 577 tuple[3] = s2b(columnName); 578 579 if (grantor != null) { 580 tuple[4] = s2b(grantor); 581 } else { 582 tuple[4] = null; 583 } 584 585 tuple[5] = s2b(fullUser.toString()); 586 tuple[6] = s2b(privilege); 587 tuple[7] = null; 588 grantRows.add(tuple); 589 } 590 } 591 } 592 } finally { 593 if (results != null) { 594 try { 595 results.close(); 596 } catch (Exception ex) { 597 ; 598 } 599 600 results = null; 601 } 602 603 if (stmt != null) { 604 try { 605 stmt.close(); 606 } catch (Exception ex) { 607 ; 608 } 609 610 stmt = null; 611 } 612 } 613 614 return buildResultSet(fields, grantRows); 615 } 616 617 717 public java.sql.ResultSet getColumns(String catalog, String schemaPattern, 718 String tableName, String columnNamePattern) 719 throws java.sql.SQLException { 720 String databasePart = ""; 721 722 if (columnNamePattern == null) { 723 columnNamePattern = "%"; 724 } 725 726 if (catalog != null) { 727 if (!catalog.equals("")) { 728 databasePart = " FROM " + this.quotedId + catalog 729 + this.quotedId; 730 } 731 } else { 732 databasePart = " FROM " + this.quotedId + this.database 733 + this.quotedId; 734 } 735 736 ArrayList tableNameList = new ArrayList (); 737 int tablenameLength = 0; 738 739 if (tableName == null) { 740 java.sql.ResultSet tables = null; 742 743 try { 744 tables = getTables(catalog, schemaPattern, "%", new String [0]); 745 746 while (tables.next()) { 747 String tableNameFromList = tables.getString("TABLE_NAME"); 748 tableNameList.add(tableNameFromList); 749 750 if (tableNameFromList.length() > tablenameLength) { 751 tablenameLength = tableNameFromList.length(); 752 } 753 } 754 } finally { 755 if (tables != null) { 756 try { 757 tables.close(); 758 } catch (Exception sqlEx) { 759 AssertionFailedException.shouldNotHappen(sqlEx); 760 } 761 762 tables = null; 763 } 764 } 765 } else { 766
|