00001
00025
package org.objectweb.cjdbc.controller.backend;
00026
00027
import java.sql.Connection;
00028
import java.sql.DatabaseMetaData;
00029
import java.sql.ResultSet;
00030
import java.sql.SQLException;
00031
00032
import org.objectweb.cjdbc.common.i18n.Translate;
00033
import org.objectweb.cjdbc.common.log.Trace;
00034
import org.objectweb.cjdbc.common.sql.schema.DatabaseColumn;
00035
import org.objectweb.cjdbc.common.sql.schema.DatabaseProcedure;
00036
import org.objectweb.cjdbc.common.sql.schema.DatabaseProcedureParameter;
00037
import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema;
00038
import org.objectweb.cjdbc.common.sql.schema.DatabaseTable;
00039
import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager;
00040
00052 public class DatabaseBackendMetaData
00053 {
00055 private AbstractConnectionManager
connectionManager;
00056
00058 private Trace
logger;
00059
00061 private DatabaseSchema
databaseSchema;
00062
00064 private int dynamicPrecision;
00065
00067 private boolean gatherSystemTables =
false;
00068
00081 public DatabaseBackendMetaData(AbstractConnectionManager connectionManager,
00082 Trace logger,
int dynamicPrecision,
boolean gatherSystemTables)
00083 {
00084
this.connectionManager = connectionManager;
00085
this.dynamicPrecision = dynamicPrecision;
00086
this.logger = logger;
00087
this.gatherSystemTables = gatherSystemTables;
00088 }
00089
00096 private void createDatabaseSchemaDynamically() throws SQLException
00097 {
00098
if (
dynamicPrecision ==
DatabaseBackendSchemaConstants.DynamicPrecisionStatic)
00099
return;
00100 Connection connection = null;
00101
boolean wasInitialized =
connectionManager.isInitialized();
00102 ResultSet rs = null;
00103
00104
try
00105 {
00106
if (!wasInitialized)
00107
connectionManager.initializeConnections();
00108
00109 connection =
connectionManager.getConnection();
00110
if (connection == null)
00111 {
00112 String msg =
Translate.get(
"backend.meta.connection.failed");
00113
logger.error(msg);
00114
throw new SQLException(msg);
00115 }
00116
00117
00118 DatabaseMetaData metaData = connection.getMetaData();
00119
if (metaData == null)
00120 {
00121
logger.warn(
Translate.get(
"backend.meta.received.null"));
00122
return;
00123 }
00124
00125
databaseSchema =
new DatabaseSchema();
00126
00127
00128 String[] types;
00129
if (
gatherSystemTables)
00130 types =
new String[]{
"TABLE",
"VIEW",
"SYSTEM TABLE",
"SYSTEM VIEW"};
00131
else
00132 types =
new String[]{
"TABLE",
"VIEW"};
00133
00134
00135
00136
00137
00138
00139
00140
try
00141 {
00142 rs = metaData.getTables(null, null,
"%", types);
00143 }
00144
catch (Exception e)
00145 {
00146
00147
logger.error(
Translate.get(
"backend.meta.view.not.supported"), e);
00148 rs = metaData.getTables(null, null,
"%",
new String[]{
"TABLE"});
00149 }
00150
00151
if (rs == null)
00152 {
00153
logger.warn(
Translate.get(
"backend.meta.received.null"));
00154
return;
00155 }
00156
00157 String tableName;
00158
DatabaseTable table = null;
00159
while (rs.next())
00160 {
00161
00162 tableName = rs.getString(3);
00163
if (
logger.isDebugEnabled())
00164
logger.debug(
Translate.get(
"backend.meta.found.table", tableName));
00165
00166
00167 table =
new DatabaseTable(tableName);
00168
databaseSchema.addTable(table);
00169
00170
if (
dynamicPrecision >=
DatabaseBackendSchemaConstants.DynamicPrecisionColumn)
00171 {
00172
00173
getColumns(metaData, table);
00174
00175
getPrimaryKeys(metaData, table);
00176 }
00177 }
00178
00179
00180
if (
dynamicPrecision >=
DatabaseBackendSchemaConstants.DynamicPrecisionProcedures)
00181
getProcedures(metaData,
databaseSchema);
00182 }
00183
catch (Exception e)
00184 {
00185
if (e instanceof RuntimeException)
00186
logger.error(
Translate.get(
"backend.meta.runtime.error"), e);
00187
throw new SQLException(
Translate.get(
"backend.meta.failed.get.info", e));
00188 }
00189 finally
00190 {
00191
if (connection != null)
00192
connectionManager.releaseConnection(connection);
00193
00194
if (!wasInitialized)
00195
connectionManager.finalizeConnections();
00196
00197
try
00198 {
00199 rs.close();
00200 }
00201
catch (Exception ignore)
00202 {
00203 }
00204 }
00205 }
00206
00211 private void getProcedures(DatabaseMetaData metaData, DatabaseSchema schema)
00212 {
00213
if (
logger.isDebugEnabled())
00214
logger.debug(
Translate.get(
"backend.meta.get.procedures"));
00215 ResultSet rs = null;
00216 ResultSet rs2 = null;
00217
try
00218 {
00219
00220 rs = metaData.getProcedures(null, null,
"%");
00221
00222
if (rs == null)
00223 {
00224
logger.warn(
Translate.get(
"backend.meta.get.procedures.failed",
00225 metaData.getConnection().getCatalog()));
00226
return;
00227 }
00228
00229
while (rs.next())
00230 {
00231
00232
00233
00234
00235
DatabaseProcedure procedure =
new DatabaseProcedure(rs.getString(3), rs
00236 .getString(7), rs.getShort(8));
00237
00238
if (schema.getProcedure(procedure.
getName()) != null)
00239 {
00240
if (
logger.isDebugEnabled())
00241
logger.debug(
Translate
00242 .get(
"backend.meta.procedure.already.in.schema", procedure
00243 .getName()));
00244
continue;
00245 }
00246
else
00247 {
00248
if (
logger.isDebugEnabled())
00249
logger.debug(
Translate.get(
"backend.meta.found.procedure",
00250 procedure.
getName()));
00251 }
00252
00253
00254
00255
00256
if (
dynamicPrecision <
DatabaseBackendSchemaConstants.DynamicPrecisionProcedures)
00257
continue;
00258
00259 rs2 = metaData
00260 .getProcedureColumns(null, null, procedure.
getName(),
"%");
00261
if (rs2 == null)
00262
logger.warn(
Translate.get(
"backend.meta.get.procedure.params.failed",
00263 procedure.
getName()));
00264
else
00265 {
00266
while (rs2.next())
00267 {
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
DatabaseProcedureParameter param =
new DatabaseProcedureParameter(
00280 rs2.getString(4), rs2.getInt(5), rs2.getInt(6), rs2
00281 .getString(7), rs2.getFloat(8), rs2.getInt(9), rs2
00282 .getInt(10), rs2.getInt(11), rs2.getInt(12), rs2
00283 .getString(13));
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 procedure.
addParameter(param);
00301 }
00302 rs2.close();
00303 }
00304
00305 schema.addProcedure(procedure);
00306 }
00307 }
00308
catch (Exception e)
00309 {
00310
logger.error(
Translate.get(
"backend.meta.get.procedures.failed", e
00311 .getMessage()));
00312 }
00313 finally
00314 {
00315
try
00316 {
00317 rs.close();
00318 }
00319
catch (Exception ignore)
00320 {
00321 }
00322
try
00323 {
00324 rs2.close();
00325 }
00326
catch (Exception ignoreAsWell)
00327 {
00328 }
00329 }
00330 }
00331
00340 private void getColumns(DatabaseMetaData metaData,
DatabaseTable table)
00341
throws SQLException
00342 {
00343 ResultSet rs = null;
00344
try
00345 {
00346
00347
00348
00349
00350
00351 rs = metaData.getColumns(null, null, table.getName(),
"%");
00352
00353
if (rs == null)
00354 {
00355
logger.warn(
Translate.get(
"backend.meta.get.columns.failed", table
00356 .getName()));
00357
return;
00358 }
00359
00360
DatabaseColumn column = null;
00361
int type;
00362
while (rs.next())
00363 {
00364
00365
00366 type = rs.getShort(5);
00367 column =
new DatabaseColumn(rs.getString(4),
false, type);
00368 table.addColumn(column);
00369
00370
if (
logger.isDebugEnabled())
00371
logger.debug(
Translate.get(
"backend.meta.found.column", rs
00372 .getString(4)));
00373 }
00374 }
00375
catch (SQLException e)
00376 {
00377
throw new SQLException(
Translate.get(
"backend.meta.get.columns.failed",
00378 table.getName()));
00379 }
00380 finally
00381 {
00382
try
00383 {
00384 rs.close();
00385 }
00386
catch (Exception ignore)
00387 {
00388 }
00389 }
00390 }
00391
00400 private void getPrimaryKeys(DatabaseMetaData metaData,
DatabaseTable table)
00401
throws SQLException
00402 {
00403 ResultSet rs = null;
00404
try
00405 {
00406
00407
00408
00409
00410
00411 rs = metaData.getPrimaryKeys(null, null, table.getName());
00412
00413
if (rs == null)
00414 {
00415
logger.warn(
Translate.get(
"backend.meta.get.primary.keys.failed", table
00416 .getName()));
00417
return;
00418 }
00419
00420 String columnName = null;
00421
while (rs.next())
00422 {
00423
00424
00425
00426 columnName = rs.getString(4);
00427
if (columnName == null)
00428
continue;
00429
if (
logger.isDebugEnabled())
00430
logger.debug(
Translate.get(
"backend.meta.found.primary.key",
00431 columnName));
00432
00433
00434 table.getColumn(columnName).setIsUnique(
true);
00435 }
00436 }
00437
catch (SQLException e)
00438 {
00439
throw new SQLException(
Translate.get(
00440
"backend.meta.get.primary.keys.failed", table.getName()));
00441 }
00442 finally
00443 {
00444
try
00445 {
00446 rs.close();
00447 }
00448
catch (Exception ignore)
00449 {
00450 }
00451 }
00452 }
00453
00466 public DatabaseSchema
getDatabaseSchema() throws SQLException
00467 {
00468
if (
databaseSchema == null)
00469
createDatabaseSchemaDynamically();
00470
return databaseSchema;
00471 }
00472 }