Author: tomdz
Date: Tue Feb 28 15:20:10 2006
New Revision: 381820
URL: http://svn.apache.org/viewcvs?rev=381820&view=rev
Log:
Fixed/enhanced the Firebird platform
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdBuilder.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdPlatform.java
db/ddlutils/trunk/src/test/jdbc.properties.firebird
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdBuilder.java
URL:
http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdBuilder.java?rev=381820&r1=381819&r2=381820&view=diff
==============================================================================
---
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdBuilder.java
(original)
+++
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdBuilder.java
Tue Feb 28 15:20:10 2006
@@ -30,6 +30,7 @@
* The SQL Builder for the FireBird database.
*
* @author Martin van den Bemt
+ * @author Thomas Dudziak
* @version $Revision: 231306 $
*/
public class FirebirdBuilder extends SqlBuilder
@@ -61,7 +62,7 @@
for (int idx = 0; idx < columns.length; idx++)
{
print("CREATE GENERATOR ");
- printIdentifier(getConstraintName("gen", table,
columns[idx].getName(), null));
+ printIdentifier(getGeneratorName(table, columns[idx]));
printEndOfStatement();
print(TERM_COMMAND);
printEndOfStatement();
@@ -86,6 +87,18 @@
}
/**
+ * Determines the name of the generator for an auto-increment column.
+ *
+ * @param table The table
+ * @param column The auto-increment column
+ * @return The generator name
+ */
+ protected String getGeneratorName(Table table, Column column)
+ {
+ return getConstraintName("gen", table, column.getName(), null);
+ }
+
+ /**
* [EMAIL PROTECTED]
*/
public void dropTable(Table table) throws IOException
@@ -155,6 +168,18 @@
Types.SMALLINT).toString();
}
return defaultValue;
+ }
+
+ /**
+ *
+ * [EMAIL PROTECTED]
+ */
+ public void createExternalForeignKeys(Database database) throws IOException
+ {
+ for (int idx = 0; idx < database.getTableCount(); idx++)
+ {
+ createExternalForeignKeys(database, database.getTable(idx));
+ }
}
}
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java
URL:
http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java?rev=381820&r1=381819&r2=381820&view=diff
==============================================================================
---
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java
(original)
+++
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java
Tue Feb 28 15:20:10 2006
@@ -16,13 +16,18 @@
* limitations under the License.
*/
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
-import java.util.Iterator;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.ddlutils.PlatformInfo;
import org.apache.ddlutils.model.Column;
import org.apache.ddlutils.model.ForeignKey;
@@ -34,7 +39,8 @@
/**
* The Jdbc Model Reader for Firebird.
*
- * @author <a href="mailto:[EMAIL PROTECTED]">Martin van den Bemt</a>
+ * @author Martin van den Bemt
+ * @author Thomas Dudziak
* @version $Revision: $
*/
public class FirebirdModelReader extends JdbcModelReader
@@ -47,103 +53,295 @@
public FirebirdModelReader(PlatformInfo platformInfo)
{
super(platformInfo);
+ setDefaultCatalogPattern(null);
+ setDefaultSchemaPattern(null);
+ setDefaultTablePattern("%");
}
/**
* [EMAIL PROTECTED]
*/
- protected void readIndex(DatabaseMetaDataWrapper metaData, Map values, Map
knownIndices) throws SQLException
+ protected Table readTable(DatabaseMetaDataWrapper metaData, Map values)
throws SQLException
{
- super.readIndex(metaData, values, knownIndices);
+ Table table = super.readTable(metaData, values);
- Iterator indexNames = knownIndices.keySet().iterator();
-
- while (indexNames.hasNext())
+ if (table != null)
{
- String indexName = (String)indexNames.next();
-
- if (indexName.indexOf("PRIMARY") != -1)
- {
- // we have hit a primary key, remove it..
- indexNames.remove();
- }
+ determineAutoIncrementColumns(table);
}
+
+ return table;
}
/**
* [EMAIL PROTECTED]
- * @todo This needs some more work, since table names can be case
sensitive or lowercase
- * depending on the platform (really cute).
- * See
http://dev.mysql.com/doc/refman/4.1/en/name-case-sensitivity.html for more info.
*/
- protected Table readTable(DatabaseMetaDataWrapper metaData, Map values)
throws SQLException
+ protected Collection readColumns(DatabaseMetaDataWrapper metaData, String
tableName) throws SQLException
{
- Table table = super.readTable(metaData, values);
+ ResultSet columnData = null;
- if (table != null)
+ try
{
- determineAutoIncrementFromResultSetMetaData(table,
table.getColumns());
- // fix the indexes.
- fixIndexes(table);
- }
+ List columns = new ArrayList();
- return table;
+ if (getPlatformInfo().isUseDelimitedIdentifiers())
+ {
+ // Jaybird has a problem when delimited identifiers are
used as
+ // it is not able to find the columns for the table
+ // So we have to filter manually below
+ columnData =
metaData.getColumns(getDefaultTablePattern(), null);
+
+ while (columnData.next())
+ {
+ Map values = readColumns(columnData,
getColumnsForColumn());
+
+ if (tableName.equals(values.get("TABLE_NAME")))
+ {
+ columns.add(readColumn(metaData, values));
+ }
+ }
+ }
+ else
+ {
+ columnData = metaData.getColumns(tableName, null);
+
+ while (columnData.next())
+ {
+ Map values = readColumns(columnData,
getColumnsForColumn());
+
+ columns.add(readColumn(metaData, values));
+ }
+ }
+
+ return columns;
+ }
+ finally
+ {
+ if (columnData != null)
+ {
+ columnData.close();
+ }
+ }
}
/**
- * Helper method that determines the auto increment status for the given
columns via the
- * [EMAIL PROTECTED] ResultSetMetaData#isAutoIncrement(int)} method.<br>
+ * [EMAIL PROTECTED]
+ */
+ protected Column readColumn(DatabaseMetaDataWrapper metaData, Map
values) throws SQLException
+ {
+ Column column = super.readColumn(metaData, values);
+
+ if (column.getTypeCode() == Types.FLOAT)
+ {
+ column.setTypeCode(Types.REAL);
+ }
+ return column;
+ }
+
+ /**
+ * Helper method that determines the auto increment status using
Firebird's system tables.
*
- * @param table The table
- * @param columnsToCheck The columns to check (e.g. the primary key
columns)
+ * @param table The table
*/
- protected void determineAutoIncrementFromResultSetMetaData(Table table,
Column[] columnsToCheck) throws SQLException
+ protected void determineAutoIncrementColumns(Table table) throws
SQLException
{
- StringBuffer query = new StringBuffer();
- String prefix = ("gen_"+table.getName()+"_").toUpperCase();
+ // Since for long table and column names, the generator name will be
shortened
+ // we have to determine for each column whether there is a generator
for it
+ FirebirdBuilder builder = new FirebirdBuilder(getPlatformInfo());
+ Column[] columns = table.getColumns();
+ HashMap names = new HashMap();
+ String name;
+
+ for (int idx = 0; idx < columns.length; idx++)
+ {
+ name = builder.getGeneratorName(table, columns[idx]);
+ if (!getPlatformInfo().isUseDelimitedIdentifiers())
+ {
+ name = name.toUpperCase();
+ }
+ names.put(name, columns[idx]);
+ }
- query.append("SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS WHERE
RDB$GENERATOR_NAME STARTING WITH '");
- query.append(prefix);
- query.append("'");
+ Statement stmt = getConnection().createStatement();
- Statement stmt = getConnection().createStatement();
- ResultSet rs = stmt.executeQuery(query.toString());
+ try
+ {
+ ResultSet rs = stmt.executeQuery("SELECT RDB$GENERATOR_NAME FROM
RDB$GENERATORS");
- while(rs.next())
+ while (rs.next())
+ {
+ Column column = (Column)names.get(rs.getString(1).trim());
+
+ if (column != null)
+ {
+ column.setAutoIncrement(true);
+ }
+ }
+ rs.close();
+ }
+ finally
{
- String generatorName =
rs.getString(1).substring(prefix.length()).trim();
- Column column = table.findColumn(generatorName, false);
+ stmt.close();
+ }
+ }
- if (column != null)
+ /**
+ * [EMAIL PROTECTED]
+ */
+ protected Collection readPrimaryKeyNames(DatabaseMetaDataWrapper metaData,
String tableName) throws SQLException
+ {
+ List pks = new ArrayList();
+ ResultSet pkData = null;
+
+ try
+ {
+ if (getPlatformInfo().isUseDelimitedIdentifiers())
+ {
+ // Jaybird has a problem when delimited identifiers are
used as
+ // it is not able to find the primary key info for the
table
+ // So we have to filter manually below
+ pkData = metaData.getPrimaryKeys(getDefaultTablePattern());
+ while (pkData.next())
+ {
+ Map values = readColumns(pkData, getColumnsForPK());
+
+ if (tableName.equals(values.get("TABLE_NAME")))
+ {
+ pks.add(readPrimaryKeyName(metaData, values));
+ }
+ }
+ }
+ else
+ {
+ pkData = metaData.getPrimaryKeys(tableName);
+ while (pkData.next())
+ {
+ Map values = readColumns(pkData, getColumnsForPK());
+
+ pks.add(readPrimaryKeyName(metaData, values));
+ }
+ }
+ }
+ finally
+ {
+ if (pkData != null)
{
- column.setAutoIncrement(true);
+ pkData.close();
}
}
- stmt.close();
+ return pks;
}
-
+
/**
- * Firebird als returns indexes for foreignkeys and we need to strip
- * them from the model.
- *
- * @param table the table to fix.
+ * [EMAIL PROTECTED]
*/
- private void fixIndexes(Table table)
+ protected Collection readForeignKeys(DatabaseMetaDataWrapper metaData,
String tableName) throws SQLException
{
- // we don't do anything when there are no indexes or foreignkeys.
- if ((table.getIndexCount() > 0) && (table.getForeignKeyCount() > 0))
+ Map fks = new ListOrderedMap();
+ ResultSet fkData = null;
+
+ try
+ {
+ if (getPlatformInfo().isUseDelimitedIdentifiers())
+ {
+ // Jaybird has a problem when delimited identifiers are
used as
+ // it is not able to find the foreign key info for the
table
+ // So we have to filter manually below
+ fkData = metaData.getForeignKeys(getDefaultTablePattern());
+ while (fkData.next())
+ {
+ Map values = readColumns(fkData, getColumnsForFK());
+
+ if (tableName.equals(values.get("FKTABLE_NAME")))
+ {
+ readForeignKey(metaData, values, fks);
+ }
+ }
+ }
+ else
+ {
+ fkData = metaData.getForeignKeys(tableName);
+ while (fkData.next())
+ {
+ Map values = readColumns(fkData, getColumnsForFK());
+
+ readForeignKey(metaData, values, fks);
+ }
+ }
+ }
+ finally
{
- for (int idx = 0; idx < table.getForeignKeyCount(); idx++)
+ if (fkData != null)
{
- ForeignKey fk = table.getForeignKey(idx);
- Index index = table.findIndex(fk.getName());
+ fkData.close();
+ }
+ }
+ return fks.values();
+ }
- if (index != null)
- {
- // remove it from the indexes..
- table.removeIndex(index);
- }
+ /**
+ * [EMAIL PROTECTED]
+ */
+ protected Collection readIndices(DatabaseMetaDataWrapper metaData, String
tableName) throws SQLException
+ {
+ // Jaybird is not able to read indices when delimited identifiers are
turned on,
+ // so we gather the data manually using Firebird's system tables
+ Map indices = new ListOrderedMap();
+ StringBuffer query = new StringBuffer();
+
+ query.append("SELECT a.RDB$INDEX_NAME INDEX_NAME, b.RDB$RELATION_NAME
TABLE_NAME, b.RDB$UNIQUE_FLAG NON_UNIQUE,");
+ query.append(" a.RDB$FIELD_POSITION ORDINAL_POSITION, a.RDB$FIELD_NAME
COLUMN_NAME, 3 INDEX_TYPE");
+ query.append(" FROM RDB$INDEX_SEGMENTS a, RDB$INDICES b WHERE
a.RDB$INDEX_NAME=b.RDB$INDEX_NAME AND b.RDB$RELATION_NAME = ?");
+
+ PreparedStatement stmt =
getConnection().prepareStatement(query.toString());
+ ResultSet indexData = null;
+
+ stmt.setString(1, getPlatformInfo().isUseDelimitedIdentifiers() ?
tableName : tableName.toUpperCase());
+
+ try
+ {
+ indexData = stmt.executeQuery();
+
+ while (indexData.next())
+ {
+ Map values = readColumns(indexData, getColumnsForIndex());
+
+ // we have to reverse the meaning of the unique flag
+ values.put("NON_UNIQUE",
Boolean.FALSE.equals(values.get("NON_UNIQUE")) ? Boolean.TRUE : Boolean.FALSE);
+ // and trim the names
+ values.put("INDEX_NAME",
((String)values.get("INDEX_NAME")).trim());
+ values.put("TABLE_NAME",
((String)values.get("TABLE_NAME")).trim());
+ values.put("COLUMN_NAME",
((String)values.get("COLUMN_NAME")).trim());
+ readIndex(metaData, values, indices);
+ }
+ }
+ finally
+ {
+ if (indexData != null)
+ {
+ indexData.close();
}
}
+ return indices.values();
}
+
+ /**
+ * [EMAIL PROTECTED]
+ */
+ protected boolean isInternalPrimaryKeyIndex(Table table, Index index)
+ {
+ // Firebird generates an unique index for the pks of the form
"RDB$PRIMARY825"
+ return index.getName().startsWith("RDB$PRIMARY");
+ }
+
+ /**
+ * [EMAIL PROTECTED]
+ */
+ protected boolean isInternalForeignKeyIndex(Table table, ForeignKey fk,
Index index)
+ {
+ // Firebird generates a normal index that has the same name as
the fk
+ return fk.getName().equals(index.getName());
+ }
+
+
}
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdPlatform.java
URL:
http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdPlatform.java?rev=381820&r1=381819&r2=381820&view=diff
==============================================================================
---
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdPlatform.java
(original)
+++
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/firebird/FirebirdPlatform.java
Tue Feb 28 15:20:10 2006
@@ -62,9 +62,8 @@
info.setIndicesEmbedded(false);
info.setCommentPrefix("/*");
info.setCommentSuffix("*/");
- info.setSupportingDelimitedIdentifiers(false);
+ //info.setSupportingDelimitedIdentifiers(false);
- // BINARY and VARBINARY are also handled by the
InterbaseBuilder.getSqlType method
info.addNativeTypeMapping(Types.ARRAY, "BLOB",
Types.LONGVARBINARY);
info.addNativeTypeMapping(Types.BINARY, "BLOB",
Types.LONGVARBINARY);
info.addNativeTypeMapping(Types.BIT, "SMALLINT",
Types.SMALLINT);
@@ -78,6 +77,7 @@
info.addNativeTypeMapping(Types.LONGVARCHAR, "BLOB SUB_TYPE TEXT");
info.addNativeTypeMapping(Types.NULL, "BLOB",
Types.LONGVARBINARY);
info.addNativeTypeMapping(Types.OTHER, "BLOB",
Types.LONGVARBINARY);
+ // This is back-mapped to REAL in the model reader
info.addNativeTypeMapping(Types.REAL, "FLOAT");
info.addNativeTypeMapping(Types.TINYINT, "SMALLINT",
Types.SMALLINT);
info.addNativeTypeMapping(Types.REF, "BLOB",
Types.LONGVARBINARY);
@@ -87,17 +87,8 @@
info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT");
info.addNativeTypeMapping("DATALINK", "BLOB", "LONGVARBINARY");
- /*
- * This value is set to 128, to give multiple column index a chance
- * to stay below the maximum key size of 256.
- * If you use different encodings, you most likely need to decrease
this value.
- */
- // TODO: Why should we care - after all this is a database problem and
not a
- // DdlUtils one ? This value should be the one specified by JDBC
which is 254
- // Also, do we really need to specify a default size for
SMALLINT ?
- info.addDefaultSize(Types.VARCHAR, 128);
- info.addDefaultSize(Types.CHAR, 128);
- info.addDefaultSize(Types.SMALLINT, 5);
+ info.addDefaultSize(Types.VARCHAR, 254);
+ info.addDefaultSize(Types.CHAR, 254);
setSqlBuilder(new FirebirdBuilder(info));
setModelReader(new FirebirdModelReader(info));
Modified: db/ddlutils/trunk/src/test/jdbc.properties.firebird
URL:
http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/test/jdbc.properties.firebird?rev=381820&r1=381819&r2=381820&view=diff
==============================================================================
--- db/ddlutils/trunk/src/test/jdbc.properties.firebird (original)
+++ db/ddlutils/trunk/src/test/jdbc.properties.firebird Tue Feb 28 15:20:10 2006
@@ -11,7 +11,7 @@
datasource.class=org.apache.commons.dbcp.BasicDataSource
datasource.driverClassName=org.firebirdsql.jdbc.FBDriver
-datasource.url=jdbc:firebirdsql://10.21.21.33:3050/c:/data/firebird/DDLUTILS
+datasource.url=jdbc:firebirdsql://localhost/C:/Programme/Firebird/Firebird_1_5/data/ddlutils.fdb
datasource.username=SYSDBA
datasource.password=masterkey