]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-3621: Post-init handler to modify field datatypes now checks whether the targe...
authorAron Roberts <aron@socrates.berkeley.edu>
Mon, 7 Mar 2011 23:02:45 +0000 (23:02 +0000)
committerAron Roberts <aron@socrates.berkeley.edu>
Mon, 7 Mar 2011 23:02:45 +0000 (23:02 +0000)
services/common/src/main/java/org/collectionspace/services/common/init/AddIndices.java
services/common/src/main/java/org/collectionspace/services/common/init/ModifyFieldDatatypes.java

index 5295d666e434ecad3b8b97d9ed194ba9d3f9fa20..1b4a5438fa5df1ef81fae73f5a9efae17597c8ca 100755 (executable)
  */\r
 package org.collectionspace.services.common.init;\r
 \r
+import java.sql.Connection;\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+import java.sql.Statement;\r
+import java.util.List;\r
+\r
 import org.collectionspace.services.common.Tools;\r
 import org.collectionspace.services.common.service.ServiceBindingType;\r
 import org.collectionspace.services.common.service.InitHandler.Params.Field;\r
@@ -27,13 +33,6 @@ import org.collectionspace.services.common.storage.JDBCTools;
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
-import java.sql.Connection;\r
-import java.sql.ResultSet;\r
-import java.sql.SQLException;\r
-import java.sql.Statement;\r
-\r
-import java.util.List;\r
-\r
 /**\r
  * AddIndices, post-init action to add indexes to the database.\r
  * \r
@@ -112,34 +111,32 @@ public class AddIndices extends InitHandler implements IInitHandler {
         String indexName = columnName + INDEX_SUFFIX;\r
         try {\r
             DatabaseProductType databaseProductType = JDBCTools.getDatabaseProductType();\r
+            if (indexExists(databaseProductType, tableName, indexName)) {\r
+                logger.trace("Index already exists for column " + columnName\r
+                        + " in table " + tableName);\r
+                // FIXME: Can add the option to drop and re-create an index here.\r
+                // For example, see MySQL documentation on DROP INDEX.\r
+                return 0;\r
+            }\r
             // TODO: Consider refactoring this 'if' statement to a general-purpose\r
             // mechanism for retrieving and populating catalog/DDL-type SQL statements\r
             // appropriate to a particular database product.\r
             if (databaseProductType == DatabaseProductType.MYSQL) {\r
-                // If the index already exists, do nothing.\r
-                if (indexExists(databaseProductType, tableName, indexName)) {\r
-                    // FIXME: Can add the option to drop and re-create an index here.\r
-                    // See MySQL documentation on DROP INDEX.\r
-                } else {\r
-                    sql = "CREATE INDEX " + indexName + " ON " + tableName + " (" + columnName + ")";\r
-                }\r
+                 logger.trace("Creating index for column " + columnName + " in table " + tableName);\r
+                 sql = "CREATE INDEX " + indexName + " ON " + tableName + " (" + columnName + ")";\r
             } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
-                if (indexExists(databaseProductType, tableName, indexName)) {\r
-                    // FIXME: Can add the option to reindex an existing index here.\r
-                    // See PostgreSQL documentation on REINDEX.\r
-                } else {\r
-                    sql = "CREATE INDEX ON " + tableName + " (" + columnName + ")";\r
-                }\r
+                 logger.trace("Creating index for column " + columnName + " in table " + tableName);\r
+                sql = "CREATE INDEX ON " + tableName + " (" + columnName + ")";\r
             } else {\r
                 throw new Exception("Unrecognized database system " + databaseProductType);\r
             }\r
             if (sql != null && ! sql.trim().isEmpty()) {\r
                 rows = JDBCTools.executeUpdate(sql);\r
-                logger.info("Index added to column ("+columnName+") on table ("+tableName+")");\r
+                logger.trace("Index added to column ("+columnName+") on table ("+tableName+")");\r
             }\r
             return rows;\r
         } catch (Throwable e) {\r
-            logger.info("Index NOT added to column ("+columnName+") on table ("+tableName+") SQL: "+sql+" ERROR: "+e);\r
+            logger.debug("Index NOT added to column ("+columnName+") on table ("+tableName+") SQL: "+sql+" ERROR: "+e);\r
             return -1;\r
         }\r
     }\r
@@ -152,24 +149,25 @@ public class AddIndices extends InitHandler implements IInitHandler {
         Connection conn = null;\r
         Statement stmt = null;\r
         ResultSet rs = null;\r
+\r
+        if (databaseProductType == DatabaseProductType.MYSQL) {\r
+            sql = "SHOW INDEX FROM " + tableName + " WHERE key_name='" + indexName + "'";\r
+        } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
+            // FIXME: Add comparable SQL statement for PostgreSQL.\r
+        }\r
+\r
         try {\r
-            if (databaseProductType == DatabaseProductType.MYSQL) {\r
-                sql = "SHOW INDEX FROM " + tableName + " WHERE key_name='"\r
-                        + indexName + "'";\r
-                conn = JDBCTools.getConnection(JDBCTools.getDefaultRepositoryName());\r
-                stmt = conn.createStatement();\r
-                rs = stmt.executeQuery(sql);\r
-                if (rs.last()) {\r
-                   rows = rs.getRow();\r
-                }\r
-                rs.close();\r
-                stmt.close();\r
-                conn.close();\r
-                if (rows > 0) {\r
-                    indexExists = true;\r
-                }\r
-            } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
-                // FIXME: Add comparable logic for PostgreSQL.\r
+            conn = JDBCTools.getConnection(JDBCTools.getDefaultRepositoryName());\r
+            stmt = conn.createStatement();\r
+            rs = stmt.executeQuery(sql);\r
+            if (rs.last()) {\r
+               rows = rs.getRow();\r
+            }\r
+            rs.close();\r
+            stmt.close();\r
+            conn.close();\r
+            if (rows > 0) {\r
+                indexExists = true;\r
             }\r
         } catch (Exception e) {\r
             logger.debug("Error when identifying whether index exists in table "\r
index 0e72c503decdd08cc10afc811d52ebe8b41e0816..7678df18475eb89bd875d62a01431611a0557d8a 100644 (file)
  */
 package org.collectionspace.services.common.init;
 
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.List;
+
 import org.collectionspace.services.common.service.ServiceBindingType;
 import org.collectionspace.services.common.service.InitHandler.Params.Field;
 import org.collectionspace.services.common.service.InitHandler.Params.Property;
 import org.collectionspace.services.common.storage.DatabaseProductType;
 import org.collectionspace.services.common.storage.JDBCTools;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,13 +62,21 @@ public class ModifyFieldDatatypes extends InitHandler implements IInitHandler {
             String datatype = "";
             for (Field field : fields) {
                 datatype = getDatatypeFromLogicalType(databaseProductType, field.getType());
-                // TODO: Consider refactoring this 'if' statement to a general-purpose
+                // If the field is already of the desired datatype, skip it.
+                if (fieldHasDesiredDatatype(databaseProductType, field, datatype)) {
+                    logger.trace("Field " + field.getTable() + "." + field.getCol()
+                            + " is already of desired datatype " + datatype);
+                    continue;
+                }
+                // TODO: Consider refactoring this nested 'if' statement to a general-purpose
                 // mechanism for retrieving and populating catalog/DDL-type SQL statements
                 // appropriate to a particular database product.
                 if (databaseProductType == DatabaseProductType.MYSQL) {
+                    logger.trace("Modifying field " + field.getTable() + "."
+                            + field.getCol() + " to datatype " + datatype);
                     sql = "ALTER TABLE " + field.getTable() + " MODIFY COLUMN " + field.getCol() + " " + datatype;
                 } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {
-                    sql = "ALTER TABLE " + field.getTable() + " ALTER COLUMN " + field.getCol() + " " + datatype;
+                        sql = "ALTER TABLE " + field.getTable() + " ALTER COLUMN " + field.getCol() + " " + datatype;
                 } else {
                     throw new Exception("Unrecognized database system.");
                 }
@@ -73,7 +87,7 @@ public class ModifyFieldDatatypes extends InitHandler implements IInitHandler {
         }
     }
 
-    // TODO: Refactor this method to a general-purpose mechanism for retrieving
+    // TODO: Consider refactoring this method to a general-purpose mechanism for retrieving
     // datatypes appropriate to a particular database product, that corresponds
     // to logical datatypes such as "LARGETEXT".
     //
@@ -93,4 +107,82 @@ public class ModifyFieldDatatypes extends InitHandler implements IInitHandler {
         }
         return datatype;
     }
+
+    private boolean fieldHasDesiredDatatype(DatabaseProductType databaseProductType,
+            Field field, String datatype) {
+
+        boolean fieldHasDesiredDatatype = false;
+        int rows = 0;
+        String sql = "";
+        String currentDatatype = "";
+        Connection conn = null;
+        Statement stmt = null;
+        ResultSet rs = null;
+
+        if (databaseProductType == DatabaseProductType.MYSQL) {
+            sql = "SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS "
+                    + "WHERE TABLE_SCHEMA = '" + getDatabaseName(field) + "'"
+                    + " AND TABLE_NAME = '" + getTableName(field) + "'"
+                    + " AND COLUMN_NAME = '" + field.getCol() + "'";
+        } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {
+            // FIXME: Add comparable SQL statement for PostgreSQL.
+        }
+
+        try {
+            conn = JDBCTools.getConnection(JDBCTools.getDefaultRepositoryName());
+            stmt = conn.createStatement();
+            rs = stmt.executeQuery(sql);
+            while (rs.next()) {
+                currentDatatype = rs.getString(1);
+            }
+            if (datatype.equalsIgnoreCase(currentDatatype)) {
+                fieldHasDesiredDatatype = true;
+            }
+            rs.close();
+            stmt.close();
+            conn.close();
+        } catch (Exception e) {
+            logger.debug("Error when identifying datatype of field " + field.getCol()
+                    + " in table " + field.getTable() + ":" + e.getMessage());
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (stmt != null) {
+                    stmt.close();
+                }
+                if (conn != null) {
+                    conn.close();
+                }
+            } catch (SQLException sqle) {
+                logger.debug("SQL Exception closing statement/connection in ModifyFieldDatatypes: " + sqle.getLocalizedMessage());
+            }
+        }
+        return fieldHasDesiredDatatype;
+    }
+
+    // FIXME: Hacks to separate the '.'-delimited database/schema name
+    // from the table name in field.getTable, where that value is
+    // specified in tenant bindings configuration as 'database.table'.
+    //
+    // Even as the current hack, this logic should reside in Field, not here.
+
+    private String getDatabaseName(Field field) {
+        String databaseName = field.getTable();
+        String[] databaseAndTable = databaseName.split("\\.", 2);
+        if (! databaseAndTable[0].isEmpty()) {
+            databaseName = databaseAndTable[0];
+        }
+        return databaseName;
+    }
+
+    private String getTableName(Field field) {
+        String tableName = field.getTable();
+        String[] databaseAndTable = tableName.split("\\.", 2);
+        if (! databaseAndTable[1].isEmpty()) {
+            tableName = databaseAndTable[1];
+        }
+        return tableName;
+    }
 }