1 21 22 package org.dbunit.database; 23 24 import org.dbunit.dataset.*; 25 import org.dbunit.dataset.filter.IColumnFilter; 26 import org.dbunit.dataset.datatype.DataType; 27 import org.dbunit.dataset.datatype.IDataTypeFactory; 28 29 import java.sql.*; 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Collections ; 33 import java.util.List ; 34 35 40 public class DatabaseTableMetaData extends AbstractTableMetaData 41 { 42 private final String _tableName; 43 private final IDatabaseConnection _connection; 44 private Column[] _columns; 45 private Column[] _primaryKeys; 46 47 DatabaseTableMetaData(String tableName, IDatabaseConnection connection 48 ) 49 { 50 _tableName = tableName; 51 _connection = connection; 52 } 53 54 public static ITableMetaData createMetaData(String tableName, 55 ResultSet resultSet, IDataTypeFactory dataTypeFactory) 56 throws DataSetException, SQLException 57 { 58 ResultSetMetaData metaData = resultSet.getMetaData(); 59 Column[] columns = new Column[metaData.getColumnCount()]; 60 for (int i = 0; i < columns.length; i++) 61 { 62 int columnType = metaData.getColumnType(i + 1); 63 String columnTypeName = metaData.getColumnTypeName(i + 1); 64 DataType dataType = dataTypeFactory.createDataType( 65 columnType, columnTypeName); 66 columns[i] = new Column( 67 metaData.getColumnName(i + 1), 68 dataType, 69 columnTypeName, 70 Column.nullableValue(metaData.isNullable(i + 1))); 71 } 72 73 return new DefaultTableMetaData(tableName, columns); 74 } 75 76 public static ITableMetaData createMetaData(String tableName, 77 ResultSet resultSet, IDatabaseConnection connection) 78 throws SQLException, DataSetException 79 { 80 DatabaseConfig config = connection.getConfig(); 81 IDataTypeFactory typeFactory = (IDataTypeFactory)config.getProperty( 82 DatabaseConfig.PROPERTY_DATATYPE_FACTORY); 83 return createMetaData(tableName, resultSet, typeFactory); 84 } 85 86 private String [] getPrimaryKeyNames() throws SQLException 87 { 88 String schemaName = _connection.getSchema(); 90 String tableName = _tableName; 91 int index = tableName.indexOf("."); 92 if (index >= 0) 93 { 94 schemaName = tableName.substring(0, index); 95 tableName = tableName.substring(index + 1); 96 } 97 98 Connection connection = _connection.getConnection(); 99 DatabaseMetaData databaseMetaData = connection.getMetaData(); 100 ResultSet resultSet = databaseMetaData.getPrimaryKeys( 101 null, schemaName, tableName); 102 103 List list = new ArrayList (); 104 try 105 { 106 while (resultSet.next()) 107 { 108 String name = resultSet.getString(4); 109 int sequence = resultSet.getInt(5); 110 list.add(new PrimaryKeyData(name, sequence)); 111 } 112 } 113 finally 114 { 115 resultSet.close(); 116 } 117 118 Collections.sort(list); 119 String [] keys = new String [list.size()]; 120 for (int i = 0; i < keys.length; i++) 121 { 122 PrimaryKeyData data = (PrimaryKeyData)list.get(i); 123 keys[i] = data.getName(); 124 } 125 126 return keys; 127 } 128 129 private class PrimaryKeyData implements Comparable 130 { 131 private final String _name; 132 private final int _index; 133 134 public PrimaryKeyData(String name, int index) 135 { 136 _name = name; 137 _index = index; 138 } 139 140 public String getName() 141 { 142 return _name; 143 } 144 145 public int getIndex() 146 { 147 return _index; 148 } 149 150 153 public int compareTo(Object o) 154 { 155 PrimaryKeyData data = (PrimaryKeyData)o; 156 return getIndex() - data.getIndex(); 157 } 158 } 159 160 163 public String getTableName() 164 { 165 return _tableName; 166 } 167 168 public Column[] getColumns() throws DataSetException 169 { 170 if (_columns == null) 171 { 172 try 173 { 174 String schemaName = _connection.getSchema(); 176 String tableName = _tableName; 177 int index = tableName.indexOf("."); 178 if (index >= 0) 179 { 180 schemaName = tableName.substring(0, index); 181 tableName = tableName.substring(index + 1); 182 } 183 184 Connection jdbcConnection = _connection.getConnection(); 185 DatabaseMetaData databaseMetaData = jdbcConnection.getMetaData(); 186 ResultSet resultSet = databaseMetaData.getColumns( 187 null, schemaName, tableName, "%"); 188 189 try 190 { 191 DatabaseConfig config = _connection.getConfig(); 192 IDataTypeFactory dataTypeFactory = (IDataTypeFactory)config.getProperty( 193 DatabaseConfig.PROPERTY_DATATYPE_FACTORY); 194 boolean datatypeWarning = config.getFeature( 195 DatabaseConfig.FEATURE_DATATYPE_WARNING); 196 197 List columnList = new ArrayList (); 198 while (resultSet.next()) 199 { 200 String columnName = resultSet.getString(4); 201 int sqlType = resultSet.getInt(5); 202 String sqlTypeName = resultSet.getString(6); 203 int nullable = resultSet.getInt(11); 205 206 DataType dataType = 208 dataTypeFactory.createDataType(sqlType, sqlTypeName); 209 if (dataType != DataType.UNKNOWN) 210 { 211 Column column = new Column(columnName, dataType, 212 sqlTypeName, Column.nullableValue(nullable)); 213 columnList.add(column); 214 } 215 else if (datatypeWarning) 216 { 217 System.out.println( 218 "WARNING - " + tableName + "." + columnName + 219 " data type (" + sqlType + ", ‘" + sqlTypeName + 220 "’) not recognized and will be ignored. See FAQ for more information."); 221 } 222 } 223 224 if (columnList.size() == 0) 225 { 226 throw new NoColumnsFoundException(tableName); 227 } 228 229 _columns = (Column[])columnList.toArray(new Column[0]); 230 } 231 finally 232 { 233 resultSet.close(); 234 } 235 } 236 catch (SQLException e) 237 { 238 throw new DataSetException(e); 239 } 240 } 241 return _columns; 242 } 243 244 public Column[] getPrimaryKeys() throws DataSetException 245 { 246 if (_primaryKeys == null) 247 { 248 try 249 { 250 DatabaseConfig config = _connection.getConfig(); 251 IColumnFilter primaryKeysFilter = (IColumnFilter)config.getProperty( 252 DatabaseConfig.PROPERTY_PRIMARY_KEY_FILTER); 253 if (primaryKeysFilter != null) 254 { 255 _primaryKeys = getPrimaryKeys(getTableName(), getColumns(), 256 primaryKeysFilter); 257 } 258 else 259 { 260 _primaryKeys = getPrimaryKeys(getColumns(), 261 getPrimaryKeyNames()); 262 } 263 } 264 catch (SQLException e) 265 { 266 throw new DataSetException(e); 267 } 268 } 269 return _primaryKeys; 270 } 271 272 public String toString() 275 { 276 try 277 { 278 String tableName = getTableName(); 279 String columns = Arrays.asList(getColumns()).toString(); 280 String primaryKeys = Arrays.asList(getPrimaryKeys()).toString(); 281 return "table=" + tableName + ", cols=" + columns + ", pk=" + primaryKeys + ""; 282 } 283 catch (DataSetException e) 284 { 285 return super.toString(); 286 } 287 } 288 } 289 290 291 292 293 294 295 296 297 298 299 | Popular Tags |