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>
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
*/\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
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
+++ /dev/null
-/**
- * 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;
- }
- }
-}
--- /dev/null
+/**
+ * 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;
+ }
+}
--- /dev/null
+/**
+ * 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");
+}
\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
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
\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
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
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
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