?? databasemetadata.java
字號:
/* Copyright (C) 2002-2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. There are special exceptions to the terms and conditions of the GPL as it is applied to this software. View the full text of the exception exception in file EXCEPTIONS-CONNECTOR-J in the directory of this software distribution. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package com.mysql.jdbc;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.sql.Types;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.StringTokenizer;import java.util.TreeMap;/** * JDBC Interface to Mysql functions * * <p> * This class provides information about the database as a whole. * </p> * * <p> * Many of the methods here return lists of information in ResultSets. You can * use the normal ResultSet methods such as getString and getInt to retrieve * the data from these ResultSets. If a given form of metadata is not * available, these methods show throw a java.sql.SQLException. * </p> * * <p> * Some of these methods take arguments that are String patterns. These * methods all have names such as fooPattern. Within a pattern String "%" * means match any substring of 0 or more characters and "_" means match any * one character. * </p> * * @author Mark Matthews * @version $Id: DatabaseMetaData.java,v 1.27.2.44 2004/09/30 07:35:03 mmatthew Exp $ */public class DatabaseMetaData implements java.sql.DatabaseMetaData { private static final byte[] TABLE_AS_BYTES = "TABLE".getBytes(); /** The table type for generic tables that support foreign keys. */ private static final String SUPPORTS_FK = "SUPPORTS_FK"; // // Column indexes used by all DBMD foreign key // ResultSets // private static final int PKTABLE_CAT = 0; private static final int PKTABLE_SCHEM = 1; private static final int PKTABLE_NAME = 2; private static final int PKCOLUMN_NAME = 3; private static final int FKTABLE_CAT = 4; private static final int FKTABLE_SCHEM = 5; private static final int FKTABLE_NAME = 6; private static final int FKCOLUMN_NAME = 7; private static final int KEY_SEQ = 8; private static final int UPDATE_RULE = 9; private static final int DELETE_RULE = 10; private static final int FK_NAME = 11; private static final int PK_NAME = 12; private static final int DEFERRABILITY = 13; /** The connection to the database */ private Connection conn; /** The 'current' database name being used */ private String database = null; /** What character to use when quoting identifiers */ private String quotedId = null; /** * Creates a new DatabaseMetaData object. * * @param conn DOCUMENT ME! * @param database DOCUMENT ME! */ public DatabaseMetaData(Connection conn, String database) { this.conn = conn; this.database = database; try { this.quotedId = this.conn.supportsQuotedIdentifiers() ? getIdentifierQuoteString() : ""; } catch (SQLException sqlEx) { // Forced by API, never thrown from getIdentifierQuoteString() in this // implementation. AssertionFailedException.shouldNotHappen(sqlEx); } } /** * @see DatabaseMetaData#getAttributes(String, String, String, String) */ public java.sql.ResultSet getAttributes(String arg0, String arg1, String arg2, String arg3) throws SQLException { Field[] fields = new Field[21]; fields[0] = new Field("", "TYPE_CAT", Types.CHAR, 32); fields[1] = new Field("", "TYPE_SCHEM", Types.CHAR, 32); fields[2] = new Field("", "TYPE_NAME", Types.CHAR, 32); fields[3] = new Field("", "ATTR_NAME", Types.CHAR, 32); fields[4] = new Field("", "DATA_TYPE", Types.SMALLINT, 32); fields[5] = new Field("", "ATTR_TYPE_NAME", Types.CHAR, 32); fields[6] = new Field("", "ATTR_SIZE", Types.INTEGER, 32); fields[7] = new Field("", "DECIMAL_DIGITS", Types.INTEGER, 32); fields[8] = new Field("", "NUM_PREC_RADIX", Types.INTEGER, 32); fields[9] = new Field("", "NULLABLE ", Types.INTEGER, 32); fields[10] = new Field("", "REMARKS", Types.CHAR, 32); fields[11] = new Field("", "ATTR_DEF", Types.CHAR, 32); fields[12] = new Field("", "SQL_DATA_TYPE", Types.INTEGER, 32); fields[13] = new Field("", "SQL_DATETIME_SUB", Types.INTEGER, 32); fields[14] = new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, 32); fields[15] = new Field("", "ORDINAL_POSITION", Types.INTEGER, 32); fields[16] = new Field("", "IS_NULLABLE", Types.CHAR, 32); fields[17] = new Field("", "SCOPE_CATALOG", Types.CHAR, 32); fields[18] = new Field("", "SCOPE_SCHEMA", Types.CHAR, 32); fields[19] = new Field("", "SCOPE_TABLE", Types.CHAR, 32); fields[20] = new Field("", "SOURCE_DATA_TYPE", Types.SMALLINT, 32); return buildResultSet(fields, new ArrayList()); } /** * Get a description of a table's optimal set of columns that uniquely * identifies a row. They are ordered by SCOPE. * * <P> * Each column description has the following columns: * * <OL> * <li> * <B>SCOPE</B> short => actual scope of result * * <UL> * <li> * bestRowTemporary - very temporary, while using row * </li> * <li> * bestRowTransaction - valid for remainder of current transaction * </li> * <li> * bestRowSession - valid for remainder of current session * </li> * </ul> * * </li> * <li> * <B>COLUMN_NAME</B> String => column name * </li> * <li> * <B>DATA_TYPE</B> short => SQL data type from java.sql.Types * </li> * <li> * <B>TYPE_NAME</B> String => Data source dependent type name * </li> * <li> * <B>COLUMN_SIZE</B> int => precision * </li> * <li> * <B>BUFFER_LENGTH</B> int => not used * </li> * <li> * <B>DECIMAL_DIGITS</B> short => scale * </li> * <li> * <B>PSEUDO_COLUMN</B> short => is this a pseudo column like an Oracle * ROWID * * <UL> * <li> * bestRowUnknown - may or may not be pseudo column * </li> * <li> * bestRowNotPseudo - is NOT a pseudo column * </li> * <li> * bestRowPseudo - is a pseudo column * </li> * </ul> * * </li> * </ol> * </p> * * @param catalog a catalog name; "" retrieves those without a catalog * @param schema a schema name; "" retrieves those without a schema * @param table a table name * @param scope the scope of interest; use same values as SCOPE * @param nullable include columns that are nullable? * * @return ResultSet each row is a column description * * @throws java.sql.SQLException DOCUMENT ME! */ public java.sql.ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws java.sql.SQLException { Field[] fields = new Field[8]; fields[0] = new Field("", "SCOPE", Types.SMALLINT, 5); fields[1] = new Field("", "COLUMN_NAME", Types.CHAR, 32); fields[2] = new Field("", "DATA_TYPE", Types.SMALLINT, 32); fields[3] = new Field("", "TYPE_NAME", Types.CHAR, 32); fields[4] = new Field("", "COLUMN_SIZE", Types.INTEGER, 10); fields[5] = new Field("", "BUFFER_LENGTH", Types.INTEGER, 10); fields[6] = new Field("", "DECIMAL_DIGITS", Types.INTEGER, 10); fields[7] = new Field("", "PSEUDO_COLUMN", Types.SMALLINT, 5); String databasePart = ""; if (catalog != null) { if (!catalog.equals("")) { databasePart = " FROM " + this.quotedId + catalog + this.quotedId; } } else { databasePart = " FROM " + this.quotedId + this.database + this.quotedId; } if (table == null) { throw new java.sql.SQLException("Table not specified.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } ResultSet results = null; Statement stmt = null; try { stmt = this.conn.createStatement(); if (stmt.getMaxRows() != 0) { stmt.setMaxRows(0); } StringBuffer queryBuf = new StringBuffer("SHOW COLUMNS FROM "); queryBuf.append(this.quotedId); queryBuf.append(table); queryBuf.append(this.quotedId); queryBuf.append(databasePart); results = stmt.executeQuery(queryBuf.toString()); ArrayList tuples = new ArrayList(); while (results.next()) { String keyType = results.getString("Key"); if (keyType != null) { if (StringUtils.startsWithIgnoreCase(keyType, "PRI")) { byte[][] rowVal = new byte[8][]; rowVal[0] = Integer.toString(java.sql.DatabaseMetaData.bestRowSession) .getBytes(); rowVal[1] = results.getBytes("Field"); String type = results.getString("Type"); int size = MysqlIO.getMaxBuf(); int decimals = 0; /* * Parse the Type column from MySQL */ if (type.indexOf("enum") != -1) { String temp = type.substring(type.indexOf("("), type.indexOf(")")); java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(temp, ","); int maxLength = 0; while (tokenizer.hasMoreTokens()) { maxLength = Math.max(maxLength, (tokenizer.nextToken().length() - 2)); } size = maxLength; decimals = 0; type = "enum"; } else if (type.indexOf("(") != -1) { if (type.indexOf(",") != -1) { size = Integer.parseInt(type.substring(type .indexOf("(") + 1, type.indexOf(","))); decimals = Integer.parseInt(type.substring(type .indexOf(",") + 1, type.indexOf(")"))); } else { size = Integer.parseInt(type.substring(type .indexOf("(") + 1, type.indexOf(")"))); } type = type.substring(type.indexOf("(")); } rowVal[2] = new byte[0]; // FIXME! rowVal[3] = s2b(type); rowVal[4] = Integer.toString(size + decimals).getBytes(); rowVal[5] = Integer.toString(size + decimals).getBytes(); rowVal[6] = Integer.toString(decimals).getBytes(); rowVal[7] = Integer.toString(java.sql.DatabaseMetaData.bestRowNotPseudo) .getBytes(); tuples.add(rowVal); } } } return buildResultSet(fields, tuples); } finally { if (results != null) { try { results.close(); } catch (Exception ex) { ; } results = null; } if (stmt != null) { try { stmt.close(); } catch (Exception ex) { ; } stmt = null; } } } /** * Does a catalog appear at the start of a qualified table name? (Otherwise * it appears at the end)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -