import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import com.quantum.adapters.DatabaseAdapter;
import com.quantum.sql.MultiSQLServer;
-import com.quantum.sql.SQLResults;
+import com.quantum.sql.SQLResultSetResults;
/**
* @author BC
*/
public class Database {
- private DatabaseAdapter databaseAdapter;
+ private static final int TABLE_METADATA_TABLE_SCHEM = 2;
+ private static final int TABLE_METADATA_TABLE_NAME = 3;
+
+ private static final int TABLE_TYPE_METADATA_TABLE_TYPE = 1;
+
+ private static final int FOREIGN_KEY_METADATA_PKTABLE_SCHEM = 2;
+ private static final int FOREIGN_KEY_METADATA_PKTABLE_NAME = 3;
+ private static final int FOREIGN_KEY_METADATA_PKCOLUMN_NAME = 4;
+ private static final int FOREIGN_KEY_METADATA_FKTABLE_SCHEM = 6;
+ private static final int FOREIGN_KEY_METADATA_FKTABLE_NAME = 7;
+ private static final int FOREIGN_KEY_METADATA_FKCOLUMN_NAME = 8;
+ private static final int FOREIGN_KEY_METADATA_KEY_SEQ = 9;
+ private static final int FOREIGN_KEY_METADATA_DELETE_RULE = 11;
+ private static final int FOREIGN_KEY_METADATA_FK_NAME = 12;
+
+ private static final int TYPE_INFO_METADATA_TYPE_NAME = 1;
+ private static final int TYPE_INFO_METADATA_DATA_TYPE = 2;
+ private static final int TYPE_INFO_METADATA_PRECISION = 3;
+ private static final int TYPE_INFO_METADATA_LITERAL_PREFIX = 4;
+ private static final int TYPE_INFO_METADATA_LITERAL_SUFFIX = 5;
+ private static final int TYPE_INFO_METADATA_CREATE_PARMS = 6;
+
+ private DatabaseAdapter databaseAdapter;
private Bookmark bookmark;
+ private List entityTypes;
+
public Database(Bookmark bookmark) {
this.bookmark = bookmark;
this.databaseAdapter = bookmark.getAdapter();
}
}
- public String[] getEntityTypes()
+ public synchronized String[] getEntityTypes()
throws NotConnectedException, SQLException {
- return getEntityTypes(this.bookmark.getConnection());
+ if (this.entityTypes == null) {
+ Collection collection = initializeEntityTypes(this.bookmark.getConnection());
+ this.entityTypes = Collections.synchronizedList(new ArrayList(collection));
+ }
+ return (String[]) this.entityTypes.toArray(new String[this.entityTypes.size()]);
}
public String getUsername() throws NotConnectedException, SQLException {
/**
- * <p>This method returns a list of entity types supported by the database
+ * <p>This method returns a set of entity types supported by the database
* adapter. This list will always be limited to Tables, Views and
* Sequences.</p>
*
* Tables, Views and Sequences.</p>
*
* @param connection
- * @return
+ * @return a set of Strings, typically "TABLE", "VIEW", and "SEQUENCE"
* @throws SQLException
*/
- public String[] getEntityTypes(Connection connection) throws SQLException {
+ private Set initializeEntityTypes(Connection connection) throws SQLException {
Set set = new HashSet();
if (this.databaseAdapter.getShowTableQuery(this.bookmark.getUsername()) != null) {
DatabaseMetaData metaData = connection.getMetaData();
ResultSet resultSet = metaData.getTableTypes();
while (resultSet.next()) {
- String type = resultSet.getString("TABLE_TYPE");
+ String type = resultSet.getString(TABLE_TYPE_METADATA_TABLE_TYPE);
if (type != null) {
// Informix, in particular, pads this with extra spaces
type = type.trim();
set.add(type);
}
}
-
- return (String[]) set.toArray(new String[set.size()]);
+ return set;
}
public String getInformation() throws SQLException {
for (int i = 0; i < types.length; i++) {
list.addAll(getEntitiesList(bookmark, connection, types[i], schema));
+ // TODO: This should be polished so that synonyms can be shown with different icons as regular Entities
+ list.addAll(getSynonymsList(bookmark, connection, types[i], schema));
}
return (Entity[]) list.toArray(new Entity[list.size()]);
protected List getEntitiesList(Bookmark bookmark, Connection connection, String type, Schema schema)
throws SQLException {
- String sql = getSQL(bookmark, type, schema);
List list = new ArrayList();
- SQLResults results = null;
+ // We try first the JDBC driver
+ DatabaseMetaData metaData = connection.getMetaData();
+ // getTables needs a null schema to get all the schemas. So we don't pass a "" schema, but a null one
+ ResultSet set = null;
+ if (metaData.supportsSchemasInTableDefinitions()) {
+ set = metaData.getTables(null, (schema != null) ? schema.getName() : null, "%", new String[] { type });
+ } else {
+ set = metaData.getTables(null, null, "%", new String[] { type });
+ }
+
+ while (set.next()) {
+ String tempSchema = set.getString(TABLE_METADATA_TABLE_SCHEM);
+ tempSchema = (tempSchema == null) ? "" : tempSchema.trim();
+ String tableName = set.getString(TABLE_METADATA_TABLE_NAME);
+ tableName = (tableName == null) ? "" : tableName.trim();
+
+ if (tableName != null && tableName.length() > 0) {
+ Entity entity = EntityFactory.getInstance().create(bookmark, tempSchema, tableName, type, false);
+ if (entity != null) {
+ list.add(entity);
+ }
+ }
+ }
+ set.close();
+ // If we have some results, then the JDBC driver is working,
+ // so we return the results and quit
+ if (list.size() > 0)
+ return list;
+
+
+ // If no results, we check also the sql query to get the list of entities
+ SQLResultSetResults results = null;
+ // Get the proper sql query to the appropiate type of entity
+ String sql = getSQL(bookmark, type, schema);
+ // If nothing returned, too bad, it seems there is no sql query for that database and entity type
if (sql != null) {
- results = MultiSQLServer.getInstance().execute(connection, sql);
+ results = (SQLResultSetResults) MultiSQLServer.getInstance().execute(
+ bookmark, connection, sql, Integer.MAX_VALUE);
for (int i = 1, size = (results == null) ? 0 : results.getRowCount(); i <= size; i++) {
String schemaName = results.getColumnCount() == 1
? schema.getName() : results.getElement(1, i).toString();
+ if (schemaName != null) {
+ schemaName = schemaName.trim();
+ }
String tableName = results.getColumnCount() == 1
? results.getElement(1, i).toString()
: results.getElement(2, i).toString();
if (tableName != null && tableName.length() > 0) {
Entity entity = EntityFactory.getInstance().create(
- bookmark, schemaName, tableName, type);
+ bookmark, schemaName, tableName, type, false);
if (entity != null) {
list.add(entity);
}
}
}
}
- // If we have some results, we go back
- if (results != null) return list;
- // Else, we try the JDBC driver
- DatabaseMetaData metaData = connection.getMetaData();
- // getTables needs a null schema to get all the schemas. So we don't pass a "" schema, but a null one
- ResultSet set = null;
- if (metaData.supportsSchemasInTableDefinitions())
- set = metaData.getTables(null, (schema != null) ? schema.getName() : null, "%", new String[] { type });
- else
- set = metaData.getTables(null, null, "%", new String[] { type });
-
- while (set.next()) {
- String tempSchema = set.getString("TABLE_SCHEM");
- tempSchema = (tempSchema == null) ? "" : tempSchema.trim();
- String tableName = set.getString("TABLE_NAME");
- tableName = (tableName == null) ? "" : tableName.trim();
+ return list;
+ }
+ /**
+ * Returns a list with the synonym objects of the given type, using a query
+ * @param bookmark
+ * @param connection
+ * @param type
+ * @param schema
+ * @return
+ * @throws SQLException
+ */
+ protected List getSynonymsList(Bookmark bookmark, Connection connection, String type, Schema schema)
+ throws SQLException {
+ List list = new ArrayList();
+ // We try first the JDBC driver
+ DatabaseMetaData metaData = connection.getMetaData();
+ SQLResultSetResults results = null;
+ // Get the proper sql query to the appropiate type of entity
+ String sql = this.databaseAdapter.getShowSynonymsQuery(schema.getName(), type);
+ // If nothing returned, too bad, it seems there is no sql query for that database and entity type
+ if (sql != null) {
+ results = (SQLResultSetResults) MultiSQLServer.getInstance().execute(
+ bookmark, connection, sql, Integer.MAX_VALUE);
+ for (int i = 1, size = (results == null) ? 0 : results.getRowCount(); i <= size; i++) {
+ String schemaName = results.getColumnCount() == 1
+ ? schema.getName() : results.getElement(1, i).toString();
+ if (schemaName != null) {
+ schemaName = schemaName.trim();
+ }
+ String tableName = results.getColumnCount() == 1
+ ? results.getElement(1, i).toString()
+ : results.getElement(2, i).toString();
if (tableName != null && tableName.length() > 0) {
- Entity entity = EntityFactory.getInstance().create(bookmark, tempSchema, tableName, type);
+ Entity entity = EntityFactory.getInstance().create(
+ bookmark, schemaName, tableName, type, true);
if (entity != null) {
list.add(entity);
}
}
}
- set.close();
- return list;
}
+ return list;
+}
public DataType[] getTypes() throws NotConnectedException, SQLException {
DatabaseMetaData metaData = getMetaData();
ResultSet results = metaData.getTypeInfo();
try {
while (results.next()) {
- String name = results.getString("TYPE_NAME");
- int type = results.getInt("DATA_TYPE");
- list.add(new DataType(type, name));
+ list.add(new DataType(
+ results.getInt(TYPE_INFO_METADATA_DATA_TYPE),
+ results.getString(TYPE_INFO_METADATA_TYPE_NAME),
+ results.getLong(TYPE_INFO_METADATA_PRECISION),
+ results.getString(TYPE_INFO_METADATA_LITERAL_PREFIX),
+ results.getString(TYPE_INFO_METADATA_LITERAL_SUFFIX),
+ results.getString(TYPE_INFO_METADATA_CREATE_PARMS)
+ ));
}
} finally {
results.close();
int lowestKeySequence = Integer.MAX_VALUE;
try {
while (resultSet.next()) {
- int keySequence = resultSet.getInt("KEY_SEQ");
+ int keySequence = resultSet.getInt(FOREIGN_KEY_METADATA_KEY_SEQ);
lowestKeySequence = Math.min(lowestKeySequence, keySequence);
if (keySequence == lowestKeySequence || foreignKey == null) {
foreignKey = new ForeignKeyImpl();
list.add(foreignKey);
- foreignKey.setName(resultSet.getString("FK_NAME"));
- foreignKey.setDeleteRule(resultSet.getShort("DELETE_RULE"));
- foreignKey.setForeignEntitySchema(resultSet.getString("FKTABLE_SCHEM"));
- foreignKey.setForeignEntityName(resultSet.getString("FKTABLE_NAME"));
- foreignKey.setLocalEntitySchema(resultSet.getString("PKTABLE_SCHEM"));
- foreignKey.setLocalEntityName(resultSet.getString("PKTABLE_NAME"));
+ foreignKey.setName(resultSet.getString(FOREIGN_KEY_METADATA_FK_NAME));
+ foreignKey.setDeleteRule(resultSet.getShort(FOREIGN_KEY_METADATA_DELETE_RULE));
+ foreignKey.setForeignEntitySchema(resultSet.getString(FOREIGN_KEY_METADATA_FKTABLE_SCHEM));
+ foreignKey.setForeignEntityName(resultSet.getString(FOREIGN_KEY_METADATA_FKTABLE_NAME));
+ foreignKey.setLocalEntitySchema(resultSet.getString(FOREIGN_KEY_METADATA_PKTABLE_SCHEM));
+ foreignKey.setLocalEntityName(resultSet.getString(FOREIGN_KEY_METADATA_PKTABLE_NAME));
}
foreignKey.addColumns(
- resultSet.getString("PKCOLUMN_NAME"),
- resultSet.getString("FKCOLUMN_NAME"));
+ resultSet.getString(FOREIGN_KEY_METADATA_PKCOLUMN_NAME),
+ resultSet.getString(FOREIGN_KEY_METADATA_FKCOLUMN_NAME));
}
return (ForeignKey[]) list.toArray(new ForeignKey[list.size()]);
} finally {
public Schema[] getSchemas() throws NotConnectedException, SQLException {
DatabaseMetaData metaData = getMetaData();
List list = new ArrayList();
- ResultSet resultSet = metaData.getSchemas();
- try {
- while (resultSet.next()) {
- String schemaName = resultSet.getString("TABLE_SCHEM");
- list.add(new Schema(schemaName));
+
+ if (metaData.supportsSchemasInTableDefinitions()) {
+ ResultSet resultSet = metaData.getSchemas();
+ try {
+ while (resultSet.next()) {
+ String schemaName = resultSet.getString("TABLE_SCHEM");
+ list.add(new Schema(schemaName));
+ }
+ } finally {
+ resultSet.close();
}
- return (Schema[]) list.toArray(new Schema[list.size()]);
- } finally {
- resultSet.close();
}
+ return (Schema[]) list.toArray(new Schema[list.size()]);
}
}