Author: tomdz
Date: Wed Dec 28 06:03:52 2005
New Revision: 359532
URL: http://svn.apache.org/viewcvs?rev=359532&view=rev
Log:
Finished restructuring of the jdbc model reader
Added specilization for reading Derby models via jdbc meta data
Added:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyModelReader.java
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyPlatform.java
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java
Added:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyModelReader.java
URL:
http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyModelReader.java?rev=359532&view=auto
==============================================================================
---
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyModelReader.java
(added)
+++
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyModelReader.java
Wed Dec 28 06:03:52 2005
@@ -0,0 +1,161 @@
+package org.apache.ddlutils.platform;
+
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ddlutils.model.Column;
+import org.apache.ddlutils.model.ForeignKey;
+import org.apache.ddlutils.model.Index;
+import org.apache.ddlutils.model.Table;
+
+/**
+ * Reads a database model from a Derby database.
+ *
+ * @author Thomas Dudziak
+ * @version $Revision: $
+ */
+public class DerbyModelReader extends JdbcModelReader
+{
+ /**
+ * [EMAIL PROTECTED]
+ */
+ protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values)
throws SQLException
+ {
+ Column column = super.readColumn(metaData, values);
+ String defaultValue = column.getDefaultValue();
+
+ if (defaultValue != null)
+ {
+ // we check for these strings
+ // GENERATED_BY_DEFAULT -> 'GENERATED BY DEFAULT
AS IDENTITY'
+ // AUTOINCREMENT: start 1 increment 1 -> 'GENERATED ALWAYS AS
IDENTITY'
+ if ("GENERATED_BY_DEFAULT".equals(defaultValue) ||
defaultValue.startsWith("AUTOINCREMENT:"))
+ {
+ column.setDefaultValue(null);
+ column.setAutoIncrement(true);
+ }
+ }
+ return column;
+ }
+
+ /**
+ * [EMAIL PROTECTED]
+ */
+ protected Table readTable(DatabaseMetaDataWrapper metaData, Map values)
throws SQLException
+ {
+ Table table = super.readTable(metaData, values);
+ Column[] pks = table.getPrimaryKeyColumns();
+ List columnNames = new ArrayList();
+
+ for (int columnIdx = 0; columnIdx < pks.length; columnIdx++)
+ {
+ columnNames.add(pks[columnIdx].getName());
+ }
+
+ // Derby returns a unique index for the pk which we don't want however
+ int indexIdx = findMatchingInternalIndex(table, columnNames, true);
+
+ if (indexIdx >= 0)
+ {
+ table.removeIndex(indexIdx);
+ }
+
+ // Likewise, Derby returns a non-unique index for every foreign key
+ for (int fkIdx = 0; fkIdx < table.getForeignKeyCount(); fkIdx++)
+ {
+ ForeignKey fk = table.getForeignKey(fkIdx);
+
+ columnNames.clear();
+ for (int columnIdx = 0; columnIdx < fk.getReferenceCount();
columnIdx++)
+ {
+
columnNames.add(fk.getReference(columnIdx).getLocalColumnName());
+ }
+ indexIdx = findMatchingInternalIndex(table, columnNames, false);
+ if (indexIdx >= 0)
+ {
+ table.removeIndex(indexIdx);
+ }
+ }
+ return table;
+ }
+
+ /**
+ * Tries to find an internal index that matches the given columns.
+ *
+ * @param table The table
+ * @param columnsToSearchFor The names of the columns that the index
should be for
+ * @param unique Whether to search for an unique index
+ * @return The position of the index or <code>-1</code> if no such index
was found
+ */
+ private int findMatchingInternalIndex(Table table, List
columnsToSearchFor, boolean unique)
+ {
+ for (int indexIdx = 0; indexIdx < table.getIndexCount(); indexIdx++)
+ {
+ Index index = table.getIndex(indexIdx);
+
+ if ((unique == index.isUnique()) && (index.getColumnCount() ==
columnsToSearchFor.size()))
+ {
+ boolean found = true;
+
+ for (int columnIdx = 0; found && (columnIdx <
index.getColumnCount()); columnIdx++)
+ {
+ if
(!columnsToSearchFor.get(columnIdx).equals(index.getColumn(columnIdx).getName()))
+ {
+ found = false;
+ }
+ }
+
+ // if the index seems to be internal, we immediately return it
+ if (found && mightBeInternalIndex(index))
+ {
+ return indexIdx;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Guesses whether the index might be an internal index, i.e. one created
by Derby.
+ *
+ * @param index The index to check
+ * @return <code>true</code> if the index seems to be an internal one
+ */
+ private boolean mightBeInternalIndex(Index index)
+ {
+ String name = index.getName();
+
+ // Internal names normally have the form "SQL051228005030780"
+ if ((name != null) && name.startsWith("SQL"))
+ {
+ try
+ {
+ Long.parseLong(name.substring(3));
+ return true;
+ }
+ catch (NumberFormatException ex)
+ {
+ // we ignore it
+ }
+ }
+ return false;
+ }
+}
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyPlatform.java
URL:
http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyPlatform.java?rev=359532&r1=359531&r2=359532&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyPlatform.java
(original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/DerbyPlatform.java
Wed Dec 28 06:03:52 2005
@@ -53,6 +53,7 @@
super();
// we override the builder
setSqlBuilder(new DerbyBuilder(getSqlBuilder().getPlatformInfo()));
+ setModelReader(new DerbyModelReader());
}
/**
Modified:
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java
URL:
http://svn.apache.org/viewcvs/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java?rev=359532&r1=359531&r2=359532&view=diff
==============================================================================
---
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java
(original)
+++
db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java
Wed Dec 28 06:03:52 2005
@@ -395,7 +395,8 @@
while (tableData.next())
{
- Table table = readTable(metaData, tableData);
+ Map values = readColumns(tableData, getColumnsForTable());
+ Table table = readTable(metaData, values);
if (table != null)
{
@@ -416,13 +417,12 @@
/**
* Reads the next table from the meta data.
*
- * @param metaData The database meta data
- * @param tableMetaData The result set containing the table metadata
+ * @param metaData The database meta data
+ * @param values The table metadata values as defined by [EMAIL
PROTECTED] #getColumnsForTable()}
* @return The table or <code>null</code> if the result set row did not
contain a valid table
*/
- protected Table readTable(DatabaseMetaDataWrapper metaData, ResultSet
tableMetaData) throws SQLException
+ protected Table readTable(DatabaseMetaDataWrapper metaData, Map values)
throws SQLException
{
- Map values = readColumns(tableMetaData, getColumnsForTable());
String tableName = (String)values.get("TABLE_NAME");
Table table = null;
@@ -469,7 +469,9 @@
while (columnData.next())
{
- columns.add(readColumn(metaData, columnData));
+ Map values = readColumns(columnData, getColumnsForColumn());
+
+ columns.add(readColumn(metaData, values));
}
return columns;
}
@@ -485,14 +487,13 @@
/**
* Extracts a column definition from the result set.
*
- * @param metaData The database meta data
- * @param columnData The column meta data result set
+ * @param metaData The database meta data
+ * @param values The column meta data values as defined by [EMAIL
PROTECTED] #getColumnsForColumn()}
* @return The column
*/
- protected Column readColumn(DatabaseMetaDataWrapper metaData, ResultSet
columnData) throws SQLException
+ protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values)
throws SQLException
{
Column column = new Column();
- Map values = readColumns(columnData, getColumnsForColumn());
column.setName((String)values.get("COLUMN_NAME"));
column.setDefaultValue((String)values.get("COLUMN_DEF"));
@@ -537,7 +538,9 @@
pkData = metaData.getPrimaryKeys(tableName);
while (pkData.next())
{
- pks.add(readPrimaryKeyName(metaData, pkData));
+ Map values = readColumns(pkData, getColumnsForPK());
+
+ pks.add(readPrimaryKeyName(metaData, values));
}
}
finally
@@ -554,13 +557,11 @@
* Extracts a primary key name from the result set.
*
* @param metaData The database meta data
- * @param pkData The result set containing the meta data for the current
pk definition
+ * @param values The primary key meta data values as defined by [EMAIL
PROTECTED] #getColumnsForPK()}
* @return The primary key name
*/
- protected String readPrimaryKeyName(DatabaseMetaDataWrapper metaData,
ResultSet pkData) throws SQLException
+ protected String readPrimaryKeyName(DatabaseMetaDataWrapper metaData, Map
values) throws SQLException
{
- Map values = readColumns(pkData, getColumnsForPK());
-
return (String)values.get("COLUMN_NAME");
}
@@ -582,7 +583,9 @@
while (fkData.next())
{
- readForeignKey(metaData, fkData, fks);
+ Map values = readColumns(fkData, getColumnsForFK());
+
+ readForeignKey(metaData, values, fks);
}
}
finally
@@ -599,29 +602,40 @@
* Reads the next foreign key spec from the result set.
*
* @param metaData The database meta data
- * @param fkData The foreign key meta data
- * @param lastFk The foreign key that was read last
+ * @param values The foreign key meta data as defined by [EMAIL
PROTECTED] #getColumnsForFK()}
+ * @param knownFks The already read foreign keys for the current table
*/
- protected void readForeignKey(DatabaseMetaDataWrapper metaData, ResultSet
fkData, Map knownFks) throws SQLException
+ protected void readForeignKey(DatabaseMetaDataWrapper metaData, Map
values, Map knownFks) throws SQLException
{
- Map values = readColumns(fkData, getColumnsForFK());
- String fkName = (String)values.get("FK_NAME");
- ForeignKey fk = (ForeignKey)knownFks.get(fkName);
+ String fkName = (String)values.get("FK_NAME");
+ ForeignKey fk = (ForeignKey)knownFks.get(fkName);
if (fk == null)
{
fk = new ForeignKey(fkName);
fk.setForeignTableName((String)values.get("PKTABLE_NAME"));
+ knownFks.put(fkName, fk);
}
Reference ref = new Reference();
- short position = ((Short)values.get("KEY_SEQ")).shortValue();
+ int position = ((Short)values.get("KEY_SEQ")).intValue() - 1;
ref.setForeignColumnName((String)values.get("PKCOLUMN_NAME"));
ref.setLocalColumnName((String)values.get("FKCOLUMN_NAME"));
- // TODO: use position
- fk.addReference(ref);
+ if ((position < 0) || (position >= fk.getReferenceCount()))
+ {
+ while (fk.getReferenceCount() < position)
+ {
+ fk.addReference(null);
+ }
+ fk.addReference(ref);
+ }
+ else
+ {
+ fk.addReference(position, ref);
+ fk.removeReference(position + 1);
+ }
}
/**
@@ -642,7 +656,9 @@
while (indexData.next())
{
- readIndex(metaData, indexData, indices);
+ Map values = readColumns(indexData, getColumnsForIndex());
+
+ readIndex(metaData, values, indices);
}
}
finally
@@ -659,14 +675,13 @@
* Reads the next index spec from the result set.
*
* @param metaData The database meta data
- * @param indexData The index meta data
- * @param knownIndices The already known indices
+ * @param values The index meta data as defined by [EMAIL PROTECTED]
#getColumnsForIndex()}
+ * @param knownIndices The already read indices for the current table
*/
- protected void readIndex(DatabaseMetaDataWrapper metaData, ResultSet
indexData, Map knownIndices) throws SQLException
+ protected void readIndex(DatabaseMetaDataWrapper metaData, Map values, Map
knownIndices) throws SQLException
{
- Map values = readColumns(indexData, getColumnsForIndex());
- String indexName = (String)values.get("INDEX_NAME");
- Index index = (Index)knownIndices.get(indexName);
+ String indexName = (String)values.get("INDEX_NAME");
+ Index index = (Index)knownIndices.get(indexName);
if ((index == null) && (indexName != null))
{
@@ -684,11 +699,22 @@
}
IndexColumn ic = new IndexColumn();
- short position =
((Short)values.get("ORDINAL_POSITION")).shortValue();
+ int position =
((Short)values.get("ORDINAL_POSITION")).intValue() - 1;
ic.setName((String)values.get("COLUMN_NAME"));
- // TODO: use position
- index.addColumn(ic);
+ if ((position < 0) || (position >= index.getColumnCount()))
+ {
+ while (index.getColumnCount() < position)
+ {
+ index.addColumn(null);
+ }
+ index.addColumn(ic);
+ }
+ else
+ {
+ index.addColumn(position, ic);
+ index.removeColumn(position + 1);
+ }
}
/**