*/\r
package org.collectionspace.services.common.init;\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
import org.collectionspace.services.common.service.InitHandler.Params.Property;\r
\r
/**\r
* AddIndices, post-init action to add indexes to the database.\r
+ * \r
+ * In the configuration file, you may have sets of table names and column names, or you may use params to send a \r
+ * comma-separated list of column names and a table name. That is, both of these are equivalent:\r
+ * \r
+ * The single column per element version:\r
+ *\r
+ *\r
+ * <s:initHandler xmlns:s='http://collectionspace.org/services/common/service'>\r
+ <s:classname>org.collectionspace.services.common.init.AddIndices</s:classname>\r
+ <s:params>\r
+ <s:field>\r
+ <s:table>nuxeo.organizations_common</s:table>\r
+ <s:col>inAuthority</s:col>\r
+ </s:field>\r
+ <s:field>\r
+ <s:table>nuxeo.organizations_common</s:table>\r
+ <s:col>displayName</s:col>\r
+ </s:field>\r
+ <s:field>\r
+ <s:table>nuxeo.organizations_common</s:table>\r
+ <s:col>shortIdentifier</s:col>\r
+ </s:field>\r
+ </s:params>\r
+ </s:initHandler>\r
+\r
+ The csv version:\r
+\r
+ <s:initHandler xmlns:s='http://collectionspace.org/services/common/service'>\r
+ <s:classname>org.collectionspace.services.common.init.AddIndices</s:classname>\r
+ <s:params>\r
+ <s:field>\r
+ <s:table>nuxeo.organizations_common</s:table>\r
+ <s:param>inAuthority,displayName,shortIdentifier</s:param>\r
+ </s:field>\r
+ </s:params>\r
+ </s:initHandler>\r
*\r
* $LastChangedRevision: $\r
* $LastChangedDate: $\r
final Logger logger = LoggerFactory.getLogger(AddIndices.class);\r
private final static String INDEX_SUFFIX = "_idx";\r
\r
+ /** See the class javadoc for this class: it shows the syntax supported in the configuration params.\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
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
+ logger.info("Modifying field datatypes for " + sbt.getName()\r
+ + " for repository domain " + sbt.getRepositoryDomain().trim() + "...");\r
+\r
for (Field field : fields) {\r
- try {\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
+ String tableName = field.getTable();\r
+ String fieldName = field.getCol();\r
+ String param = field.getParam();\r
+ if(Tools.notEmpty(param) && (param.indexOf(',')>-1)){\r
+ String[] fieldNames = param.split(",");\r
+ for (String fn: fieldNames){\r
+ addOneIndex(tableName, fn);\r
}\r
- rows = executeUpdate(sql);\r
- } catch (Exception e) {\r
- throw e;\r
+ } else {\r
+ addOneIndex(tableName, fieldName);\r
}\r
+ }\r
+ }\r
\r
- //call something like this: services.common.storage.DBUtils.addIndex(String tablename, String fields[]);\r
- //for every field that has an authRef, do ...\r
- // --> Connection conn = getConnection();\r
- //see parameter that you need for adding indices to SQL.\r
-\r
+ private int addOneIndex(String tableName, String columnName){\r
+ int rows = 0;\r
+ String sql = "";\r
+ try {\r
+ DatabaseProductType databaseProductType = getDatabaseProductType();\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 " + columnName + INDEX_SUFFIX + " ON " + tableName + " (" + columnName + ")";\r
+ } else if (databaseProductType == DatabaseProductType.POSTGRESQL) {\r
+ sql = "CREATE INDEX ON " + tableName + " (" + columnName + ")";\r
+ } else {\r
+ throw new Exception("Unrecognized database system " + databaseProductType);\r
+ }\r
+ rows = executeUpdate(sql);\r
+ logger.info("Index added to column ("+columnName+") on table ("+tableName+")");\r
+ return rows;\r
+ } catch (Throwable e) {\r
+ logger.info("Index NOT added to column ("+columnName+") on table ("+tableName+") SQL: "+sql+" ERROR: "+e);\r
+ return -1;\r
}\r
}\r
\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(rte.getStackTrace().toString());\r
- throw rte;\r
} catch (SQLException sqle) {\r
SQLException tempException = sqle;\r
while (null != tempException) { // SQLExceptions can be chained. Loop to log all.\r
logger.debug("SQL Exception: " + sqle.getLocalizedMessage());\r
tempException = tempException.getNextException();\r
}\r
- logger.debug(sqle.getStackTrace().toString());\r
throw new RuntimeException("SQL problem in executeQuery: ", sqle);\r
} finally {\r
try {\r
throw rte;\r
} catch (SQLException sqle) {\r
SQLException tempException = sqle;\r
+ String msg = "";\r
while (null != tempException) { // SQLExceptions can be chained. Loop to log all.\r
- logger.debug("SQL Exception: " + sqle.getLocalizedMessage());\r
+ if (! msg.isEmpty()){\r
+ msg = msg +"::next::";\r
+ }\r
+ msg = msg + sqle.getLocalizedMessage();\r
+ logger.debug("SQL Exception: " + msg);\r
tempException = tempException.getNextException();\r
}\r
- logger.debug(sqle.getStackTrace().toString());\r
- throw new RuntimeException("SQL problem in executeUpdate: ", sqle);\r
+ throw new RuntimeException("SQL problem in executeUpdate: "+msg, sqle);\r
} finally {\r
try {\r
if (conn != null) {\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
+ 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
return productType;\r
}\r