diff --git a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityFeed.xml b/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityFeed.xml deleted file mode 100644 index 3ec5c15c21..0000000000 --- a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityFeed.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - select alf_activity_feed_seq.nextval as value from dual - - - insert into alf_activity_feed (id, activity_type, activity_summary, activity_format, feed_user_id, post_user_id, post_date, post_id, site_network, app_tool, feed_date) - values (#id#, #activityType#, #activitySummary#, #activitySummaryFormat#, #feedUserId#, #postUserId#, #postDate#, #postId#, #siteNetwork#, #appTool#, #feedDate#) - - - - - - - - \ No newline at end of file diff --git a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityFeedControl.xml b/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityFeedControl.xml deleted file mode 100644 index b99e1c81a9..0000000000 --- a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityFeedControl.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - select alf_activity_feed_control_seq.nextval as value from dual - - - insert into alf_activity_feed_control (id, feed_user_id, site_network, app_tool, last_modified) - values (#id#, #feedUserId#, #siteNetwork#, #appTool#, #lastModified#) - - - - - - - - \ No newline at end of file diff --git a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityPost.xml b/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityPost.xml deleted file mode 100755 index b6f0d3cb3d..0000000000 --- a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect/ActivityPost.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - select alf_activity_post_seq.nextval as value from dual - - - insert into alf_activity_post (sequence_id, status, activity_data, post_user_id, post_date, activity_type, site_network, app_tool, job_task_node, last_modified) - values (#id#, #status#, #activityData#, #userId#, #postDate#, #activityType#, #siteNetwork#, #appTool#, #jobTaskNode#, #lastModified#) - - - - - - - - - update alf_activity_post set status = #status#, activity_data=#activityData#, site_network=#siteNetwork#, last_modified=#lastModified# - where sequence_id = #id# - and status != #status# - - - - update alf_activity_post set status = #status#, last_modified=#lastModified# - where sequence_id = #id# - and status != #status# - - - \ No newline at end of file diff --git a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect/ActivityFeed.xml b/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/ActivityFeed.xml similarity index 100% rename from config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect/ActivityFeed.xml rename to config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/ActivityFeed.xml diff --git a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect/ActivityFeedControl.xml b/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/ActivityFeedControl.xml similarity index 100% rename from config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect/ActivityFeedControl.xml rename to config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/ActivityFeedControl.xml diff --git a/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect/ActivityPost.xml b/config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/ActivityPost.xml similarity index 100% rename from config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect/ActivityPost.xml rename to config/alfresco/activities/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/ActivityPost.xml diff --git a/config/alfresco/dbscripts/create/3.0/org.hibernate.dialect.Oracle9iDialect/create-activities-extras.sql b/config/alfresco/dbscripts/create/3.0/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/create-activities-extras.sql similarity index 100% rename from config/alfresco/dbscripts/create/3.0/org.hibernate.dialect.Oracle9iDialect/create-activities-extras.sql rename to config/alfresco/dbscripts/create/3.0/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/create-activities-extras.sql diff --git a/config/alfresco/dbscripts/upgrade/1.3/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaMigrate-1.3.sql b/config/alfresco/dbscripts/upgrade/1.3/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaMigrate-1.3.sql similarity index 100% rename from config/alfresco/dbscripts/upgrade/1.3/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaMigrate-1.3.sql rename to config/alfresco/dbscripts/upgrade/1.3/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaMigrate-1.3.sql diff --git a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaUpdate-1.4-1.sql b/config/alfresco/dbscripts/upgrade/1.4/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaUpdate-1.4-1.sql similarity index 100% rename from config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaUpdate-1.4-1.sql rename to config/alfresco/dbscripts/upgrade/1.4/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaUpdate-1.4-1.sql diff --git a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaUpdate-1.4-2.sql b/config/alfresco/dbscripts/upgrade/1.4/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaUpdate-1.4-2.sql similarity index 100% rename from config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaUpdate-1.4-2.sql rename to config/alfresco/dbscripts/upgrade/1.4/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaUpdate-1.4-2.sql diff --git a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaUpdate-2.2-ACL.sql b/config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaUpdate-2.2-ACL.sql similarity index 100% rename from config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/AlfrescoSchemaUpdate-2.2-ACL.sql rename to config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/AlfrescoSchemaUpdate-2.2-ACL.sql diff --git a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/upgrade-0-create-missing-tables.sql b/config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/upgrade-0-create-missing-tables.sql similarity index 100% rename from config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/upgrade-0-create-missing-tables.sql rename to config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/upgrade-0-create-missing-tables.sql diff --git a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/upgrade-from-2.1.sql b/config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/upgrade-from-2.1.sql similarity index 100% rename from config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/upgrade-from-2.1.sql rename to config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/upgrade-from-2.1.sql diff --git a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/upgrade-from-2.2SP1.sql b/config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/upgrade-from-2.2SP1.sql similarity index 100% rename from config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9iDialect/upgrade-from-2.2SP1.sql rename to config/alfresco/dbscripts/upgrade/2.2/org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect/upgrade-from-2.2SP1.sql diff --git a/config/alfresco/extension/custom-hibernate-dialect.properties.sample b/config/alfresco/extension/custom-hibernate-dialect.properties.sample index 9b548e5180..973d55be57 100644 --- a/config/alfresco/extension/custom-hibernate-dialect.properties.sample +++ b/config/alfresco/extension/custom-hibernate-dialect.properties.sample @@ -8,11 +8,6 @@ # #hibernate.dialect=org.hibernate.dialect.DerbyDialect -# -# HSQL dialect -# -#hibernate.dialect=org.hibernate.dialect.HSQLDialect - # # MySQL dialect (default) # @@ -21,21 +16,9 @@ # # Oracle dialect # -#hibernate.dialect=org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect -#hibernate.dialect=org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect - -# -# Sybase dialect -# -#hibernate.dialect=org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect +#hibernate.dialect=org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect # # SQLServer dialect # #hibernate.dialect=org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect - -# -# PostgreSQL dialect -# -#hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect -#hibernate.query.substitutions=true TRUE, false FALSE \ No newline at end of file diff --git a/config/alfresco/extension/custom-repository.properties.sample b/config/alfresco/extension/custom-repository.properties.sample index da3334e256..c8d808f57c 100644 --- a/config/alfresco/extension/custom-repository.properties.sample +++ b/config/alfresco/extension/custom-repository.properties.sample @@ -35,12 +35,6 @@ #db.driver=org.apache.derby.jdbc.EmbeddedDriver #db.url=jdbc:derby:/srv/alfresco/alf_data/derby_data/alfresco;create=true -# -# HSQL connection -# -#db.driver=org.hsqldb.jdbcDriver -#db.url=jdbc:hsqldb:file:alf_data/hsql_data/alfresco;ifexists=true;shutdown=true; - # # MySQL connection (This is default and requires mysql-connector-java-5.0.3-bin.jar, which ships with the Alfresco server) # @@ -48,10 +42,16 @@ #db.url=jdbc:mysql://localhost/alfresco # -# PostgreSQL connection (requires postgresql-8.2-504.jdbc3.jar or equivalent) +# Oracle connection # -#db.driver=org.postgresql.Driver -#db.url=jdbc:postgresql://localhost:5432/alfresco +#db.driver=oracle.jdbc.OracleDriver +#db.url=jdbc:oracle:thin:@localhost:1521:alfresco + +# +# SQLServer connection (note you must enable TCP protocol on fixed port 1433) +# +#db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver +#db.url=jdbc:sqlserver://localhost:1433;databaseName=alfresco # The well known RMI registry port is defined in the alfresco-shared.properties file # alfresco.rmi.services.port=50500 diff --git a/config/alfresco/messages/schema-update.properties b/config/alfresco/messages/schema-update.properties index 3843c26bdb..fdc3ea2c93 100644 --- a/config/alfresco/messages/schema-update.properties +++ b/config/alfresco/messages/schema-update.properties @@ -12,6 +12,7 @@ schema.update.warn.dialect_unsupported=Alfresco should not be used with database schema.update.warn.dialect_hsql=Alfresco is using the HSQL default database. Please only use this while evaluating Alfresco, it is NOT recommended for production or deployment! schema.update.warn.dialect_derby=Alfresco is using the Apache Derby default database. Please only use this while evaluating Alfresco, it is NOT recommended for production or deployment! schema.update.warn.dialect_substituting=The dialect ''{0}'' is being changed to ''{1}''. +schema.update.err.dialect_should_use=The dialect ''{0}'' is unsupported. Please use ''{1}'' instead. schema.update.err.found_multiple=\nMore than one Alfresco schema was found when querying the database metadata.\n Limit the database user's permissions or set the 'hibernate.default_schema' property in 'custom-hibernate-dialect.properties'. schema.update.err.previous_failed=A previous schema upgrade failed or was not completed. Revert to the original database before attempting the upgrade again. schema.update.err.statement_failed=Statement execution failed:\n SQL: {0}\n Error: {1}\n File: {2}\n Line: {3} diff --git a/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle10gDialect.java b/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle10gDialect.java deleted file mode 100644 index d9f4498e75..0000000000 --- a/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle10gDialect.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.alfresco.repo.domain.hibernate.dialect; - -import java.sql.Types; - -import org.hibernate.dialect.Oracle10gDialect; - -/** - * Does away with the deprecated LONG datatype. - * - * @author Derek Hulley - * @since 2.2.2 - */ -public class AlfrescoOracle10gDialect extends Oracle10gDialect -{ - public AlfrescoOracle10gDialect() - { - super(); - registerColumnType( Types.VARBINARY, "blob" ); - } -} diff --git a/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle9Dialect.java b/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle9Dialect.java new file mode 100644 index 0000000000..8bfecfdeae --- /dev/null +++ b/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle9Dialect.java @@ -0,0 +1,23 @@ +package org.alfresco.repo.domain.hibernate.dialect; + +import java.sql.Types; + +import org.hibernate.dialect.Oracle9Dialect; + +/** + * Does away with the deprecated LONG datatype. This extends the deprecated + * Oracle9Dialect for good reason: Hibernate ceased supporting + * right outer join in the Oracle9iDialect. + * + * @author Derek Hulley + * @since 2.2.2 + */ +@SuppressWarnings("deprecation") +public class AlfrescoOracle9Dialect extends Oracle9Dialect +{ + public AlfrescoOracle9Dialect() + { + super(); + registerColumnType( Types.VARBINARY, "blob" ); + } +} diff --git a/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle9iDialect.java b/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle9iDialect.java deleted file mode 100644 index 70eb044bd8..0000000000 --- a/source/java/org/alfresco/repo/domain/hibernate/dialect/AlfrescoOracle9iDialect.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.alfresco.repo.domain.hibernate.dialect; - -import java.sql.Types; - -import org.hibernate.dialect.Oracle9iDialect; - -/** - * Does away with the deprecated LONG datatype. - * - * @author Derek Hulley - * @since 2.2.2 - */ -public class AlfrescoOracle9iDialect extends Oracle9iDialect -{ - public AlfrescoOracle9iDialect() - { - super(); - registerColumnType( Types.VARBINARY, "blob" ); - } -} diff --git a/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java b/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java index cf8bef9503..823493b74f 100644 --- a/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java +++ b/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java @@ -33,8 +33,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Writer; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.DatabaseMetaData; +import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -47,8 +47,7 @@ import org.alfresco.repo.admin.patch.Patch; import org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch; import org.alfresco.repo.content.filestore.FileContentWriter; import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle10gDialect; -import org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9iDialect; +import org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect; import org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect; import org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect; import org.alfresco.service.ServiceRegistry; @@ -112,6 +111,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean private static final String WARN_DIALECT_SUBSTITUTING = "schema.update.warn.dialect_substituting"; private static final String WARN_DIALECT_HSQL = "schema.update.warn.dialect_hsql"; private static final String WARN_DIALECT_DERBY = "schema.update.warn.dialect_derby"; + private static final String ERR_DIALECT_SHOULD_USE = "schema.update.err.dialect_should_use"; private static final String ERR_MULTIPLE_SCHEMAS = "schema.update.err.found_multiple"; private static final String ERR_PREVIOUS_FAILED_BOOTSTRAP = "schema.update.err.previous_failed"; private static final String ERR_STATEMENT_FAILED = "schema.update.err.statement_failed"; @@ -974,30 +974,25 @@ public class SchemaBootstrap extends AbstractLifecycleBean { return; } - else if (dialectName.equals(Oracle9iDialect.class.getName())) - { - String subst = AlfrescoOracle9iDialect.class.getName(); - LogUtil.warn(logger, WARN_DIALECT_SUBSTITUTING, dialectName, subst); - cfg.setProperty(Environment.DIALECT, subst); - } - else if (dialectName.equals(Oracle10gDialect.class.getName())) - { - String subst = AlfrescoOracle10gDialect.class.getName(); - LogUtil.warn(logger, WARN_DIALECT_SUBSTITUTING, dialectName, subst); - cfg.setProperty(Environment.DIALECT, subst); - } - else if (dialectName.equals(MySQLDialect.class.getName())) - { - String subst = MySQLInnoDBDialect.class.getName(); - LogUtil.warn(logger, WARN_DIALECT_SUBSTITUTING, dialectName, subst); - cfg.setProperty(Environment.DIALECT, subst); - } - else if (dialectName.equals(MySQL5Dialect.class.getName())) - { - String subst = MySQLInnoDBDialect.class.getName(); - LogUtil.warn(logger, WARN_DIALECT_SUBSTITUTING, dialectName, subst); - cfg.setProperty(Environment.DIALECT, subst); - } +// TODO: https://issues.alfresco.com/jira/browse/ETHREEOH-679 +// else if (dialectName.equals(Oracle9Dialect.class.getName())) +// { +// String subst = AlfrescoOracle9Dialect.class.getName(); +// LogUtil.warn(logger, WARN_DIALECT_SUBSTITUTING, dialectName, subst); +// cfg.setProperty(Environment.DIALECT, subst); +// } +// else if (dialectName.equals(MySQLDialect.class.getName())) +// { +// String subst = MySQLInnoDBDialect.class.getName(); +// LogUtil.warn(logger, WARN_DIALECT_SUBSTITUTING, dialectName, subst); +// cfg.setProperty(Environment.DIALECT, subst); +// } +// else if (dialectName.equals(MySQL5Dialect.class.getName())) +// { +// String subst = MySQLInnoDBDialect.class.getName(); +// LogUtil.warn(logger, WARN_DIALECT_SUBSTITUTING, dialectName, subst); +// cfg.setProperty(Environment.DIALECT, subst); +// } } /** @@ -1010,7 +1005,8 @@ public class SchemaBootstrap extends AbstractLifecycleBean LogUtil.info(logger, MSG_DIALECT_USED, dialectClazz.getName()); if (dialectClazz.equals(MySQLDialect.class) || dialectClazz.equals(MySQL5Dialect.class)) { - LogUtil.warn(logger, WARN_DIALECT_UNSUPPORTED, dialectClazz.getName()); + LogUtil.error(logger, ERR_DIALECT_SHOULD_USE, dialectClazz.getName(), MySQLInnoDBDialect.class.getName()); + throw AlfrescoRuntimeException.create(WARN_DIALECT_UNSUPPORTED, dialectClazz.getName()); } else if (dialectClazz.equals(HSQLDialect.class)) { @@ -1020,9 +1016,15 @@ public class SchemaBootstrap extends AbstractLifecycleBean { LogUtil.info(logger, WARN_DIALECT_DERBY); } + else if (dialectClazz.equals(Oracle9iDialect.class) || dialectClazz.equals(Oracle10gDialect.class)) + { + LogUtil.error(logger, ERR_DIALECT_SHOULD_USE, dialectClazz.getName(), AlfrescoOracle9Dialect.class.getName()); + throw AlfrescoRuntimeException.create(WARN_DIALECT_UNSUPPORTED, dialectClazz.getName()); + } else if (dialectClazz.equals(OracleDialect.class) || dialectClazz.equals(Oracle9Dialect.class)) { - LogUtil.warn(logger, WARN_DIALECT_UNSUPPORTED, dialectClazz.getName()); + LogUtil.error(logger, ERR_DIALECT_SHOULD_USE, dialectClazz.getName(), AlfrescoOracle9Dialect.class.getName()); + throw AlfrescoRuntimeException.create(WARN_DIALECT_UNSUPPORTED, dialectClazz.getName()); } int maxStringLength = SchemaBootstrap.DEFAULT_MAX_STRING_LENGTH; @@ -1057,7 +1059,7 @@ public class SchemaBootstrap extends AbstractLifecycleBean // serializable_value blob, maxStringLength = Integer.MAX_VALUE; } - else if (dialect instanceof OracleDialect) + else if (dialect instanceof AlfrescoOracle9Dialect) { // string_value varchar2(1024 char), // serializable_value blob, diff --git a/source/java/org/alfresco/repo/usage/UserUsageTest.java b/source/java/org/alfresco/repo/usage/UserUsageTest.java index 7ef7626db7..78b993f11b 100644 --- a/source/java/org/alfresco/repo/usage/UserUsageTest.java +++ b/source/java/org/alfresco/repo/usage/UserUsageTest.java @@ -170,6 +170,11 @@ public class UserUsageTest extends TestCase public void testCreateUpdatedeleteInTx() throws Exception { + if(!contentUsageImpl.getEnabled()) + { + return; + } + runAs(TEST_USER); assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); @@ -219,6 +224,11 @@ public class UserUsageTest extends TestCase public void testCreateUpdatedeleteAcrossTx() throws Exception { + if(!contentUsageImpl.getEnabled()) + { + return; + } + runAs(TEST_USER); assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); @@ -282,6 +292,11 @@ public class UserUsageTest extends TestCase public void testCreateCopydeleteInTx() throws Exception { + if(!contentUsageImpl.getEnabled()) + { + return; + } + runAs(TEST_USER); assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); @@ -323,6 +338,11 @@ public class UserUsageTest extends TestCase public void testCreateCopydeleteAcrossTx() throws Exception { + if(!contentUsageImpl.getEnabled()) + { + return; + } + runAs(TEST_USER); assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); @@ -378,6 +398,11 @@ public class UserUsageTest extends TestCase public void testCreateCopyDeleteFolderWithContentInTx() throws Exception { + if(!contentUsageImpl.getEnabled()) + { + return; + } + runAs(TEST_USER); assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); @@ -420,6 +445,11 @@ public class UserUsageTest extends TestCase public void testCreateCopyDeleteFolderWithContentAcrossTx() throws Exception { + if(!contentUsageImpl.getEnabled()) + { + return; + } + runAs(TEST_USER); assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); diff --git a/source/java/org/alfresco/util/schemadump/Main.java b/source/java/org/alfresco/util/schemadump/Main.java new file mode 100644 index 0000000000..8af7f47848 --- /dev/null +++ b/source/java/org/alfresco/util/schemadump/Main.java @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2005-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have received a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.util.schemadump; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +import javax.sql.DataSource; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.Oracle8iDialect; +import org.hibernate.dialect.TypeNames; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * Simple command line utility to help with database schema comparisons and upgrades. Dumps a database schema via JDBC + * to a normalised XML form. + * + * @author dward + */ +public class Main +{ + /** Reusable empty SAX attribute list. */ + private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl(); + + /** Reverse map from database types to JDBC types (loaded from a Hibernate dialect). */ + private final Map reverseTypeMap = new TreeMap(); + + /** Should we scale down string field widths (assuming 4 bytes to one character?). */ + private final boolean scaleCharacters; + + /** The JDBC connection. */ + private final Connection con; + + /** + * Creates a new instance of this tool.. + * + * @throws SQLException + * the SQL exception + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + * @throws ClassNotFoundException + * the class not found exception + * @throws NoSuchFieldException + * the no such field exception + */ + @SuppressWarnings("unchecked") + public Main() throws SQLException, IOException, InstantiationException, IllegalAccessException, + ClassNotFoundException, NoSuchFieldException + { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] + { + "classpath:/org/alfresco/extension/dump-context.xml" + }); + final DataSource datasource = (DataSource) context.getBean("dataSource"); + this.con = datasource.getConnection(); + + // Use Java reflection to bypass accessibility rules and get hold of hibernate's type mapping! + final Properties hibProps = (Properties) context.getBean("hibernateConfigProperties"); + final Dialect dialect = (Dialect) Class.forName(hibProps.getProperty("hibernate.dialect")).newInstance(); + this.scaleCharacters = dialect instanceof Oracle8iDialect; + final Field typeNamesField = Dialect.class.getDeclaredField("typeNames"); + typeNamesField.setAccessible(true); + final TypeNames typeNames = (TypeNames) typeNamesField.get(dialect); + final Field defaultsField = TypeNames.class.getDeclaredField("defaults"); + defaultsField.setAccessible(true); + final Map forwardMap2 = (Map) defaultsField.get(typeNames); + for (final Map.Entry e : forwardMap2.entrySet()) + { + this.reverseTypeMap.put(e.getValue(), e.getKey()); + } + + final Field weightedField = TypeNames.class.getDeclaredField("weighted"); + weightedField.setAccessible(true); + final Map> forwardMap1 = (Map>) weightedField + .get(typeNames); + for (final Map.Entry> e : forwardMap1.entrySet()) + { + for (final String type : e.getValue().values()) + { + this.reverseTypeMap.put(type, e.getKey()); + } + } + } + + /** + * The main method. + * + * @param args + * the args + * @throws Exception + * the exception + */ + public static void main(final String[] args) throws Exception + { + final NamedElementCollection result = new Main().execute(); + + // Set up a SAX TransformerHandler for outputting XML + final SAXTransformerFactory stf = (SAXTransformerFactory) TransformerFactory.newInstance(); + final TransformerHandler xmlOut = stf.newTransformerHandler(); + final Transformer t = xmlOut.getTransformer(); + try + { + t.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2"); + } + catch (final IllegalArgumentException e) + { + // It was worth a try + } + t.setOutputProperty(OutputKeys.INDENT, "yes"); + xmlOut.setResult(new StreamResult(args[0])); + + xmlOut.startDocument(); + result.output(xmlOut); + xmlOut.endDocument(); + } + + /** + * Execute. + * + * @return the named element collection + * @throws SQLException + * the SQL exception + * @throws IllegalArgumentException + * the illegal argument exception + * @throws IllegalAccessException + * the illegal access exception + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws InstantiationException + * the instantiation exception + * @throws ClassNotFoundException + * the class not found exception + * @throws SecurityException + * the security exception + * @throws NoSuchFieldException + * the no such field exception + */ + public NamedElementCollection execute() throws SQLException, IllegalArgumentException, IllegalAccessException, + IOException, InstantiationException, ClassNotFoundException, SecurityException, NoSuchFieldException + { + + final NamedElementCollection schemaCol = new NamedElementCollection("schema", "table"); + + final DatabaseMetaData dbmd = this.con.getMetaData(); + + // Assume that if there are schemas, we want the one named after the connection user or the one called "dbo" (MS + // SQL hack) + String schema = null; + final ResultSet schemas = dbmd.getSchemas(); + while (schemas.next()) + { + final String thisSchema = schemas.getString("TABLE_SCHEM"); + if (thisSchema.equals(dbmd.getUserName()) || thisSchema.equalsIgnoreCase("dbo")) + { + schema = thisSchema; + break; + } + } + schemas.close(); + + final ResultSet tables = dbmd.getTables(null, schema, "%", new String[] + { + "TABLE", "VIEW" + }); + while (tables.next()) + { + final String tableName = tables.getString("TABLE_NAME"); + final NamedElement tableEl = schemaCol.addNamedElement(tableName); + final NamedElementCollection columnsCol = tableEl.addCollection("columns", "column"); + final ResultSet columns = dbmd.getColumns(null, tables.getString("TABLE_SCHEM"), tableName, "%"); + while (columns.next()) + { + final NamedElement columnEl = columnsCol.addNamedElement(columns.getString("COLUMN_NAME")); + columnEl.addAttribute("seq", String.valueOf(columns.getInt("ORDINAL_POSITION"))); + columnEl.addAttribute("type", convertToTypeName(columns.getString("TYPE_NAME"), columns + .getInt("COLUMN_SIZE"), columns.getInt("DECIMAL_DIGITS"), columns.getInt("DATA_TYPE"))); + columnEl.addAttribute("nullable", columns.getString("IS_NULLABLE")); + } + columns.close(); + + final ResultSet primarykeycols = dbmd.getPrimaryKeys(null, tables.getString("TABLE_SCHEM"), tableName); + String primaryKeyName = null; + NamedElementCollection primaryKey = null; + while (primarykeycols.next()) + { + if (primaryKey == null) + { + primaryKeyName = primarykeycols.getString("PK_NAME"); + primaryKey = tableEl.addCollection("primarykey", "column"); + } + final NamedElement pkCol = primaryKey.addNamedElement(primarykeycols.getString("COLUMN_NAME")); + pkCol.addAttribute("seq", primarykeycols.getString("KEY_SEQ")); + } + primarykeycols.close(); + + final NamedElementCollection indexCol = tableEl.addCollection("indexes", "index"); + final ResultSet indexes = dbmd.getIndexInfo(null, tables.getString("TABLE_SCHEM"), tableName, false, true); + String lastIndexName = ""; + NamedElementCollection indexCols = null; + while (indexes.next()) + { + final String indexName = indexes.getString("INDEX_NAME"); + if (indexName == null) + { + // Oracle seems to have some dummy index entries + continue; + } + // Skip the index corresponding to the PK if it is mentioned + else if (indexName.equals(primaryKeyName)) + { + continue; + } + if (!indexName.equals(lastIndexName)) + { + final NamedElement index = indexCol.addNamedElement(indexName); + index.addAttribute("unique", String.valueOf(!indexes.getBoolean("NON_UNIQUE"))); + indexCols = index.addCollection("columns", "column"); + lastIndexName = indexName; + } + indexCols.addNamedElement(indexes.getString("COLUMN_NAME")); + } + indexes.close(); + + final NamedElementCollection foreignKeyCol = tableEl.addCollection("foreignkeys", "key"); + final ResultSet foreignkeys = dbmd.getImportedKeys(null, tables.getString("TABLE_SCHEM"), tableName); + String lastKeyName = ""; + NamedElementCollection foreignKeyCols = null; + while (foreignkeys.next()) + { + final String keyName = foreignkeys.getString("FK_NAME"); + if (!keyName.equals(lastKeyName)) + { + final NamedElement key = foreignKeyCol.addNamedElement(keyName); + foreignKeyCols = key.addCollection("columns", "column"); + lastKeyName = keyName; + } + final NamedElement fkCol = foreignKeyCols.addNamedElement(foreignkeys.getString("FKCOLUMN_NAME")); + fkCol.addAttribute("table", foreignkeys.getString("PKTABLE_NAME").toUpperCase()); + fkCol.addAttribute("column", foreignkeys.getString("PKCOLUMN_NAME").toUpperCase()); + } + foreignkeys.close(); + } + tables.close(); + return schemaCol; + } + + /** + * Chooses a JDBC type name, given database and JDBC type information. + * + * @param dbType + * the db type + * @param size + * the size + * @param digits + * the number of digits + * @param sqlType + * the sql type + * @return the string + * @throws IllegalArgumentException + * the illegal argument exception + * @throws IllegalAccessException + * the illegal access exception + */ + private String convertToTypeName(final String dbType, int size, final int digits, int sqlType) + throws IllegalArgumentException, IllegalAccessException + { + + // First see if the Hibernate dialect has a mapping to the database type + String dbName = dbType.toLowerCase() + "(" + size + "," + digits + ")"; + if (this.reverseTypeMap.containsKey(dbName)) + { + sqlType = this.reverseTypeMap.get(dbName); + } + else + { + dbName = dbType.toLowerCase(); + if (this.reverseTypeMap.containsKey(dbName)) + { + sqlType = this.reverseTypeMap.get(dbName); + } + } + final Field[] fields = Types.class.getFields(); + final int modifiers = Modifier.PUBLIC | Modifier.STATIC; + for (final Field field : fields) + { + if (field.getType().equals(int.class) && (field.getModifiers() & modifiers) == modifiers + && field.getInt(null) == sqlType) + { + if (size == 0 || this.reverseTypeMap.containsKey(dbName) || sqlType == Types.TIMESTAMP + || sqlType == Types.INTEGER) + { + return field.getName(); + } + else + { + // Hack to work around Oracle's byte semantics + if (this.scaleCharacters + && (sqlType == Types.CHAR || sqlType == Types.VARCHAR || sqlType == Types.CLOB)) + { + size /= 4; + } + return field.getName() + "(" + size + ")"; + } + } + } + return String.valueOf(sqlType); + } + + /** + * Represents a sorted collection of named elements in the XML model. + */ + private class NamedElementCollection + { + + /** The collection name. */ + private final String collectionName; + + /** The repeated element name. */ + private final String elementName; + + /** The attributes of the collection. */ + private final AttributesImpl attributes = new AttributesImpl(); + + /** The items in the collection. */ + private final List items = new ArrayList(100); + + /** + * The Constructor. + * + * @param collectionName + * the collection name + * @param elementName + * the repeated element name + */ + public NamedElementCollection(final String collectionName, final String elementName) + { + this.collectionName = collectionName; + this.elementName = elementName; + } + + /** + * Adds an attribute. + * + * @param name + * the name + * @param value + * the value + */ + public void addAttribute(final String name, final String value) + { + this.attributes.addAttribute("", "", name, "CDATA", value); + } + + /** + * Adds a named element. + * + * @param name + * the name + * @return the named element + */ + public NamedElement addNamedElement(final String name) + { + final NamedElement retVal = new NamedElement(name); + this.items.add(retVal); + return retVal; + } + + /** + * Outputs to XML. + * + * @param xmlOut + * the SAX content handler + * @throws SAXException + * the SAX exception + */ + public void output(final ContentHandler xmlOut) throws SAXException + { + xmlOut.startElement("", "", this.collectionName, this.attributes); + Collections.sort(this.items); + for (final NamedElement item : this.items) + { + item.output(xmlOut, this.elementName); + } + xmlOut.endElement("", "", this.collectionName); + } + } + + /** + * Represents a named element in the XML model. + */ + private class NamedElement implements Comparable + { + + /** The name. */ + private final String name; + + /** The attributes. */ + private final List attributes = new LinkedList(); + + /** The child collections. */ + private final List collections = new LinkedList();; + + /** + * Instantiates a new named element. + * + * @param name + * the name + */ + public NamedElement(final String name) + { + this.name = name.toUpperCase(); + } + + /** + * Adds an attribute. + * + * @param name + * the name + * @param value + * the value + */ + public void addAttribute(final String name, final String value) + { + this.attributes.add(new String[] + { + name, value + }); + } + + /** + * Adds a child collection. + * + * @param collectionName + * the collection name + * @param elementName + * the repeated element name + * @return the named element collection + */ + public NamedElementCollection addCollection(final String collectionName, final String elementName) + { + final NamedElementCollection retVal = new NamedElementCollection(collectionName, elementName); + this.collections.add(retVal); + return retVal; + + } + + /** + * Outputs to XML. + * + * @param xmlOut + * the SAX content handler + * @param elementName + * the element name + * @throws SAXException + * the SAX exception + */ + public void output(final ContentHandler xmlOut, final String elementName) throws SAXException + { + final AttributesImpl attribs = new AttributesImpl(); + attribs.addAttribute("", "", "name", "CDATA", this.name); + xmlOut.startElement("", "", elementName, attribs); + for (final String[] attrib : this.attributes) + { + xmlOut.startElement("", "", attrib[0], Main.EMPTY_ATTRIBUTES); + final char[] chars = attrib[1].toCharArray(); + xmlOut.characters(chars, 0, chars.length); + xmlOut.endElement("", "", attrib[0]); + } + for (final NamedElementCollection coll : this.collections) + { + coll.output(xmlOut); + } + xmlOut.endElement("", "", elementName); + } + + /* + * (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(final NamedElement o) + { + return this.name.compareTo(o.name); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) + { + if (!(obj instanceof NamedElement)) + { + return false; + } + return this.name.equals(((NamedElement) obj).name); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + return this.name.hashCode(); + } + + } +}