]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-2496,CSPACE-3550: Initial preparation for using database product-specific...
authorAron Roberts <aron@socrates.berkeley.edu>
Sat, 8 Jan 2011 01:45:40 +0000 (01:45 +0000)
committerAron Roberts <aron@socrates.berkeley.edu>
Sat, 8 Jan 2011 01:45:40 +0000 (01:45 +0000)
services/common/src/main/config/services/tenant-bindings.xml
services/common/src/main/java/org/collectionspace/services/common/init/AddIndices.java
services/common/src/main/java/org/collectionspace/services/common/init/InitHandler.java
services/common/src/main/java/org/collectionspace/services/common/init/MakeLargeTextFields.java [deleted file]
services/common/src/main/java/org/collectionspace/services/common/init/ModifyFieldDatatypes.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/storage/DatabaseProductType.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java

index dea3ab26db78167429bfe8bb0375235d7e2470eb..15deeec2c35a4af7ef1633620115317651a8a8d5 100644 (file)
                 org.collectionspace.services.collectionobject.nuxeo.CollectionObjectValidatorHandler
             </service:validatorHandler>
             <service:initHandler xmlns:service='http://collectionspace.org/services/common/service'>
-                <service:classname>org.collectionspace.services.common.init.MakeLargeTextFields</service:classname>
+                <service:classname>org.collectionspace.services.common.init.ModifyFieldDatatypes</service:classname>
                 <service:params>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_briefdescriptions</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
                     <service:field>
                         <service:table>nuxeo.collectionobjects_common_comments</service:table>
                         <service:col>item</service:col>
-                        <service:type>TEXT</service:type>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_objectproductionreasons</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_ownersreferences</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_viewersreferences</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
                         <service:param></service:param>
                     </service:field>
                 </service:params>
             <service:validatorHandler xmlns:service='http://collectionspace.org/services/common/service'>
                 org.collectionspace.services.collectionobject.nuxeo.CollectionObjectValidatorHandler
             </service:validatorHandler>
+            <service:initHandler xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:classname>org.collectionspace.services.common.init.ModifyFieldDatatypes</service:classname>
+                <service:params>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_briefdescriptions</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_comments</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_objectproductionreasons</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_ownersreferences</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                    <service:field>
+                        <service:table>nuxeo.collectionobjects_common_viewersreferences</service:table>
+                        <service:col>item</service:col>
+                        <service:type>LARGETEXT</service:type>
+                        <service:param></service:param>
+                    </service:field>
+                </service:params>
+            </service:initHandler>
             <service:properties xmlns:service='http://collectionspace.org/services/common/service'>
                 <types:item><types:key>objectNameProperty</types:key><types:value>objectName</types:value></types:item>
                 <types:item><types:key>objectNumberProperty</types:key><types:value>objectNumber</types:value></types:item>
index 018e7082b717f67f9f291854d52a8f80445f4be0..1a340fa8267870d2b3f60da24becbb8ddeffbcb1 100755 (executable)
@@ -20,32 +20,47 @@ package org.collectionspace.services.common.init;
 import org.collectionspace.services.common.service.ServiceBindingType;\r
 import org.collectionspace.services.common.service.InitHandler.Params.Field;\r
 import org.collectionspace.services.common.service.InitHandler.Params.Property;\r
+import org.collectionspace.services.common.storage.DatabaseProductType;\r
 \r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
-import java.sql.ResultSet;\r
 import java.util.List;\r
 \r
 /**\r
- * User: laramie\r
- * $LastChangedRevision:  $\r
- * $LastChangedDate:  $\r
+ * AddIndices, post-init action to add indexes to the database.\r
+ *\r
+ * $LastChangedRevision: $\r
+ * $LastChangedDate: $\r
  */\r
 public class AddIndices extends InitHandler implements IInitHandler {\r
 \r
     final Logger logger = LoggerFactory.getLogger(AddIndices.class);\r
+    private final static String INDEX_SUFFIX = "_idx";\r
 \r
+    @Override\r
     public void onRepositoryInitialized(ServiceBindingType sbt, List<Field> fields, List<Property> properties) throws Exception {\r
         //todo: all post-init tasks for services, or delegate to services that override.\r
-\r
-        // call something like this:\r
         int rows = 0;\r
+        String sql = "";\r
+        if (logger.isInfoEnabled()) {\r
+            logger.info("Modifying field datatypes for " + sbt.getName()\r
+                    + " for repository domain " + sbt.getRepositoryDomain().trim() + "...");\r
+        }\r
+        DatabaseProductType databaseProductType = getDatabaseProductType();\r
         for (Field field : fields) {\r
             try {\r
-                // MySQL\r
-                String addIndex_SQL = "CREATE INDEX " + field.getCol() + "_idx ON " + field.getTable() + " (" + field.getCol() + ")";\r
-                rows = executeUpdate(addIndex_SQL);\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
+                    sql = "CREATE INDEX " + field.getCol() + INDEX_SUFFIX + " ON " + field.getTable() + " (" + field.getCol() + ")";\r
+                } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
+                    sql = "CREATE INDEX ON " + field.getTable() + " (" + field.getCol() + ")";\r
+                } else {\r
+                    throw new Exception("Unrecognized database system " + databaseProductType);\r
+                }\r
+                rows = executeUpdate(sql);\r
             } catch (Exception e) {\r
                 throw e;\r
             }\r
index fc0f40880a3c73aacdb3a479b30252f01c1a85c2..9ab73478fbca11634bb84558f7c714e3baf13f24 100755 (executable)
@@ -17,6 +17,7 @@
  */\r
 package org.collectionspace.services.common.init;\r
 \r
+import org.collectionspace.services.common.storage.DatabaseProductType;\r
 import org.collectionspace.services.common.storage.JDBCTools;\r
 import org.collectionspace.services.common.service.ServiceBindingType;\r
 import org.collectionspace.services.common.service.InitHandler.Params.Field;\r
@@ -78,4 +79,8 @@ public class InitHandler implements IInitHandler {
     public int executeUpdate(String sql) throws Exception {\r
         return JDBCTools.executeUpdate(sql);\r
     }\r
+\r
+    public DatabaseProductType getDatabaseProductType() throws Exception {\r
+        return JDBCTools.getDatabaseProductType();\r
+    }\r
 }\r
diff --git a/services/common/src/main/java/org/collectionspace/services/common/init/MakeLargeTextFields.java b/services/common/src/main/java/org/collectionspace/services/common/init/MakeLargeTextFields.java
deleted file mode 100644 (file)
index 549106f..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * This document is a part of the source code and related artifacts
- * for CollectionSpace, an open source collections management system
- * for museums and related institutions:
- *
- * http://www.collectionspace.org
- * http://wiki.collectionspace.org
- *
- * Copyright © 2009 Regents of the University of California
- *
- * Licensed under the Educational Community License (ECL), Version 2.0.
- * You may not use this file except in compliance with this License.
- *
- * You may obtain a copy of the ECL 2.0 License at
- * https://source.collectionspace.org/collection-space/LICENSE.txt
- *
- * 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.
- */
-package org.collectionspace.services.common.init;
-
-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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * MakeLargeTextFields, post-init action to configure text fields
- * that must hold large amounts of text.
- *
- * $LastChangedRevision: $
- * $LastChangedDate: $
- */
-public class MakeLargeTextFields extends InitHandler implements IInitHandler {
-
-    final Logger logger = LoggerFactory.getLogger(MakeLargeTextFields.class);
-
-    @Override
-    public void onRepositoryInitialized(ServiceBindingType sbt, List<Field> fields, List<Property> properties) throws Exception {
-        //todo: all post-init tasks for services, or delegate to services that override.
-        int rows = 0;
-        try {
-            for (Field field : fields) {
-                // MySQL
-                String sql = "ALTER TABLE " + field.getTable() + " MODIFY COLUMN " + field.getCol() + " " + field.getType();
-                // PostgreSQL
-                // String sql = "ALTER TABLE " + field.getTable() + " ALTER COLUMN " + field.getCol() + " " + field.getType();
-                rows = executeUpdate(sql);
-            }
-        } catch (Exception e) {
-            throw e;
-        }
-    }
-}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/init/ModifyFieldDatatypes.java b/services/common/src/main/java/org/collectionspace/services/common/init/ModifyFieldDatatypes.java
new file mode 100644 (file)
index 0000000..c0fcea3
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright © 2009 Regents of the University of California
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ *
+ * 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.
+ */
+package org.collectionspace.services.common.init;
+
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ModifyFieldDatatypes, post-init action to configure the database
+ * datatypes of individual fields.
+ *
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ */
+public class ModifyFieldDatatypes extends InitHandler implements IInitHandler {
+
+    final Logger logger = LoggerFactory.getLogger(ModifyFieldDatatypes.class);
+
+    @Override
+    public void onRepositoryInitialized(ServiceBindingType sbt, List<Field> fields, List<Property> properties) throws Exception {
+        //todo: all post-init tasks for services, or delegate to services that override.
+        int rows = 0;
+        String sql = "";
+        if (logger.isInfoEnabled()) {
+            logger.info("Modifying field datatypes for " + sbt.getName()
+                    + " for repository domain " + sbt.getRepositoryDomain().trim() + "...");
+        }
+        try {
+            DatabaseProductType databaseProductType = getDatabaseProductType();
+            String datatype = "";
+            for (Field field : fields) {
+                datatype = getDatatypeFromLogicalType(databaseProductType, field.getType());
+                // TODO: Consider refactoring this '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) {
+                    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;
+                } else {
+                    throw new Exception("Unrecognized database system.");
+                }
+                rows = executeUpdate(sql);
+            }
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    // TODO: Refactor this method to a general-purpose mechanism for retrieving
+    // datatypes appropriate to a particular database product, that corresponds
+    // to logical datatypes such as "LARGETEXT".
+    //
+    // Currently, this is hard-coded to a single logical datatype.
+    private String getDatatypeFromLogicalType(DatabaseProductType databaseProductType, String logicalDatatype) throws Exception {
+        final String LARGE_TEXT_DATATYPE = "LARGETEXT";
+        String datatype = "";
+        if (!logicalDatatype.equalsIgnoreCase(LARGE_TEXT_DATATYPE)) {
+            throw new Exception("Unrecognized logical datatype " + logicalDatatype);
+        }
+        if (databaseProductType == DatabaseProductType.MYSQL) {
+            datatype = "TEXT";
+        } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {
+            datatype = "TEXT";
+        } else {
+            throw new Exception("Unrecognized database system " + databaseProductType);
+        }
+        return datatype;
+    }
+}
diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/DatabaseProductType.java b/services/common/src/main/java/org/collectionspace/services/common/storage/DatabaseProductType.java
new file mode 100644 (file)
index 0000000..20adc55
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ *  This document is a part of the source code and related artifacts
+ *  for CollectionSpace, an open source collections management system
+ *  for museums and related institutions:
+
+ *  http://www.collectionspace.org
+ *  http://wiki.collectionspace.org
+
+ *  Copyright 2009 University of California at Berkeley
+
+ *  Licensed under the Educational Community License (ECL), Version 2.0.
+ *  You may not use this file except in compliance with this License.
+
+ *  You may obtain a copy of the ECL 2.0 License at
+
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.common.storage;
+
+/**
+ * $LastChangedRevision:  $
+ * $LastChangedDate:  $
+ */
+public class DatabaseProductType {
+
+    private final String name;
+    private final String propertiesFileName;
+    private static final String PROPERTIES_FILE_SUFFIX = ".properties";
+
+    private DatabaseProductType(String name) {
+        this.name = name;
+        propertiesFileName = name + PROPERTIES_FILE_SUFFIX;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    public String getPropertiesFileName() {
+        return propertiesFileName;
+    }
+
+    public static final DatabaseProductType MYSQL = new DatabaseProductType("mysql");
+    public static final DatabaseProductType POSTGRESQL = new DatabaseProductType("postgresql");
+
+    public static final DatabaseProductType UNRECOGNIZED = new DatabaseProductType("unrecognized");
+}
index 2fb7c16f496ff99c89872e6fb88dab2e5d019a8d..ae74f164486f9a3855d3c4a20e2315a0f0bc887c 100755 (executable)
@@ -15,7 +15,6 @@
 \r
  *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
  */\r
-\r
 package org.collectionspace.services.common.storage;\r
 \r
 import org.collectionspace.services.common.ServiceMain;\r
@@ -43,8 +42,8 @@ public class JDBCTools {
     final static Logger logger = LoggerFactory.getLogger(JDBCTools.class);\r
 \r
     public static Connection getConnection(String repositoryName) throws LoginException, SQLException {\r
-        if (Tools.isEmpty(repositoryName)){\r
-            repositoryName = ServiceMain.DEFAULT_REPOSITORY_NAME;\r
+        if (Tools.isEmpty(repositoryName)) {\r
+            repositoryName = getDefaultRepositoryName();\r
         }\r
         InitialContext ctx = null;\r
         Connection conn = null;\r
@@ -72,15 +71,15 @@ public class JDBCTools {
 \r
     public static ResultSet executeQuery(String sql) throws Exception {\r
         Connection conn = null;\r
-       Statement stmt = null;\r
+        Statement stmt = null;\r
         try {\r
-               conn = JDBCTools.getConnection(ServiceMain.DEFAULT_REPOSITORY_NAME);\r
-               stmt = conn.createStatement();\r
-                       ResultSet rs = stmt.executeQuery(sql);\r
-                       stmt.close();\r
+            conn = getConnection(getDefaultRepositoryName());\r
+            stmt = conn.createStatement();\r
+            ResultSet rs = stmt.executeQuery(sql);\r
+            stmt.close();\r
             return rs;  //don't call rs.close() here ... Let caller close and catch any exceptions.\r
         } catch (RuntimeException rte) {\r
-            logger.debug("Exception in createDefaultAccounts: "+rte.getLocalizedMessage());\r
+            logger.debug("Exception in createDefaultAccounts: " + rte.getLocalizedMessage());\r
             logger.debug(rte.getStackTrace().toString());\r
             throw rte;\r
         } catch (SQLException sqle) {\r
@@ -90,30 +89,33 @@ public class JDBCTools {
                 tempException = tempException.getNextException();\r
             }\r
             logger.debug(sqle.getStackTrace().toString());\r
-            throw new RuntimeException("SQL problem in openResultSet: ", sqle);\r
+            throw new RuntimeException("SQL problem in executeQuery: ", sqle);\r
         } finally {\r
-               try {\r
-               if(conn!=null) conn.close();\r
-               if(stmt!=null) stmt.close();\r
+            try {\r
+                if (conn != null) {\r
+                    conn.close();\r
+                }\r
+                if (stmt != null) {\r
+                    stmt.close();\r
+                }\r
             } catch (SQLException sqle) {\r
-                logger.debug("SQL Exception closing statement/connection in openResultSet: "+ sqle.getLocalizedMessage());\r
+                logger.debug("SQL Exception closing statement/connection in executeQuery: " + sqle.getLocalizedMessage());\r
                 return null;\r
-               }\r
+            }\r
         }\r
-\r
     }\r
 \r
     public static int executeUpdate(String sql) throws Exception {\r
         Connection conn = null;\r
         Statement stmt = null;\r
         try {\r
-            conn = JDBCTools.getConnection(ServiceMain.DEFAULT_REPOSITORY_NAME);\r
+            conn = getConnection(getDefaultRepositoryName());\r
             stmt = conn.createStatement();\r
             int rows = stmt.executeUpdate(sql);\r
             stmt.close();\r
             return rows;\r
         } catch (RuntimeException rte) {\r
-            logger.debug("Exception in update: " + rte.getLocalizedMessage());\r
+            logger.debug("Exception in executeUpdate: " + rte.getLocalizedMessage());\r
             logger.debug(rte.getStackTrace().toString());\r
             throw rte;\r
         } catch (SQLException sqle) {\r
@@ -123,7 +125,7 @@ public class JDBCTools {
                 tempException = tempException.getNextException();\r
             }\r
             logger.debug(sqle.getStackTrace().toString());\r
-            throw new RuntimeException("SQL problem in update: ", sqle);\r
+            throw new RuntimeException("SQL problem in executeUpdate: ", sqle);\r
         } finally {\r
             try {\r
                 if (conn != null) {\r
@@ -133,11 +135,50 @@ public class JDBCTools {
                     stmt.close();\r
                 }\r
             } catch (SQLException sqle) {\r
-                logger.debug("SQL Exception closing statement/connection in openResultSet: " + sqle.getLocalizedMessage());\r
+                logger.debug("SQL Exception closing statement/connection in executeUpdate: " + sqle.getLocalizedMessage());\r
                 return -1;\r
             }\r
         }\r
+    }\r
 \r
+    public static String getDatabaseProductName() {\r
+        String productName = "";\r
+        Connection conn = null;\r
+        try {\r
+            conn = getConnection(getDefaultRepositoryName());\r
+            productName = conn.getMetaData().getDatabaseProductName();\r
+        } catch (Exception e) {\r
+        } finally {\r
+            try {\r
+                if (conn != null) {\r
+                    conn.close();\r
+                }\r
+            } catch (SQLException sqle) {\r
+                logger.debug("SQL Exception closing statement/connection in getDatabaseProductName: " + sqle.getLocalizedMessage());\r
+                return productName;\r
+            }\r
+        }\r
+        return productName;\r
     }\r
+    \r
+        public static DatabaseProductType getDatabaseProductType() throws Exception {\r
+            DatabaseProductType productType = DatabaseProductType.UNRECOGNIZED;\r
+            try {\r
+                String productName = getDatabaseProductName();\r
+                if (productName.matches("(?i).*mysql.*")) {\r
+                    productType = DatabaseProductType.MYSQL;\r
+                } else if (productName.matches("(?i).*postgresql.*")) {\r
+                    productType = DatabaseProductType.POSTGRESQL;\r
+                } else {\r
+                    throw new Exception("Unrecognized database system " + productName);\r
+                }\r
+            } catch (Exception e) {\r
+                throw e;\r
+            }\r
+            return productType;\r
+        }\r
 \r
+    public static String getDefaultRepositoryName() {\r
+        return ServiceMain.DEFAULT_REPOSITORY_NAME;\r
+    }\r
 }\r