package com.frameworkset.common.poolman.sql; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import org.frameworkset.util.ClassUtil; import com.frameworkset.common.poolman.handle.RowHandlerException; import com.frameworkset.common.poolman.util.JDBCPool; /* * An addition to the PoolMan Java Object Pooling and Caching Library * Copyright (C) 1999-2001 The Code Studio * * This file was contrbuted by and is * Copyright (C) 2001 HotMagna, http://www.hotmagna.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * The full license is located at the root of this distribution * in the LICENSE file. */ /** PoolManResultSetMetaData takes a copy of a java.sql.ResultSetMetaData * for later usage. Some databases use the underlying ResultSet for * ResultSetMetaData information, so closing the ResultSet makes the * ResultSetMetaData unavailable. Given a database-specific ResultSetMetaData * object, this class creates a copy of the values and makes them available * long after the ResultSet has been closed. * * This class is used by PoolManStatement and is stored in the cache. * */ public class PoolManResultSetMetaData implements java.sql.ResultSetMetaData, java.io.Serializable { private int _columnCount; private String[] _columnTypeName; private String[] _columnClassName; private int[] _scale; private String[] _columnLabel; private String[] _columnLabel_upper; private boolean[] _autoIncrement; private int[] _columnDisplaySize; private String[] _catalogName; private String[] _columnName; private boolean[] _writable; private boolean[] _searchable; private int[] _columnType; private boolean[] _currency; private String[] _tableName; private int[] _nullable; private boolean[] _signed; private boolean[] _readOnly; private boolean[] _definitelyWritable; private int[] _precision; private String[] _schemaName; private boolean[] _caseSensitive; /** * 存储符合java规范java属性名称,转换规则为:aaa_bb_cc-->aaaBbCc */ private String columnJavaName[]; /** * 执行查询时,保存相同的字段出现在查询字段列表中的位置信息 * * 比如 * Map<ColumnName,WrapInteger> */ private Map samecols ; // used for storing error information from when getColumnClassName() fails private String _sqlReason; private String _sqlState; private int _sqlVendorCode; public static PoolManResultSetMetaData getCopy(com.frameworkset.orm.adapter.DB db,java.sql.ResultSetMetaData original) throws java.sql.SQLException { if (original instanceof PoolManResultSetMetaData) return (PoolManResultSetMetaData)original; else return new PoolManResultSetMetaData(db,original); } public static PoolManResultSetMetaData getCopy(java.sql.ResultSetMetaData original) throws java.sql.SQLException { if (original instanceof PoolManResultSetMetaData) return (PoolManResultSetMetaData)original; else return new PoolManResultSetMetaData(null,original); } public static class WrapInteger { // int i = 0; private String columnName; public String getColumnName(int index) { return (String)indexs.get(new Integer(index)); } Map indexs = new HashMap(); int count = 1; public WrapInteger(int count,int index,String columnName) { this.count = count; indexs.put(new Integer(index),columnName); this.columnName = columnName; } public void increament(int index) { count ++; indexs.put(new Integer(index),buildUUColname(columnName,index));; } public boolean containsamecol() { return count > 1; } public Map getIndexs() { return this.indexs; } public int getCount() { return count; } } public static final String col_uuid_split = "#$_"; public static String buildUUColname(String name,int id) { return new StringBuilder(name).append(col_uuid_split ).append(id).toString(); } private PoolManResultSetMetaData(com.frameworkset.orm.adapter.DB db,java.sql.ResultSetMetaData other) throws java.sql.SQLException { _columnCount = other.getColumnCount(); _columnTypeName = new String[_columnCount]; _columnClassName = new String[_columnCount]; _scale = new int[_columnCount]; _columnLabel = new String[_columnCount]; _columnLabel_upper = new String[_columnCount]; _autoIncrement = new boolean[_columnCount]; _columnDisplaySize = new int[_columnCount]; _catalogName = new String[_columnCount]; _columnName = new String[_columnCount]; _writable = new boolean[_columnCount]; _searchable = new boolean[_columnCount]; _columnType = new int[_columnCount]; _currency = new boolean[_columnCount]; _tableName = new String[_columnCount]; _nullable = new int[_columnCount]; _signed = new boolean[_columnCount]; _readOnly = new boolean[_columnCount]; _definitelyWritable = new boolean[_columnCount]; _precision = new int[_columnCount]; _schemaName = new String[_columnCount]; _caseSensitive = new boolean[_columnCount]; samecols = new HashMap(); if(JDBCPool.nameMapping) { columnJavaName = new String[_columnCount]; } Map testM = new HashMap(); for (int c = 0; c < _columnCount; c++) { int rc = c + 1; _columnTypeName[c] = other.getColumnTypeName(rc); if (_columnClassName != null) { // this only works on JDBC compliant drivers try { _columnClassName[c] = other.getColumnClassName(rc); } catch (java.sql.SQLException x) { _columnClassName = null; // don't try again! _sqlReason = x.getMessage(); _sqlState = x.getSQLState(); _sqlVendorCode = x.getErrorCode(); } catch (Throwable e) { _columnClassName = null; // don't try again! } } _scale[c] = other.getScale(rc); _columnLabel[c] = other.getColumnLabel(rc); _columnLabel_upper[c] = _columnLabel[c].toUpperCase(); if(JDBCPool.nameMapping) { this.columnJavaName[c] = ClassUtil.genJavaName(_columnLabel[c]); } // Integer idx = new Integer(c); WrapInteger wi = (WrapInteger)testM.get(_columnLabel_upper[c]); if(wi == null) { wi = new WrapInteger(1,c,_columnLabel_upper[c]); testM.put(_columnLabel_upper[c], wi); } else { wi.increament(c); } _autoIncrement[c] = other.isAutoIncrement(rc); _columnDisplaySize[c] = other.getColumnDisplaySize(rc); try { _catalogName[c] = other.getCatalogName(rc); } catch (Exception e) { } if (_catalogName[c] == null) _catalogName[c] = ""; _columnName[c] = other.getColumnName(rc); if(db != null) { _writable[c] = db.isWritebable(other,rc); _searchable[c] = db.isSearchable(other,rc); _signed[c] = db.isSigned(other,rc); _definitelyWritable[c] = db.isDefinitelyWritable(other,rc); } else { try { _writable[c] = other.isWritable(rc); } catch (Exception e) { } try { _searchable[c] = other.isSearchable(rc); } catch (Exception e) { } try { _signed[c] = other.isSigned(rc); } catch (Exception e) { } try { _definitelyWritable[c] = other.isDefinitelyWritable(rc); } catch (Exception e) { } } _columnType[c] = other.getColumnType(rc); _currency[c] = other.isCurrency(rc); try { _tableName[c] = other.getTableName(rc); } catch (Exception e) { } if (_tableName[c] == null) _tableName[c] = ""; _nullable[c] = other.isNullable(rc); _readOnly[c] = other.isReadOnly(rc); try { _precision[c] = other.getPrecision(rc); } catch(Exception e) { } try { _schemaName[c] = other.getSchemaName(rc); } catch (Exception e) { } if (_schemaName[c] == null) _schemaName[c] = ""; _caseSensitive[c] = false;//other.isCaseSensitive(rc);,fixed mysql 每次都会向mysql后台发送SHOW FULL COLUMNS FROM 指令 } for (int c = 0; c < _columnCount; c++) { // Integer idx = new Integer(c); String name = _columnLabel_upper[c]; WrapInteger wi = (WrapInteger)testM.get(name); if(wi.containsamecol() && !samecols.containsKey(name)) { samecols.put( name, wi); } } testM = null; } public Map getSamecols() { return samecols; } public WrapInteger getSameColumns(int colIndex) { return getSameColumns(this.getColumnLabelUpper(colIndex)); // return (WrapInteger)samecols.get(new Integer(colIndex)); } public WrapInteger getSameColumnsByIndex(int colIndex) { return getSameColumns(this.getColumnLabelUpperByIndex(colIndex)); // return (WrapInteger)samecols.get(new Integer(colIndex)); } public WrapInteger getSameColumns(String colName) { return (WrapInteger)samecols.get(colName); // return getSameColumns((getColumnIndex(colName))); } public int getColumnCount() throws java.sql.SQLException { return _columnCount; } public int getColumnCounts() { return _columnCount; } public java.lang.String getColumnTypeName(int column) throws java.sql.SQLException { return _columnTypeName[column - 1]; } public java.lang.String getColumnTypeNameByIndex(int column) throws java.sql.SQLException { return _columnTypeName[column ]; } public java.lang.String getColumnClassName(int column) throws java.sql.SQLException { if (_columnClassName == null) { // java.sql.ResultSetMetaData.getColumnClassName(int col) requires a JDBC 2 compliant database driver. throw new java.sql.SQLException(_sqlReason, _sqlState, _sqlVendorCode); } return _columnClassName[column - 1]; } public java.lang.String getColumnClassNameByIndex(int column) throws java.sql.SQLException { if (_columnClassName == null) { // java.sql.ResultSetMetaData.getColumnClassName(int col) requires a JDBC 2 compliant database driver. throw new java.sql.SQLException(_sqlReason, _sqlState, _sqlVendorCode); } return _columnClassName[column]; } public int getScale(int column) throws java.sql.SQLException { return _scale[column - 1]; } public int getScaleByIndex(int column) throws java.sql.SQLException { return _scale[column ]; } public java.lang.String getColumnLabel(int column) throws java.sql.SQLException { return _columnLabel[column - 1]; } public java.lang.String getColumnLabelByIndex(int column) throws java.sql.SQLException { return _columnLabel[column ]; } public java.lang.String getColumnLabelUpper(int column) { return _columnLabel_upper[column - 1]; } public java.lang.String getColumnLabelUpperByIndex(int column) { return _columnLabel_upper[column ]; } public java.lang.String getColumnJavaName(int column) { return this.columnJavaName[column - 1]; } public java.lang.String getColumnJavaNameByIndex(int column) { return this.columnJavaName[column ]; } public boolean isAutoIncrement(int column) throws java.sql.SQLException { return _autoIncrement[column - 1]; } public boolean isAutoIncrementByIndex(int column) throws java.sql.SQLException { return _autoIncrement[column ]; } public int getColumnDisplaySize(int column) throws java.sql.SQLException { return _columnDisplaySize[column - 1]; } public int getColumnDisplaySizeByIndex(int column) throws java.sql.SQLException { return _columnDisplaySize[column]; } public java.lang.String getCatalogName(int column) throws java.sql.SQLException { return _catalogName[column - 1]; } public java.lang.String getCatalogNameByIndex(int column) throws java.sql.SQLException { return _catalogName[column]; } public java.lang.String getColumnName(int column) throws java.sql.SQLException { return _columnName[column - 1]; } public java.lang.String getColumnNameByIndex(int column) throws java.sql.SQLException { return _columnName[column ]; } public boolean isWritable(int column) throws java.sql.SQLException { return _writable[column - 1]; } public boolean isWritableByIndex(int column) throws java.sql.SQLException { return _writable[column ]; } public boolean isSearchable(int column) throws java.sql.SQLException { return _searchable[column - 1]; } public boolean isSearchableByIndex(int column) throws java.sql.SQLException { return _searchable[column]; } public int getColumnType(int column) throws java.sql.SQLException { return _columnType[column - 1]; } public int getColumnTypeByIndex(int column) throws java.sql.SQLException { return _columnType[column ]; } public boolean isCurrency(int column) throws java.sql.SQLException { return _currency[column - 1]; } public boolean isCurrencyByIndex(int column) throws java.sql.SQLException { return _currency[column ]; } public java.lang.String getTableName(int column) throws java.sql.SQLException { return _tableName[column - 1]; } public java.lang.String getTableNameByIndex(int column) throws java.sql.SQLException { return _tableName[column ]; } public int isNullable(int column) throws java.sql.SQLException { return _nullable[column - 1]; } public int isNullableByIndex(int column) throws java.sql.SQLException { return _nullable[column]; } public boolean isSigned(int column) throws java.sql.SQLException { return _signed[column - 1]; } public boolean isSignedByIndex(int column) throws java.sql.SQLException { return _signed[column ]; } public boolean isReadOnly(int column) throws java.sql.SQLException { return _readOnly[column - 1]; } public boolean isReadOnlyByIndex(int column) throws java.sql.SQLException { return _readOnly[column ]; } public boolean isDefinitelyWritable(int column) throws java.sql.SQLException { return _definitelyWritable[column - 1]; } public boolean isDefinitelyWritableByIndex(int column) throws java.sql.SQLException { return _definitelyWritable[column ]; } public int getPrecision(int column) throws java.sql.SQLException { return _precision[column - 1]; } public int getPrecisionByIndex(int column) throws java.sql.SQLException { return _precision[column ]; } public java.lang.String getSchemaName(int column) throws java.sql.SQLException { return _schemaName[column - 1]; } public java.lang.String getSchemaNameByIndex(int column) throws java.sql.SQLException { return _schemaName[column ]; } public boolean isCaseSensitive(int column) throws java.sql.SQLException { return _caseSensitive[column - 1]; } public boolean isCaseSensitiveByIndex(int column) throws java.sql.SQLException { return _caseSensitive[column ]; } public String[] get_columnLabel_upper() { return _columnLabel_upper; } public String toString() { if(this._columnLabel == null || this._columnLabel.length == 0) return ""; StringBuffer ret = new StringBuffer(); boolean flag = false; for(String name :this._columnLabel) { if(!flag) { ret.append(name); flag = true; } else { ret.append(",").append(name); } } return ret.toString(); } public String toDetailString() { if(this._columnLabel == null || this._columnLabel.length == 0) return ""; StringBuffer ret = new StringBuffer(); // boolean flag = false; int i = 0; for(String name :this._columnLabel) { if(i == 0) { ret.append("columnname=").append(name).append("||").append("sqltype=").append(this._columnTypeName[i]).append("||javatype=").append(this._columnClassName[i]); } else { ret.append("\r\ncolumnname=").append(name).append("||").append("sqltype=").append(this._columnTypeName[i]).append("||javatype=").append(this._columnClassName[i]); } i ++; } return ret.toString(); } public int seekIndex(String colName) { String temp = colName.toUpperCase(); String[] columnLabel_uppers = get_columnLabel_upper(); for(int i = 0; i < columnLabel_uppers.length ; i ++) { if(columnLabel_uppers[i].equals(temp)) return i; } throw new RowHandlerException("查询结果中不存在列[" + colName + "]."); } /**列名获取列的信息开始 * @throws SQLException */ public String getCatalogName(String colName) throws SQLException { return this.getCatalogNameByIndex(this.seekIndex(colName)); } public String getColumnClassName(String colName) throws SQLException { return this.getColumnClassNameByIndex(this.seekIndex(colName)); } public int getColumnDisplaySize(String colName) throws SQLException{ return this.getColumnDisplaySizeByIndex(this.seekIndex(colName) ); } public String getColumnLabel(String colName) throws SQLException{ return this.getColumnLabelByIndex(this.seekIndex(colName) ); } public String getColumnLabelUpper(String colName) throws SQLException{ return this.getColumnLabelUpperByIndex(this.seekIndex(colName) ); } public String getColumnName(String colName) throws SQLException{ return this.getColumnNameByIndex(this.seekIndex(colName) ); } public int getColumnType(String colName) throws SQLException{ return this.getColumnTypeByIndex(this.seekIndex(colName) ); } public String getColumnTypeName(String colName) throws SQLException{ return this.getColumnTypeNameByIndex(this.seekIndex(colName) ); } public int getPrecision(String colName) throws SQLException{ return this.getPrecisionByIndex(this.seekIndex(colName) ); } public int getScale(String colName) throws SQLException{ return this.getScaleByIndex(this.seekIndex(colName) ); } public String getSchemaName(String colName) throws SQLException{ return this.getSchemaNameByIndex(this.seekIndex(colName) ); } public String getTableName(String colName) throws SQLException{ return this.getTableNameByIndex(this.seekIndex(colName) ); } public boolean isAutoIncrement(String colName) throws SQLException{ return this.isAutoIncrementByIndex(this.seekIndex(colName) ); } public boolean isCaseSensitive(String colName) throws SQLException{ return this.isCaseSensitiveByIndex(this.seekIndex(colName) ); } public boolean isCurrency(String colName) throws SQLException{ return this.isCurrencyByIndex(this.seekIndex(colName) ); } public boolean isDefinitelyWritable(String colName) throws SQLException{ return this.isDefinitelyWritableByIndex(this.seekIndex(colName) ); } public int isNullable(String colName) throws SQLException{ return this.isNullableByIndex(this.seekIndex(colName) ); } public boolean isReadOnly(String colName) throws SQLException{ return this.isReadOnlyByIndex(this.seekIndex(colName) ); } public boolean isSearchable(String colName) throws SQLException{ return this.isSearchableByIndex(this.seekIndex(colName) ); } public boolean isSigned(String colName) throws SQLException{ return this.isSignedByIndex(this.seekIndex(colName) ); } public boolean isWritable(String colName) throws SQLException{ return this.isWritableByIndex(this.seekIndex(colName) ); } public <T> T unwrap(Class<T> iface) throws SQLException { // TODO Auto-generated method stub return null; } public boolean isWrapperFor(Class<?> iface) throws SQLException { // TODO Auto-generated method stub return false; } public String[] getColumnJavaName() { return columnJavaName; } public String[] get_columnLabel() { return _columnLabel; } public int[] get_columnType() { return _columnType; } }