db-ddlutils-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject svn commit: r359532 - in /db/ddlutils/trunk/src/java/org/apache/ddlutils/platform: DerbyModelReader.java DerbyPlatform.java JdbcModelReader.java
Date Wed, 28 Dec 2005 14:03:57 GMT
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
+{
+    /**
+     * {@inheritDoc}
+     */
+    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;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    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 {@link #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 {@link #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 {@link #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 {@link #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 {@link #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);
+        }
     }
 
     /**



Mime
View raw message