From ff289445e91966b3c337f0cdd94cb2d4a627e6fb Mon Sep 17 00:00:00 2001 From: chenson42 Date: Mon, 14 Nov 2011 13:16:02 +0000 Subject: [PATCH] Refactoring in progress ... --- .../symmetric/AbstractSymmetricEngine.java | 2 +- .../symmetric/db/AbstractDbDialect.java | 75 +- .../db/AbstractEmbeddedDbDialect.java | 2 +- .../db/AutoIncrementColumnFilter.java | 4 +- .../symmetric/db/DbDialectFactory.java | 49 +- .../org/jumpmind/symmetric/db/IDbDialect.java | 7 +- .../jumpmind/symmetric/db/SqlTemplate.java | 158 +- .../symmetric/db/db2/Db2v9DbDialect.java | 7 +- .../symmetric/db/hsqldb/HsqlDbDialect.java | 6 +- .../symmetric/db/hsqldb2/HsqlDb2Dialect.java | 4 +- .../db/informix/InformixDbDialect.java | 4 +- .../symmetric/db/mssql/MsSqlDbDialect.java | 2 +- .../symmetric/db/mysql/MySqlDbDialect.java | 4 +- .../symmetric/db/oracle/OracleDbDialect.java | 6 +- .../db/postgresql/PostgreSqlDbDialect.java | 6 +- .../db/postgresql/PostgresDmlStatement.java | 2 +- .../symmetric/db/sybase/SybaseDbDialect.java | 2 +- .../ext/IDatabaseUpgradeListener.java | 2 +- .../csv/AbstractStreamDataCommand.java | 4 +- .../symmetric/extract/csv/CsvExtractor.java | 28 +- .../symmetric/load/DataLoaderContext.java | 2 +- .../symmetric/load/IColumnFilter.java | 2 +- .../symmetric/load/IDataLoaderContext.java | 2 +- .../symmetric/load/TableTemplate.java | 4 +- .../symmetric/model/DataMetaData.java | 2 +- .../org/jumpmind/symmetric/model/Trigger.java | 4 +- .../symmetric/model/TriggerHistory.java | 4 +- .../symmetric/model/TriggerRouter.java | 4 +- .../symmetric/profile/DefaultProfile.java | 2 +- .../symmetric/route/DataGapRouteReader.java | 3 +- .../service/ITriggerRouterService.java | 2 +- .../service/impl/ConfigurationService.java | 12 +- .../service/impl/DataExtractorService.java | 2 +- .../symmetric/service/impl/DataService.java | 2 +- .../service/impl/ParameterService.java | 5 +- .../symmetric/service/impl/RouterService.java | 2 +- .../service/impl/TriggerRouterService.java | 2 +- .../transform/AdditiveColumnTransform.java | 4 +- .../transform/TransformDataLoader.java | 2 +- .../symmetric/transform/TransformTable.java | 2 +- .../org/jumpmind/symmetric/util/AppUtils.java | 47 - .../ConfigurationChangedDataRouterTest.java | 2 +- symmetric/symmetric-db/pom.xml | 4 + .../db/AbstractDatabasePlatform.java | 227 ++ .../{ddl => }/DatabaseOperationException.java | 2 +- .../symmetric/db/DatabasePlatformFactory.java | 266 ++ ...ormInfo.java => DatabasePlatformInfo.java} | 8 +- .../symmetric/db/DatabasePlatformUtils.java | 320 ++ .../db/{ddl => }/DdlUtilsException.java | 7 +- .../symmetric/db/IDatabasePlatform.java | 184 ++ .../alteration => alter}/AddColumnChange.java | 10 +- .../AddForeignKeyChange.java | 10 +- .../alteration => alter}/AddIndexChange.java | 10 +- .../AddPrimaryKeyChange.java | 8 +- .../alteration => alter}/AddTableChange.java | 12 +- .../ColumnAutoIncrementChange.java | 8 +- .../alteration => alter}/ColumnChange.java | 4 +- .../ColumnDataTypeChange.java | 8 +- .../ColumnDefaultValueChange.java | 8 +- .../ColumnRequiredChange.java | 8 +- .../ColumnSizeChange.java | 8 +- .../IModelChange.java} | 8 +- .../alteration => alter}/ModelComparator.java | 439 ++- .../PrimaryKeyChange.java | 8 +- .../RemoveColumnChange.java | 8 +- .../RemoveForeignKeyChange.java | 10 +- .../RemoveIndexChange.java | 8 +- .../RemovePrimaryKeyChange.java | 8 +- .../RemoveTableChange.java | 6 +- .../alteration => alter}/TableChange.java | 6 +- .../TableChangeImplBase.java | 4 +- .../db/{ddl/alteration => alter}/package.html | 0 .../jumpmind/symmetric/db/ddl/Platform.java | 616 ---- .../symmetric/db/ddl/PlatformFactory.java | 231 -- .../symmetric/db/ddl/PlatformUtils.java | 448 --- .../db/ddl/platform/CreationParameters.java | 82 - .../db/ddl/platform/PlatformImplBase.java | 1247 -------- .../symmetric/db/ddl/platform/SqlBuilder.java | 2783 ----------------- .../cloudscape/CloudscapeBuilder.java | 62 - .../cloudscape/CloudscapePlatform.java | 84 - .../db/ddl/platform/cloudscape/package.html | 30 - .../db/ddl/platform/db2/Db2Builder.java | 273 -- .../db/ddl/platform/db2/Db2Platform.java | 95 - .../db/ddl/platform/db2/Db2v8Builder.java | 40 - .../db/ddl/platform/db2/Db2v8Platform.java | 48 - .../db/ddl/platform/derby/DerbyPlatform.java | 135 - .../db/ddl/platform/h2/H2Builder.java | 288 -- .../db/ddl/platform/hsqldb/HsqlDbBuilder.java | 179 -- .../ddl/platform/hsqldb/HsqlDbPlatform.java | 111 - .../ddl/platform/hsqldb2/HsqlDb2Platform.java | 111 - .../platform/interbase/InterbasePlatform.java | 179 -- .../db/ddl/platform/mssql/MSSqlPlatform.java | 156 - .../platform/mysql/MySql50ModelReader.java | 56 - .../ddl/platform/mysql/MySql50Platform.java | 57 - .../db/ddl/platform/mysql/MySqlBuilder.java | 351 --- .../db/ddl/platform/mysql/MySqlPlatform.java | 102 - .../ddl/platform/oracle/Oracle10Builder.java | 65 - .../ddl/platform/oracle/Oracle10Platform.java | 48 - .../ddl/platform/oracle/Oracle8Builder.java | 524 ---- .../ddl/platform/oracle/Oracle8Platform.java | 107 - .../ddl/platform/oracle/Oracle9Platform.java | 50 - .../platform/oracle/OracleModelReader.java | 401 --- .../postgresql/PostgreSqlPlatform.java | 213 -- .../platform/sybase/SybaseASE15Platform.java | 47 - .../ddl/platform/sybase/SybasePlatform.java | 296 -- .../symmetric/db/ddl/util/JdbcSupport.java | 220 -- .../symmetric/db/ddl/util/SqlTokenizer.java | 109 - .../symmetric/db/{ddl => }/io/DatabaseIO.java | 6 +- .../db/{ddl => }/io/DigesterRules.java | 2 +- .../db/{ddl => }/io/LocalEntityResolver.java | 2 +- .../symmetric/db/{ddl => }/io/package.html | 0 .../symmetric/db/{ddl => }/model/Column.java | 4 +- .../db/{ddl => }/model/Database.java | 2 +- .../db/{ddl => }/model/ForeignKey.java | 2 +- .../symmetric/db/{ddl => }/model/Index.java | 2 +- .../db/{ddl => }/model/IndexColumn.java | 2 +- .../db/{ddl => }/model/IndexImpBase.java | 2 +- .../{ddl => }/model/JdbcTypeCategoryEnum.java | 2 +- .../db/{ddl => }/model/ModelException.java | 4 +- .../db/{ddl => }/model/NonUniqueIndex.java | 2 +- .../db/{ddl => }/model/Reference.java | 2 +- .../symmetric/db/{ddl => }/model/Table.java | 2 +- .../symmetric/db/{ddl => }/model/TypeMap.java | 4 +- .../db/{ddl => }/model/UniqueIndex.java | 2 +- .../symmetric/db/{ddl => }/model/package.html | 0 .../symmetric/db/{ddl => }/package.html | 4 +- .../platform/DatabaseMetaDataWrapper.java | 2 +- .../platform/DefaultValueHelper.java | 6 +- .../{ddl => }/platform/JdbcModelReader.java | 38 +- .../platform/MetaDataColumnDescriptor.java | 2 +- .../symmetric/db/platform/SqlBuilder.java | 2512 +++++++++++++++ .../symmetric/db/platform/db2/Db2Builder.java | 234 ++ .../platform/db2/Db2ModelReader.java | 22 +- .../db/platform/db2/Db2Platform.java | 102 + .../db/{ddl => }/platform/db2/package.html | 0 .../platform/derby/DerbyBuilder.java | 142 +- .../platform/derby/DerbyModelReader.java | 20 +- .../db/platform/derby/DerbyPlatform.java | 87 + .../db/{ddl => }/platform/derby/package.html | 0 .../platform/firebird/FirebirdBuilder.java | 304 +- .../firebird/FirebirdModelReader.java | 399 +-- .../platform/firebird/FirebirdPlatform.java | 30 +- .../{ddl => }/platform/firebird/package.html | 0 .../greenplum/GreenplumModelReader.java | 14 +- .../platform/greenplum/GreenplumPlatform.java | 9 +- .../symmetric/db/platform/h2/H2Builder.java | 133 + .../{ddl => }/platform/h2/H2ModelReader.java | 22 +- .../db/{ddl => }/platform/h2/H2Platform.java | 41 +- .../db/platform/hsqldb/HsqlDbBuilder.java | 153 + .../platform/hsqldb/HsqlDbModelReader.java | 63 +- .../db/platform/hsqldb/HsqlDbPlatform.java | 88 + .../db/{ddl => }/platform/hsqldb/package.html | 0 .../platform/hsqldb2/HsqlDb2Builder.java | 143 +- .../platform/hsqldb2/HsqlDb2ModelReader.java | 20 +- .../db/platform/hsqldb2/HsqlDb2Platform.java | 84 + .../platform/informix/InformixBuilder.java | 41 +- .../informix/InformixModelReader.java | 20 +- .../platform/informix/InformixPlatform.java | 29 +- .../platform/interbase/InterbaseBuilder.java | 291 +- .../interbase/InterbaseModelReader.java | 396 +-- .../platform/interbase/InterbasePlatform.java | 100 + .../{ddl => }/platform/interbase/package.html | 0 .../platform/mssql/MSSqlBuilder.java | 619 ++-- .../platform/mssql/MSSqlModelReader.java | 20 +- .../db/platform/mssql/MSSqlPlatform.java | 102 + .../db/{ddl => }/platform/mssql/package.html | 0 .../db/platform/mysql/MySqlBuilder.java | 282 ++ .../platform/mysql/MySqlModelReader.java | 74 +- .../db/platform/mysql/MySqlPlatform.java | 110 + .../db/{ddl => }/platform/mysql/package.html | 0 .../db/platform/oracle/OracleBuilder.java | 458 +++ .../db/platform/oracle/OracleModelReader.java | 382 +++ .../db/platform/oracle/OraclePlatform.java | 105 + .../db/{ddl => }/platform/oracle/package.html | 0 .../db/{ddl => }/platform/package.html | 0 .../postgresql/PostgreSqlBuilder.java | 207 +- .../postgresql/PostgreSqlModelReader.java | 20 +- .../postgresql/PostgreSqlPlatform.java | 92 + .../platform/postgresql/package.html | 0 .../platform/sqlite/SqLiteBuilder.java | 89 +- .../platform/sqlite/SqLiteModelReader.java | 22 +- .../platform/sqlite/SqLitePlatform.java | 31 +- .../platform/sybase/SybaseBuilder.java | 553 ++-- .../platform/sybase/SybaseModelReader.java | 24 +- .../db/platform/sybase/SybasePlatform.java | 99 + .../db/{ddl => }/platform/sybase/package.html | 0 .../symmetric/db/sql/AbstractSqlTemplate.java | 2 +- .../symmetric/db/sql/DmlStatement.java | 20 +- .../symmetric/db/sql/ISqlTemplate.java | 2 +- .../org/jumpmind/symmetric/db/sql/Query.java | 4 +- .../jumpmind/symmetric/db/sql}/SqlScript.java | 102 +- .../symmetric/db/sql/SqlScriptException.java | 19 + .../db/{ddl => }/util/CallbackClosure.java | 4 +- .../db/{ddl => }/util/Jdbc3Utils.java | 4 +- .../util/MultiInstanceofPredicate.java | 2 +- .../symmetric/db/{ddl => }/util/package.html | 0 .../symmetric/db/{ddl => }/io/mapping.xml | 16 +- .../org/jumpmind/symmetric/ddl/TestBase.java | 127 - .../symmetric/ddl/TestPlatformBase.java | 219 -- .../alteration/TestAlterationAlgorithm.java | 2723 ---------------- .../ddl/alteration/TestModelComparator.java | 1283 -------- .../symmetric/ddl/alteration/package.html | 29 - .../symmetric/ddl/io/TestDatabaseIO.java | 1305 -------- .../jumpmind/symmetric/ddl/io/package.html | 29 - .../ddl/model/TestArrayAccessAtTable.java | 125 - .../jumpmind/symmetric/ddl/model/package.html | 29 - .../org/jumpmind/symmetric/ddl/package.html | 29 - .../ddl/platform/TestCloudscapePlatform.java | 169 - .../ddl/platform/TestDB2Platform.java | 171 - .../ddl/platform/TestDerbyPlatform.java | 169 - .../ddl/platform/TestFirebirdPlatform.java | 181 -- .../ddl/platform/TestHsqlDbPlatform.java | 180 -- .../ddl/platform/TestInterbasePlatform.java | 181 -- .../ddl/platform/TestMSSqlPlatform.java | 353 --- .../ddl/platform/TestMySql50Platform.java | 202 -- .../ddl/platform/TestMySqlPlatform.java | 216 -- .../ddl/platform/TestOracle8Platform.java | 177 -- .../ddl/platform/TestOracle9Platform.java | 167 - .../symmetric/ddl/platform/TestPlatform.java | 48 - .../ddl/platform/TestPlatformImplBase.java | 56 - .../ddl/platform/TestPlatformUtils.java | 363 --- .../ddl/platform/TestPostgresqlPlatform.java | 173 - .../ddl/platform/TestSqlBuilder.java | 66 - .../ddl/platform/TestSybasePlatform.java | 208 -- .../symmetric/ddl/platform/package.html | 29 - .../src/test/resources/jdbc.properties.axion | 27 - .../src/test/resources/jdbc.properties.db2 | 31 - .../src/test/resources/jdbc.properties.derby | 43 - .../resources/jdbc.properties.derby-embedded | 36 - .../test/resources/jdbc.properties.firebird | 35 - .../src/test/resources/jdbc.properties.hsqldb | 38 - .../resources/jdbc.properties.interbase2007 | 35 - .../resources/jdbc.properties.interbase75 | 35 - .../src/test/resources/jdbc.properties.maxdb | 34 - .../src/test/resources/jdbc.properties.mckoi | 37 - .../src/test/resources/jdbc.properties.mysql | 37 - .../test/resources/jdbc.properties.mysql50 | 37 - .../test/resources/jdbc.properties.oracle10 | 49 - .../test/resources/jdbc.properties.oracle9 | 49 - .../test/resources/jdbc.properties.postgresql | 52 - .../src/test/resources/jdbc.properties.sapdb | 34 - .../resources/jdbc.properties.sqlserver2000 | 42 - .../resources/jdbc.properties.sqlserver2005 | 36 - .../test/resources/jdbc.properties.sybaseASE | 36 - .../jumpmind/symmetric/SymmetricLauncher.java | 30 +- .../symmetric/map/AddColumnsFilter.java | 2 +- .../map/ChangeColumnsNamesFilter.java | 2 +- .../symmetric/map/RemoveColumnsFilter.java | 2 +- .../db/AbstractDbDialectUnitTest.java | 4 +- .../symmetric/db/SqlScriptUnitTest.java | 1 + .../ddl/platform/h2/H2PlatformUnitTest.java | 138 - .../symmetric/extract/DataExtractorTest.java | 52 +- .../impl/TriggerRouterServiceTest.java | 2 +- .../symmetric/test/SimpleIntegrationTest.java | 2 +- .../symmetric/test/TestSetupUtil.java | 28 +- .../symmetric/util/AppUtilsUnitTest.java | 24 +- .../jumpmind/symmetric/util/FormatUtils.java | 60 + .../symmetric/util/FormatUtilsTest.java | 30 + 258 files changed, 8506 insertions(+), 22606 deletions(-) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/AbstractDatabasePlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/DatabaseOperationException.java (94%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformFactory.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/PlatformInfo.java => DatabasePlatformInfo.java} (96%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformUtils.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/DdlUtilsException.java (86%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/IDatabasePlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/AddColumnChange.java (90%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/AddForeignKeyChange.java (86%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/AddIndexChange.java (84%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/AddPrimaryKeyChange.java (88%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/AddTableChange.java (83%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/ColumnAutoIncrementChange.java (87%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/ColumnChange.java (88%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/ColumnDataTypeChange.java (88%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/ColumnDefaultValueChange.java (88%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/ColumnRequiredChange.java (87%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/ColumnSizeChange.java (88%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration/ModelChange.java => alter/IModelChange.java} (84%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/ModelComparator.java (52%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/PrimaryKeyChange.java (90%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/RemoveColumnChange.java (86%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/RemoveForeignKeyChange.java (86%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/RemoveIndexChange.java (86%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/RemovePrimaryKeyChange.java (88%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/RemoveTableChange.java (87%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/TableChange.java (85%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/TableChangeImplBase.java (89%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl/alteration => alter}/package.html (100%) delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformFactory.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformUtils.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/CreationParameters.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/PlatformImplBase.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/SqlBuilder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapeBuilder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapePlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/package.html delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Builder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Builder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyPlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/h2/H2Builder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbBuilder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbPlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbasePlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlPlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50ModelReader.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlBuilder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlPlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Builder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Builder.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle9Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/OracleModelReader.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlPlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseASE15Platform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybasePlatform.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/JdbcSupport.java delete mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/SqlTokenizer.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/io/DatabaseIO.java (98%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/io/DigesterRules.java (94%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/io/LocalEntityResolver.java (98%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/io/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/Column.java (99%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/Database.java (99%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/ForeignKey.java (99%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/Index.java (98%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/IndexColumn.java (99%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/IndexImpBase.java (94%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/JdbcTypeCategoryEnum.java (96%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/ModelException.java (91%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/NonUniqueIndex.java (95%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/Reference.java (99%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/Table.java (99%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/TypeMap.java (99%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/UniqueIndex.java (98%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/model/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/package.html (89%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/DatabaseMetaDataWrapper.java (96%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/DefaultValueHelper.java (93%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/JdbcModelReader.java (97%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/MetaDataColumnDescriptor.java (95%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/SqlBuilder.java create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Builder.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/db2/Db2ModelReader.java (89%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Platform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/db2/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/derby/DerbyBuilder.java (54%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/derby/DerbyModelReader.java (83%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyPlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/derby/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/firebird/FirebirdBuilder.java (51%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/firebird/FirebirdModelReader.java (56%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/firebird/FirebirdPlatform.java (84%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/firebird/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/greenplum/GreenplumModelReader.java (86%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/greenplum/GreenplumPlatform.java (66%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/h2/H2Builder.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/h2/H2ModelReader.java (85%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/h2/H2Platform.java (77%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbBuilder.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/hsqldb/HsqlDbModelReader.java (61%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbPlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/hsqldb/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/hsqldb2/HsqlDb2Builder.java (56%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/hsqldb2/HsqlDb2ModelReader.java (79%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2Platform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/informix/InformixBuilder.java (67%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/informix/InformixModelReader.java (83%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/informix/InformixPlatform.java (70%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/interbase/InterbaseBuilder.java (58%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/interbase/InterbaseModelReader.java (58%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbasePlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/interbase/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/mssql/MSSqlBuilder.java (55%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/mssql/MSSqlModelReader.java (90%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlPlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/mssql/package.html (100%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlBuilder.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/mysql/MySqlModelReader.java (55%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlPlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/mysql/package.html (100%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleBuilder.java create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleModelReader.java create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OraclePlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/oracle/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/postgresql/PostgreSqlBuilder.java (55%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/postgresql/PostgreSqlModelReader.java (91%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlPlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/postgresql/package.html (100%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/sqlite/SqLiteBuilder.java (80%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/sqlite/SqLiteModelReader.java (84%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/sqlite/SqLitePlatform.java (79%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/sybase/SybaseBuilder.java (50%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/sybase/SybaseModelReader.java (91%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybasePlatform.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/platform/sybase/package.html (100%) rename symmetric/{symmetric-core/src/main/java/org/jumpmind/symmetric/db => symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql}/SqlScript.java (76%) create mode 100644 symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/SqlScriptException.java rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/util/CallbackClosure.java (95%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/util/Jdbc3Utils.java (95%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/util/MultiInstanceofPredicate.java (94%) rename symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/{ddl => }/util/package.html (100%) rename symmetric/symmetric-db/src/main/resources/org/jumpmind/symmetric/db/{ddl => }/io/mapping.xml (83%) delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestBase.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestPlatformBase.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestAlterationAlgorithm.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestModelComparator.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/package.html delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/TestDatabaseIO.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/package.html delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/TestArrayAccessAtTable.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/package.html delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/package.html delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestCloudscapePlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDB2Platform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDerbyPlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestFirebirdPlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestHsqlDbPlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestInterbasePlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMSSqlPlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySql50Platform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySqlPlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle8Platform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle9Platform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformImplBase.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformUtils.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPostgresqlPlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSqlBuilder.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSybasePlatform.java delete mode 100644 symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/package.html delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.axion delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.db2 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.derby delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.derby-embedded delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.firebird delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.hsqldb delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase2007 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase75 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.maxdb delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.mckoi delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql50 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle10 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle9 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.postgresql delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.sapdb delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2000 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2005 delete mode 100644 symmetric/symmetric-db/src/test/resources/jdbc.properties.sybaseASE delete mode 100644 symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/ddl/platform/h2/H2PlatformUnitTest.java create mode 100644 symmetric/symmetric-util/src/main/java/org/jumpmind/symmetric/util/FormatUtils.java create mode 100644 symmetric/symmetric-util/src/test/java/org/jumpmind/symmetric/util/FormatUtilsTest.java diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java index 8659b90e99..ee60d36b5a 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java @@ -38,7 +38,7 @@ import org.jumpmind.symmetric.common.logging.LogFactory; import org.jumpmind.symmetric.config.PropertiesFactoryBean; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.ext.IExtensionPointManager; import org.jumpmind.symmetric.job.IJobManager; import org.jumpmind.symmetric.model.Node; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java index 4793fa6540..4158a9aaf0 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java @@ -56,15 +56,15 @@ import org.jumpmind.symmetric.common.ParameterConstants; import org.jumpmind.symmetric.common.logging.ILog; import org.jumpmind.symmetric.common.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.io.DatabaseIO; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; +import org.jumpmind.symmetric.db.io.DatabaseIO; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; import org.jumpmind.symmetric.db.sql.DmlStatement; +import org.jumpmind.symmetric.db.sql.SqlScript; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.db.sql.SqlConstants; import org.jumpmind.symmetric.db.sybase.SybaseDbDialect; @@ -78,6 +78,7 @@ import org.jumpmind.symmetric.model.TriggerRouter; import org.jumpmind.symmetric.service.IParameterService; import org.jumpmind.symmetric.util.AppUtils; +import org.jumpmind.symmetric.util.FormatUtils; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.TransientDataAccessResourceException; @@ -101,7 +102,7 @@ abstract public class AbstractDbDialect implements IDbDialect { protected JdbcTemplate jdbcTemplate; - protected Platform platform; + protected IDatabasePlatform platform; protected Database cachedModel = new Database(); @@ -212,7 +213,7 @@ public int getMaxTriggerNameLength() { : MAX_SYMMETRIC_SUPPORTED_TRIGGER_SIZE; } - public void init(Platform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { + public void init(IDatabasePlatform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { log.info("DbDialectInUse", this.getClass().getName()); this.jdbcTemplate = jdbcTemplate; this.queryTimeoutInSeconds = queryTimeout; @@ -552,22 +553,22 @@ protected String createPostTriggerDDL(DataEventType dml, Trigger trigger, Trigge } public String getCreateSymmetricDDL() { - Database db = readSymmetricSchemaFromXml(); - prefixConfigDatabase(db); - return platform.getCreateTablesSql(db, true, true); + Database database = readSymmetricSchemaFromXml(); + prefixConfigDatabase(database); + StringWriter writer = new StringWriter(); + SqlBuilder builder = platform.createSqlBuilder(writer); + builder.createTables(database, true); + return writer.getBuffer().toString(); } - public String getCreateTableSQL(TriggerRouter trig) { - Table table = getTable(null, trig.getTrigger().getSourceSchemaName(), trig.getTrigger() - .getSourceTableName(), true); + public String getCreateTableSQL(TriggerRouter triggerRouter) { + Table table = getTable(null, triggerRouter.getTrigger().getSourceSchemaName(), + triggerRouter.getTrigger().getSourceTableName(), true); String sql = null; - try { - StringWriter buffer = new StringWriter(); - platform.getSqlBuilder().setWriter(buffer); - platform.getSqlBuilder().createTable(cachedModel, table); - sql = buffer.toString(); - } catch (IOException e) { - } + StringWriter writer = new StringWriter(); + SqlBuilder builder = platform.createSqlBuilder(writer); + builder.createTable(cachedModel, table); + sql = writer.toString(); return sql; } @@ -604,7 +605,7 @@ public String getCreateTableXML(TriggerRouter triggerRouter) { public void createTables(String xml) { StringReader reader = new StringReader(xml); Database db = new DatabaseIO().read(reader); - platform.createTables(db, true, true); + platform.createDatabase(jdbcTemplate.getDataSource(), db, true, true); } public boolean doesDatabaseNeedConfigured() { @@ -663,9 +664,10 @@ protected boolean createTablesIfNecessary() { } } - SqlBuilder builder = platform.getSqlBuilder(); + StringWriter writer = new StringWriter(); + SqlBuilder builder = platform.createSqlBuilder(writer); - if (builder.isAlterDatabase(modelFromDatabase, modelFromXml, null)) { + if (builder.isAlterDatabase(modelFromDatabase, modelFromXml)) { log.info("TablesAutoUpdatingFoundTablesToAlter"); DataSource ds = jdbcTemplate.getDataSource(); String delimiter = platform.getPlatformInfo().getSqlCommandDelimiter(); @@ -676,9 +678,7 @@ protected boolean createTablesIfNecessary() { new SqlScript(sql, ds, true, delimiter, null).execute(); } - StringWriter writer = new StringWriter(); - builder.setWriter(writer); - builder.alterDatabase(modelFromDatabase, modelFromXml, null); + builder.alterDatabase(modelFromDatabase, modelFromXml); String alterSql = writer.toString(); if (log.isDebugEnabled()) { log.debug("TablesAutoUpdatingAlterSql", alterSql); @@ -762,7 +762,7 @@ protected void fixIndexes(Table table, String tablePrefix) throws CloneNotSuppor } } - public Platform getPlatform() { + public IDatabasePlatform getPlatform() { return this.platform; } @@ -878,7 +878,8 @@ public Object[] getObjectValues(BinaryEncoding encoding, String[] values, objectValue = getDate(value, SqlConstants.TIMESTAMP_PATTERNS); } else if (type == Types.TIMESTAMP || (type == Types.DATE && isDateOverrideToTimestamp())) { - objectValue = new Timestamp(getTime(value, SqlConstants.TIMESTAMP_PATTERNS)); + objectValue = new Timestamp(getTime(value, + SqlConstants.TIMESTAMP_PATTERNS)); } else if (type == Types.CHAR) { String charValue = value.toString(); if ((StringUtils.isBlank(charValue) && isBlankCharColumnSpacePadded()) @@ -1201,7 +1202,7 @@ public boolean areDatabaseTransactionsPendingSince(long time) { public long getDatabaseTime() { try { String sql = "select current_timestamp from " + tablePrefix + "_node_identity"; - sql = AppUtils.replaceTokens(sql, getSqlScriptReplacementTokens(), false); + sql = FormatUtils.replaceTokens(sql, getSqlScriptReplacementTokens(), false); return jdbcTemplate.queryForObject(sql, java.util.Date.class).getTime(); } catch (Exception ex) { @@ -1270,7 +1271,7 @@ public String getDriverVersion() { public String scrubSql(String sql) { Map replacementTokens = getSqlScriptReplacementTokens(); if (replacementTokens != null) { - return AppUtils.replaceTokens(sql, replacementTokens, false).trim(); + return FormatUtils.replaceTokens(sql, replacementTokens, false).trim(); } else { return sql; } @@ -1315,10 +1316,10 @@ public void addDatabaseUpgradeListener(IDatabaseUpgradeListener listener) { protected void initLobHandler() { } - public DmlStatement createStatementBuilder(DmlType type, String catalogName, String schemaName, String tableName, Column[] keys, - Column[] columns, Column[] preFilteredColumns) { - return new DmlStatement(type, catalogName, schemaName, tableName, keys, columns, preFilteredColumns, - isDateOverrideToTimestamp(), getIdentifierQuoteString()); + public DmlStatement createStatementBuilder(DmlType type, String catalogName, String schemaName, + String tableName, Column[] keys, Column[] columns, Column[] preFilteredColumns) { + return new DmlStatement(type, catalogName, schemaName, tableName, keys, columns, + preFilteredColumns, isDateOverrideToTimestamp(), getIdentifierQuoteString()); } public void setPrimaryKeyViolationCodes(int[] primaryKeyViolationCodes) { diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractEmbeddedDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractEmbeddedDbDialect.java index edef36d727..3aa05166e2 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractEmbeddedDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractEmbeddedDbDialect.java @@ -20,7 +20,7 @@ package org.jumpmind.symmetric.db; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.model.Channel; import org.jumpmind.symmetric.model.Node; import org.jumpmind.symmetric.model.Trigger; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AutoIncrementColumnFilter.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AutoIncrementColumnFilter.java index c3084625f8..6c556717d1 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AutoIncrementColumnFilter.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AutoIncrementColumnFilter.java @@ -24,8 +24,8 @@ import java.util.ArrayList; import org.apache.commons.collections.CollectionUtils; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.load.IColumnFilter; import org.jumpmind.symmetric.load.IDataLoaderContext; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java index 05acd9baa9..652eb98e2c 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java @@ -26,26 +26,21 @@ import org.jumpmind.symmetric.common.logging.ILog; import org.jumpmind.symmetric.common.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformFactory; -import org.jumpmind.symmetric.db.ddl.PlatformUtils; -import org.jumpmind.symmetric.db.ddl.platform.db2.Db2Platform; -import org.jumpmind.symmetric.db.ddl.platform.derby.DerbyPlatform; -import org.jumpmind.symmetric.db.ddl.platform.firebird.FirebirdPlatform; -import org.jumpmind.symmetric.db.ddl.platform.greenplum.GreenplumPlatform; -import org.jumpmind.symmetric.db.ddl.platform.h2.H2Platform; -import org.jumpmind.symmetric.db.ddl.platform.hsqldb.HsqlDbPlatform; -import org.jumpmind.symmetric.db.ddl.platform.hsqldb2.HsqlDb2Platform; -import org.jumpmind.symmetric.db.ddl.platform.informix.InformixPlatform; -import org.jumpmind.symmetric.db.ddl.platform.interbase.InterbasePlatform; -import org.jumpmind.symmetric.db.ddl.platform.mssql.MSSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.mysql.MySqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle10Platform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle8Platform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle9Platform; -import org.jumpmind.symmetric.db.ddl.platform.postgresql.PostgreSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.sqlite.SqLitePlatform; -import org.jumpmind.symmetric.db.ddl.platform.sybase.SybasePlatform; +import org.jumpmind.symmetric.db.platform.db2.Db2Platform; +import org.jumpmind.symmetric.db.platform.derby.DerbyPlatform; +import org.jumpmind.symmetric.db.platform.firebird.FirebirdPlatform; +import org.jumpmind.symmetric.db.platform.greenplum.GreenplumPlatform; +import org.jumpmind.symmetric.db.platform.h2.H2Platform; +import org.jumpmind.symmetric.db.platform.hsqldb.HsqlDbPlatform; +import org.jumpmind.symmetric.db.platform.hsqldb2.HsqlDb2Platform; +import org.jumpmind.symmetric.db.platform.informix.InformixPlatform; +import org.jumpmind.symmetric.db.platform.interbase.InterbasePlatform; +import org.jumpmind.symmetric.db.platform.mssql.MSSqlPlatform; +import org.jumpmind.symmetric.db.platform.mysql.MySqlPlatform; +import org.jumpmind.symmetric.db.platform.oracle.OraclePlatform; +import org.jumpmind.symmetric.db.platform.postgresql.PostgreSqlPlatform; +import org.jumpmind.symmetric.db.platform.sqlite.SqLitePlatform; +import org.jumpmind.symmetric.db.platform.sybase.SybasePlatform; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.FactoryBean; @@ -78,7 +73,7 @@ public IDbDialect getObject() throws Exception { waitForAvailableDatabase(); - Platform pf = PlatformFactory.createNewPlatformInstance(jdbcTemplate.getDataSource()); + IDatabasePlatform pf = DatabasePlatformFactory.createNewPlatformInstance(jdbcTemplate.getDataSource()); if (forceDelimitedIdentifierModeOn) { pf.setDelimitedIdentifierModeOn(true); @@ -92,11 +87,7 @@ public IDbDialect getObject() throws Exception { if (pf instanceof MySqlPlatform) { dialect = (AbstractDbDialect) beanFactory.getBean("mysqlDialect"); - } else if (pf instanceof Oracle8Platform) { - dialect = (AbstractDbDialect) beanFactory.getBean("oracleDialect"); - } else if (pf instanceof Oracle9Platform) { - dialect = (AbstractDbDialect) beanFactory.getBean("oracleDialect"); - } else if (pf instanceof Oracle10Platform) { + } else if (pf instanceof OraclePlatform) { dialect = (AbstractDbDialect) beanFactory.getBean("oracleDialect"); } else if (pf instanceof MSSqlPlatform) { dialect = (AbstractDbDialect) beanFactory.getBean("msSqlDialect"); @@ -117,13 +108,13 @@ public IDbDialect getObject() throws Exception { } else if (pf instanceof InformixPlatform) { dialect = (AbstractDbDialect) beanFactory.getBean("informixDialect"); } else if (pf instanceof Db2Platform) { - String currentDbProductVersion = PlatformUtils.getDatabaseProductVersion(jdbcTemplate + String currentDbProductVersion = DatabasePlatformUtils.getDatabaseProductVersion(jdbcTemplate .getDataSource()); if (currentDbProductVersion.equals(db2zSeriesProductVersion)) { dialect = (AbstractDbDialect) beanFactory.getBean("db2zSeriesDialect"); } else { - int dbMajorVersion = PlatformUtils.getDatabaseMajorVersion(jdbcTemplate.getDataSource()); - int dbMinorVersion = PlatformUtils.getDatabaseMinorVersion(jdbcTemplate.getDataSource()); + int dbMajorVersion = DatabasePlatformUtils.getDatabaseMajorVersion(jdbcTemplate.getDataSource()); + int dbMinorVersion = DatabasePlatformUtils.getDatabaseMinorVersion(jdbcTemplate.getDataSource()); if (dbMajorVersion < 9 || (dbMajorVersion == 9 && dbMinorVersion < 5)) { dialect = (AbstractDbDialect) beanFactory.getBean("db2Dialect"); } else { diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java index 4d47f86fc0..e4d2551c94 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java @@ -23,9 +23,8 @@ import java.util.Map; import java.util.Set; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.ext.IDatabaseUpgradeListener; @@ -90,7 +89,7 @@ public void removeTrigger(StringBuilder sqlBuffer, String catalogName, String sc public void initTablesAndFunctions(); - public Platform getPlatform(); + public IDatabasePlatform getPlatform(); public String getName(); diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java index 68064f8328..0fea3bd2e1 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java @@ -28,8 +28,8 @@ import org.apache.commons.lang.StringUtils; import org.jumpmind.symmetric.Version; import org.jumpmind.symmetric.common.Constants; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.mssql.MsSqlDbDialect; import org.jumpmind.symmetric.db.postgresql.PostgreSqlDbDialect; import org.jumpmind.symmetric.model.Channel; @@ -38,7 +38,7 @@ import org.jumpmind.symmetric.model.Trigger; import org.jumpmind.symmetric.model.TriggerHistory; import org.jumpmind.symmetric.model.TriggerRouter; -import org.jumpmind.symmetric.util.AppUtils; +import org.jumpmind.symmetric.util.FormatUtils; /** * Responsible for generating dialect specific SQL such as trigger bodies and @@ -104,27 +104,27 @@ public String createInitalLoadSql(Node node, IDbDialect dialect, TriggerRouter t dialect.getInitialLoadTableAlias(), "", columns, dialect, DataEventType.INSERT, false, channel, triggerRouter.getTrigger()).columnString; - sql = AppUtils.replace("columns", columnsText, sql); - sql = AppUtils + sql = FormatUtils.replace("columns", columnsText, sql); + sql = FormatUtils .replace( "whereClause", StringUtils.isBlank(triggerRouter.getInitialLoadSelect()) ? Constants.ALWAYS_TRUE_CONDITION : triggerRouter.getInitialLoadSelect(), sql); - sql = AppUtils.replace("tableName", quote(table.getName(), dialect), sql); - sql = AppUtils.replace("schemaName", triggerHistory == null ? getSourceTablePrefix(triggerRouter.getTrigger(), dialect) : getSourceTablePrefix(triggerHistory, dialect), sql); - sql = AppUtils.replace( + sql = FormatUtils.replace("tableName", quote(table.getName(), dialect), sql); + sql = FormatUtils.replace("schemaName", triggerHistory == null ? getSourceTablePrefix(triggerRouter.getTrigger(), dialect) : getSourceTablePrefix(triggerHistory, dialect), sql); + sql = FormatUtils.replace( "primaryKeyWhereString", getPrimaryKeyWhereString(dialect.getInitialLoadTableAlias(), table.getPrimaryKeyColumns()), sql); // Replace these parameters to give the initiaLoadContition a chance to // reference the node that is being loaded - sql = AppUtils.replace("groupId", node.getNodeGroupId(), sql); - sql = AppUtils.replace("externalId", node.getExternalId(), sql); - sql = AppUtils.replace("nodeId", node.getNodeId(), sql); + sql = FormatUtils.replace("groupId", node.getNodeGroupId(), sql); + sql = FormatUtils.replace("externalId", node.getExternalId(), sql); + sql = FormatUtils.replace("nodeId", node.getNodeId(), sql); sql = replaceDefaultSchemaAndCatalog(dialect, triggerRouter.getTrigger(), sql); - sql = AppUtils.replace("prefixName", dialect.getTablePrefix(), sql); - sql = AppUtils.replace("oracleToClob", + sql = FormatUtils.replace("prefixName", dialect.getTablePrefix(), sql); + sql = FormatUtils.replace("oracleToClob", triggerRouter.getTrigger().isUseCaptureLobs() ? "to_clob('')||" : "", sql); return sql; @@ -165,10 +165,10 @@ protected String replaceDefaultSchemaAndCatalog(IDbDialect dbDialect, Trigger tr boolean resolveSchemaAndCatalogs = trigger.getSourceCatalogName() != null || trigger.getSourceSchemaName() != null; - sql = AppUtils.replace("defaultSchema", resolveSchemaAndCatalogs && defaultSchema != null + sql = FormatUtils.replace("defaultSchema", resolveSchemaAndCatalogs && defaultSchema != null && defaultSchema.length() > 0 ? defaultSchema + "." : "", sql); - return AppUtils.replace("defaultCatalog", resolveSchemaAndCatalogs + return FormatUtils.replace("defaultCatalog", resolveSchemaAndCatalogs && defaultCatalog != null && defaultCatalog.length() > 0 ? defaultCatalog + "." : "", sql); } @@ -181,15 +181,15 @@ public String createCsvDataSql(IDbDialect dialect, Trigger trigger, TriggerHisto String columnsText = buildColumnString(dialect.getInitialLoadTableAlias(), dialect.getInitialLoadTableAlias(), "", columns, dialect, DataEventType.INSERT, false, channel, trigger).columnString; - sql = AppUtils.replace("columns", columnsText, sql); - sql = AppUtils.replace("oracleToClob", trigger.isUseCaptureLobs() ? "to_clob('')||" : "", + sql = FormatUtils.replace("columns", columnsText, sql); + sql = FormatUtils.replace("oracleToClob", trigger.isUseCaptureLobs() ? "to_clob('')||" : "", sql); - sql = AppUtils.replace("tableName", quote(table.getName(), dialect), sql); - sql = AppUtils.replace("schemaName", triggerHistory == null ? getSourceTablePrefix(trigger, dialect) : getSourceTablePrefix(triggerHistory, dialect), sql); + sql = FormatUtils.replace("tableName", quote(table.getName(), dialect), sql); + sql = FormatUtils.replace("schemaName", triggerHistory == null ? getSourceTablePrefix(trigger, dialect) : getSourceTablePrefix(triggerHistory, dialect), sql); - sql = AppUtils.replace("whereClause", whereClause, sql); - sql = AppUtils.replace( + sql = FormatUtils.replace("whereClause", whereClause, sql); + sql = FormatUtils.replace( "primaryKeyWhereString", getPrimaryKeyWhereString(dialect.getInitialLoadTableAlias(), table.getPrimaryKeyColumns()), sql); @@ -207,13 +207,13 @@ public String createCsvPrimaryKeySql(IDbDialect dialect, Trigger trigger, Trigge String columnsText = buildColumnString(dialect.getInitialLoadTableAlias(), dialect.getInitialLoadTableAlias(), "", columns, dialect, DataEventType.INSERT, false, channel, trigger).toString(); - sql = AppUtils.replace("columns", columnsText, sql); - sql = AppUtils.replace("oracleToClob", trigger.isUseCaptureLobs() ? "to_clob('')||" : "", + sql = FormatUtils.replace("columns", columnsText, sql); + sql = FormatUtils.replace("oracleToClob", trigger.isUseCaptureLobs() ? "to_clob('')||" : "", sql); - sql = AppUtils.replace("tableName", quote(table.getName(), dialect), sql); - sql = AppUtils.replace("schemaName", triggerHistory == null ? getSourceTablePrefix(trigger, dialect) : getSourceTablePrefix(triggerHistory, dialect), sql); - sql = AppUtils.replace("whereClause", whereClause, sql); - sql = AppUtils.replace("primaryKeyWhereString", + sql = FormatUtils.replace("tableName", quote(table.getName(), dialect), sql); + sql = FormatUtils.replace("schemaName", triggerHistory == null ? getSourceTablePrefix(trigger, dialect) : getSourceTablePrefix(triggerHistory, dialect), sql); + sql = FormatUtils.replace("whereClause", whereClause, sql); + sql = FormatUtils.replace("primaryKeyWhereString", getPrimaryKeyWhereString(dialect.getInitialLoadTableAlias(), columns), sql); return sql; @@ -262,11 +262,11 @@ public String replaceTemplateVariables(IDbDialect dialect, DataEventType dml, Tr TriggerHistory history, Channel channel, String tablePrefix, Table table, String defaultCatalog, String defaultSchema, String ddl) { - ddl = AppUtils.replace("targetTableName", getDefaultTargetTableName(trigger, history), ddl); + ddl = FormatUtils.replace("targetTableName", getDefaultTargetTableName(trigger, history), ddl); - ddl = AppUtils.replace("triggerName", history.getTriggerNameForDmlType(dml), ddl); - ddl = AppUtils.replace("channelName", trigger.getChannelId(), ddl); - ddl = AppUtils.replace("triggerHistoryId", + ddl = FormatUtils.replace("triggerName", history.getTriggerNameForDmlType(dml), ddl); + ddl = FormatUtils.replace("channelName", trigger.getChannelId(), ddl); + ddl = FormatUtils.replace("triggerHistoryId", Integer.toString(history == null ? -1 : history.getTriggerHistoryId()), ddl); String triggerExpression = dialect.getTransactionTriggerExpression(defaultCatalog, defaultSchema, trigger); @@ -274,114 +274,114 @@ public String replaceTemplateVariables(IDbDialect dialect, DataEventType dml, Tr && !StringUtils.isBlank(trigger.getTxIdExpression())) { triggerExpression = trigger.getTxIdExpression(); } - ddl = AppUtils.replace("txIdExpression", + ddl = FormatUtils.replace("txIdExpression", dialect.preProcessTriggerSqlClause(triggerExpression), ddl); - ddl = AppUtils + ddl = FormatUtils .replace("externalSelect", (trigger.getExternalSelect() == null ? "null" : "(" + dialect.preProcessTriggerSqlClause(trigger.getExternalSelect()) + ")"), ddl); - ddl = AppUtils.replace("syncOnInsertCondition", + ddl = FormatUtils.replace("syncOnInsertCondition", dialect.preProcessTriggerSqlClause(trigger.getSyncOnInsertCondition()), ddl); - ddl = AppUtils.replace("syncOnUpdateCondition", + ddl = FormatUtils.replace("syncOnUpdateCondition", dialect.preProcessTriggerSqlClause(trigger.getSyncOnUpdateCondition()), ddl); - ddl = AppUtils.replace("syncOnDeleteCondition", + ddl = FormatUtils.replace("syncOnDeleteCondition", dialect.preProcessTriggerSqlClause(trigger.getSyncOnDeleteCondition()), ddl); - ddl = AppUtils.replace("dataHasChangedCondition", + ddl = FormatUtils.replace("dataHasChangedCondition", dialect.preProcessTriggerSqlClause(dialect.getDataHasChangedCondition(trigger)), ddl); - ddl = AppUtils.replace("sourceNodeExpression", dialect.getSourceNodeExpression(), ddl); + ddl = FormatUtils.replace("sourceNodeExpression", dialect.getSourceNodeExpression(), ddl); - ddl = AppUtils.replace("oracleLobType", trigger.isUseCaptureLobs() ? "clob" : "long", ddl); + ddl = FormatUtils.replace("oracleLobType", trigger.isUseCaptureLobs() ? "clob" : "long", ddl); String syncTriggersExpression = dialect.getSyncTriggersExpression(); - ddl = AppUtils.replace("syncOnIncomingBatchCondition", + ddl = FormatUtils.replace("syncOnIncomingBatchCondition", trigger.isSyncOnIncomingBatch() ? Constants.ALWAYS_TRUE_CONDITION : syncTriggersExpression, ddl); - ddl = AppUtils.replace("origTableAlias", ORIG_TABLE_ALIAS, ddl); + ddl = FormatUtils.replace("origTableAlias", ORIG_TABLE_ALIAS, ddl); Column[] columns = trigger.orderColumnsForTable(table); ColumnString columnString = buildColumnString(ORIG_TABLE_ALIAS, newTriggerValue, newColumnPrefix, columns, dialect, dml, false, channel, trigger); - ddl = AppUtils.replace("columns", columnString.toString(), ddl); + ddl = FormatUtils.replace("columns", columnString.toString(), ddl); ddl = replaceDefaultSchemaAndCatalog(dialect, trigger, ddl); - ddl = AppUtils + ddl = FormatUtils .replace( "virtualOldNewTable", buildVirtualTableSql(dialect, oldColumnPrefix, newColumnPrefix, table.getColumns()), ddl); - ddl = AppUtils.replace( + ddl = FormatUtils.replace( "oldColumns", buildColumnString(ORIG_TABLE_ALIAS, oldTriggerValue, oldColumnPrefix, columns, dialect, dml, true, channel, trigger).toString(), ddl); ddl = eval(columnString.isBlobClob, "containsBlobClobColumns", ddl); // some column templates need tableName and schemaName - ddl = AppUtils.replace("tableName", history == null ? quote(trigger.getSourceTableName(), dialect) + ddl = FormatUtils.replace("tableName", history == null ? quote(trigger.getSourceTableName(), dialect) : quote(history.getSourceTableName(), dialect), ddl); - ddl = AppUtils.replace("schemaName", + ddl = FormatUtils.replace("schemaName", history == null ? getSourceTablePrefix(trigger, dialect) : getSourceTablePrefix(history, dialect), ddl); columns = table.getPrimaryKeyColumns(); - ddl = AppUtils.replace( + ddl = FormatUtils.replace( "oldKeys", buildColumnString(ORIG_TABLE_ALIAS, oldTriggerValue, oldColumnPrefix, columns, dialect, dml, true, channel, trigger).toString(), ddl); - ddl = AppUtils.replace("oldNewPrimaryKeyJoin", + ddl = FormatUtils.replace("oldNewPrimaryKeyJoin", aliasedPrimaryKeyJoin(oldTriggerValue, newTriggerValue, columns.length == 0 ? table.getColumns() : columns), ddl); - ddl = AppUtils.replace("tableNewPrimaryKeyJoin", + ddl = FormatUtils.replace("tableNewPrimaryKeyJoin", aliasedPrimaryKeyJoin(ORIG_TABLE_ALIAS, newTriggerValue, columns.length == 0 ? table.getColumns() : columns), ddl); - ddl = AppUtils.replace( + ddl = FormatUtils.replace( "primaryKeyWhereString", getPrimaryKeyWhereString(dml == DataEventType.DELETE ? oldTriggerValue : newTriggerValue, columns), ddl); - ddl = AppUtils.replace("declareOldKeyVariables", buildKeyVariablesDeclare(columns, "old"), + ddl = FormatUtils.replace("declareOldKeyVariables", buildKeyVariablesDeclare(columns, "old"), ddl); - ddl = AppUtils.replace("declareNewKeyVariables", buildKeyVariablesDeclare(columns, "new"), + ddl = FormatUtils.replace("declareNewKeyVariables", buildKeyVariablesDeclare(columns, "new"), ddl); String builtString = buildColumnNameString(oldTriggerValue, columns); - ddl = AppUtils.replace("oldKeyNames", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); + ddl = FormatUtils.replace("oldKeyNames", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); builtString = buildColumnNameString(newTriggerValue, columns); - ddl = AppUtils.replace("newKeyNames", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); + ddl = FormatUtils.replace("newKeyNames", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); builtString = buildKeyVariablesString(columns, "old"); - ddl = AppUtils.replace("oldKeyVariables", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); + ddl = FormatUtils.replace("oldKeyVariables", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); builtString = buildKeyVariablesString(columns, "new"); - ddl = AppUtils.replace("newKeyVariables", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); + ddl = FormatUtils.replace("newKeyVariables", StringUtils.isNotBlank(builtString) ? ","+builtString:"", ddl); - ddl = AppUtils.replace("varNewPrimaryKeyJoin", + ddl = FormatUtils.replace("varNewPrimaryKeyJoin", aliasedPrimaryKeyJoinVar(newTriggerValue, "new", columns), ddl); - ddl = AppUtils.replace("varOldPrimaryKeyJoin", + ddl = FormatUtils.replace("varOldPrimaryKeyJoin", aliasedPrimaryKeyJoinVar(oldTriggerValue, "old", columns), ddl); // replace $(newTriggerValue) and $(oldTriggerValue) - ddl = AppUtils.replace("newTriggerValue", newTriggerValue, ddl); - ddl = AppUtils.replace("oldTriggerValue", oldTriggerValue, ddl); - ddl = AppUtils.replace("newColumnPrefix", newColumnPrefix, ddl); - ddl = AppUtils.replace("oldColumnPrefix", oldColumnPrefix, ddl); - ddl = AppUtils.replace("prefixName", tablePrefix, ddl); + ddl = FormatUtils.replace("newTriggerValue", newTriggerValue, ddl); + ddl = FormatUtils.replace("oldTriggerValue", oldTriggerValue, ddl); + ddl = FormatUtils.replace("newColumnPrefix", newColumnPrefix, ddl); + ddl = FormatUtils.replace("oldColumnPrefix", oldColumnPrefix, ddl); + ddl = FormatUtils.replace("prefixName", tablePrefix, ddl); ddl = replaceDefaultSchemaAndCatalog(dialect, trigger, ddl); - ddl = AppUtils.replace("oracleToClob", trigger.isUseCaptureLobs() ? "to_clob('')||" : "", + ddl = FormatUtils.replace("oracleToClob", trigger.isUseCaptureLobs() ? "to_clob('')||" : "", ddl); switch (dml) { case DELETE: - ddl = AppUtils.replace("curTriggerValue", oldTriggerValue, ddl); - ddl = AppUtils.replace("curColumnPrefix", oldColumnPrefix, ddl); + ddl = FormatUtils.replace("curTriggerValue", oldTriggerValue, ddl); + ddl = FormatUtils.replace("curColumnPrefix", oldColumnPrefix, ddl); break; case INSERT: case UPDATE: default: - ddl = AppUtils.replace("curTriggerValue", newTriggerValue, ddl); - ddl = AppUtils.replace("curColumnPrefix", newColumnPrefix, ddl); + ddl = FormatUtils.replace("curTriggerValue", newTriggerValue, ddl); + ddl = FormatUtils.replace("curColumnPrefix", newColumnPrefix, ddl); break; } return ddl; @@ -633,10 +633,10 @@ private ColumnString buildColumnString(String origTableAlias, String tableAlias, throw new NotImplementedException(); } - String formattedColumnText = AppUtils.replace("columnName", + String formattedColumnText = FormatUtils.replace("columnName", String.format("%s%s", columnPrefix, column.getName()), templateToUse); - formattedColumnText = AppUtils.replace("masterCollation", + formattedColumnText = FormatUtils.replace("masterCollation", dbDialect.getMasterCollation(), formattedColumnText); if (isLob) { @@ -653,9 +653,9 @@ private ColumnString buildColumnString(String origTableAlias, String tableAlias, .substring(0, columnsText.length() - lastCommandToken.length()); } - columnsText = AppUtils.replace("origTableAlias", origTableAlias, columnsText); - columnsText = AppUtils.replace("tableAlias", tableAlias, columnsText); - columnsText = AppUtils.replace("prefixName", dbDialect.getTablePrefix(), columnsText); + columnsText = FormatUtils.replace("origTableAlias", origTableAlias, columnsText); + columnsText = FormatUtils.replace("tableAlias", tableAlias, columnsText); + columnsText = FormatUtils.replace("prefixName", dbDialect.getTablePrefix(), columnsText); return new ColumnString(columnsText, isLob); } @@ -847,10 +847,10 @@ public void setNewColumnPrefix(String newColumnPrefix) { public String getFunctionSql(String functionKey, String functionName, String defaultSchema) { if (this.functionTemplatesToInstall != null) { - String ddl = AppUtils.replace("functionName", functionName, + String ddl = FormatUtils.replace("functionName", functionName, this.functionTemplatesToInstall.get(functionKey)); - ddl = AppUtils.replace("version", Version.versionWithUnderscores(), ddl); - ddl = AppUtils.replace("defaultSchema", defaultSchema != null + ddl = FormatUtils.replace("version", Version.versionWithUnderscores(), ddl); + ddl = FormatUtils.replace("defaultSchema", defaultSchema != null && defaultSchema.length() > 0 ? defaultSchema + "." : "", ddl); return ddl; } else { @@ -860,9 +860,9 @@ public String getFunctionSql(String functionKey, String functionName, String def public String getFunctionInstalledSql(String functionName, String defaultSchema) { if (functionInstalledSql != null) { - String ddl = AppUtils.replace("functionName", functionName, functionInstalledSql); - ddl = AppUtils.replace("version", Version.versionWithUnderscores(), ddl); - ddl = AppUtils.replace("defaultSchema", defaultSchema != null + String ddl = FormatUtils.replace("functionName", functionName, functionInstalledSql); + ddl = FormatUtils.replace("version", Version.versionWithUnderscores(), ddl); + ddl = FormatUtils.replace("defaultSchema", defaultSchema != null && defaultSchema.length() > 0 ? defaultSchema : "", ddl); return ddl; } else { diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/db2/Db2v9DbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/db2/Db2v9DbDialect.java index 677306a3d1..f12b2927a5 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/db2/Db2v9DbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/db2/Db2v9DbDialect.java @@ -22,12 +22,9 @@ import java.net.URL; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.SqlScript; +import org.jumpmind.symmetric.db.sql.SqlScript; import org.springframework.jdbc.core.JdbcTemplate; -/* - * - */ public class Db2v9DbDialect extends Db2DbDialect implements IDbDialect { static final String SYNC_TRIGGERS_DISABLED_USER_VARIABLE = "sync_triggers_disabled"; @@ -42,7 +39,7 @@ protected void initTablesAndFunctionsForSpecificDialect() { try { log.info("EnvironmentVariablesCreating", SYNC_TRIGGERS_DISABLED_USER_VARIABLE, SYNC_TRIGGERS_DISABLED_NODE_VARIABLE); - new SqlScript(getSqlScriptUrl(), getPlatform().getDataSource(), ";").execute(); + new SqlScript(getSqlScriptUrl(), jdbcTemplate.getDataSource(), ";").execute(); } catch (Exception ex) { log.error("DB2DialectInitializingError", ex); } diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb/HsqlDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb/HsqlDbDialect.java index f0d4e31fc7..e04b41cbaa 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb/HsqlDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb/HsqlDbDialect.java @@ -24,8 +24,8 @@ import org.jumpmind.symmetric.db.AbstractEmbeddedDbDialect; import org.jumpmind.symmetric.db.BinaryEncoding; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.model.Trigger; import org.jumpmind.symmetric.model.TriggerHistory; import org.springframework.jdbc.core.JdbcTemplate; @@ -40,7 +40,7 @@ public class HsqlDbDialect extends AbstractEmbeddedDbDialect implements IDbDiale private boolean enforceStrictSize = true; @Override - public void init(Platform pf, int queryTimeout, final JdbcTemplate jdbcTemplate) { + public void init(IDatabasePlatform pf, int queryTimeout, final JdbcTemplate jdbcTemplate) { super.init(pf, queryTimeout, jdbcTemplate); jdbcTemplate.update("SET WRITE_DELAY 100 MILLIS"); jdbcTemplate.update("SET PROPERTY \"hsqldb.default_table_type\" 'cached'"); diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb2/HsqlDb2Dialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb2/HsqlDb2Dialect.java index 2eafcc09b0..fb86df0671 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb2/HsqlDb2Dialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/hsqldb2/HsqlDb2Dialect.java @@ -24,7 +24,7 @@ import org.jumpmind.symmetric.db.AbstractDbDialect; import org.jumpmind.symmetric.db.BinaryEncoding; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.Platform; +import org.jumpmind.symmetric.db.IDatabasePlatform; import org.jumpmind.symmetric.model.Trigger; import org.jumpmind.symmetric.model.TriggerHistory; import org.springframework.jdbc.core.JdbcTemplate; @@ -35,7 +35,7 @@ public class HsqlDb2Dialect extends AbstractDbDialect implements IDbDialect { @Override - public void init(Platform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { + public void init(IDatabasePlatform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { super.init(pf, queryTimeout, jdbcTemplate); jdbcTemplate.execute("SET DATABASE DEFAULT TABLE TYPE CACHED"); } diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/informix/InformixDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/informix/InformixDbDialect.java index b579d15700..3484b86f6e 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/informix/InformixDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/informix/InformixDbDialect.java @@ -27,7 +27,7 @@ import org.jumpmind.symmetric.db.AbstractDbDialect; import org.jumpmind.symmetric.db.AutoIncrementColumnFilter; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.Platform; +import org.jumpmind.symmetric.db.IDatabasePlatform; import org.jumpmind.symmetric.load.IColumnFilter; import org.jumpmind.symmetric.model.Trigger; import org.springframework.jdbc.core.JdbcTemplate; @@ -42,7 +42,7 @@ public InformixDbDialect() { } @Override - public void init(Platform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { + public void init(IDatabasePlatform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { super.init(pf, queryTimeout, jdbcTemplate); Map env = System.getenv(); String clientIdentifierMode = env.get("DELIMIDENT"); diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlDbDialect.java index dd236aea8f..53d4109f88 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlDbDialect.java @@ -33,7 +33,7 @@ import org.jumpmind.symmetric.db.AutoIncrementColumnFilter; import org.jumpmind.symmetric.db.BinaryEncoding; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.load.IColumnFilter; import org.jumpmind.symmetric.model.Trigger; import org.jumpmind.symmetric.model.TriggerHistory; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlDbDialect.java index 908b60f6cb..c6456bfa59 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlDbDialect.java @@ -32,7 +32,7 @@ import org.jumpmind.symmetric.db.AbstractDbDialect; import org.jumpmind.symmetric.db.BinaryEncoding; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.Platform; +import org.jumpmind.symmetric.db.IDatabasePlatform; import org.jumpmind.symmetric.model.Trigger; import org.jumpmind.symmetric.model.TriggerHistory; import org.springframework.jdbc.core.JdbcTemplate; @@ -61,7 +61,7 @@ protected void initTablesAndFunctionsForSpecificDialect() { } @Override - public void init(Platform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { + public void init(IDatabasePlatform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { super.init(pf, queryTimeout, jdbcTemplate); this.identifierQuoteString = "`"; } diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java index a16bdc7de1..b684dba5d0 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java @@ -30,9 +30,9 @@ import org.jumpmind.symmetric.db.AbstractDbDialect; import org.jumpmind.symmetric.db.BinaryEncoding; import org.jumpmind.symmetric.db.IDbDialect; +import org.jumpmind.symmetric.db.IDatabasePlatform; import org.jumpmind.symmetric.db.SequenceIdentifier; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.model.Channel; import org.jumpmind.symmetric.model.DataEventType; import org.jumpmind.symmetric.model.Trigger; @@ -55,7 +55,7 @@ public class OracleDbDialect extends AbstractDbDialect implements IDbDialect { String selectTransactionsSql; @Override - public void init(Platform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { + public void init(IDatabasePlatform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { super.init(pf, queryTimeout, jdbcTemplate); try { areDatabaseTransactionsPendingSince(System.currentTimeMillis()); diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlDbDialect.java index afb4c58985..028dde288e 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlDbDialect.java @@ -34,8 +34,8 @@ import org.jumpmind.symmetric.db.AbstractDbDialect; import org.jumpmind.symmetric.db.BinaryEncoding; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; import org.jumpmind.symmetric.db.sql.DmlStatement; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.model.Trigger; @@ -58,7 +58,7 @@ public class PostgreSqlDbDialect extends AbstractDbDialect implements IDbDialect private String transactionIdExpression = "null"; @Override - public void init(Platform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { + public void init(IDatabasePlatform pf, int queryTimeout, JdbcTemplate jdbcTemplate) { super.init(pf, 0, jdbcTemplate); } diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgresDmlStatement.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgresDmlStatement.java index 9bd6a1cb57..16f3e01ac4 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgresDmlStatement.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgresDmlStatement.java @@ -21,7 +21,7 @@ package org.jumpmind.symmetric.db.postgresql; import org.apache.commons.lang.ArrayUtils; -import org.jumpmind.symmetric.db.ddl.model.Column; +import org.jumpmind.symmetric.db.model.Column; import org.jumpmind.symmetric.db.sql.DmlStatement; public class PostgresDmlStatement extends DmlStatement { diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/sybase/SybaseDbDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/sybase/SybaseDbDialect.java index d53d9768e5..a7ba0978a6 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/sybase/SybaseDbDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/sybase/SybaseDbDialect.java @@ -36,7 +36,7 @@ import org.jumpmind.symmetric.db.AutoIncrementColumnFilter; import org.jumpmind.symmetric.db.BinaryEncoding; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.load.IColumnFilter; import org.jumpmind.symmetric.model.Trigger; import org.jumpmind.symmetric.model.TriggerHistory; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/ext/IDatabaseUpgradeListener.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/ext/IDatabaseUpgradeListener.java index ad18d48021..51ebd84a94 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/ext/IDatabaseUpgradeListener.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/ext/IDatabaseUpgradeListener.java @@ -3,7 +3,7 @@ import java.io.IOException; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.model.Database; +import org.jumpmind.symmetric.db.model.Database; public interface IDatabaseUpgradeListener extends IExtensionPoint { diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/AbstractStreamDataCommand.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/AbstractStreamDataCommand.java index 03e48aeed0..8fa9f54f01 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/AbstractStreamDataCommand.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/AbstractStreamDataCommand.java @@ -31,8 +31,8 @@ import org.jumpmind.symmetric.common.logging.ILog; import org.jumpmind.symmetric.common.logging.LogFactory; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.extract.DataExtractorContext; import org.jumpmind.symmetric.model.Data; import org.jumpmind.symmetric.model.Trigger; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/CsvExtractor.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/CsvExtractor.java index 4bd53adc50..0b93a6927d 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/CsvExtractor.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/extract/csv/CsvExtractor.java @@ -19,21 +19,21 @@ * under the License. */ package org.jumpmind.symmetric.extract.csv; -import java.io.IOException; -import java.io.Writer; - +import java.io.IOException; +import java.io.Writer; + import org.apache.commons.lang.StringUtils; -import org.jumpmind.symmetric.common.ParameterConstants; -import org.jumpmind.symmetric.common.csv.CsvConstants; -import org.jumpmind.symmetric.extract.DataExtractorContext; +import org.jumpmind.symmetric.common.ParameterConstants; +import org.jumpmind.symmetric.common.csv.CsvConstants; +import org.jumpmind.symmetric.extract.DataExtractorContext; import org.jumpmind.symmetric.extract.IDataExtractor; -import org.jumpmind.symmetric.model.Data; -import org.jumpmind.symmetric.model.DataEventType; -import org.jumpmind.symmetric.model.OutgoingBatch; -import org.jumpmind.symmetric.model.Router; -import org.jumpmind.symmetric.service.ITriggerRouterService; -import org.jumpmind.symmetric.util.AppUtils; -import org.jumpmind.symmetric.util.CsvUtils; +import org.jumpmind.symmetric.model.Data; +import org.jumpmind.symmetric.model.DataEventType; +import org.jumpmind.symmetric.model.OutgoingBatch; +import org.jumpmind.symmetric.model.Router; +import org.jumpmind.symmetric.service.ITriggerRouterService; +import org.jumpmind.symmetric.util.CsvUtils; +import org.jumpmind.symmetric.util.FormatUtils; /** * @see IDataExtractor @@ -117,7 +117,7 @@ protected void writeTable(Data data, String routerId, Writer out, DataExtractorC protected String getTargetName(String name) { String catalogName = name == null ? "" : name; if (StringUtils.isNotBlank(catalogName)) { - catalogName = AppUtils.replaceTokens(catalogName, parameterService.getReplacementValues(), true); + catalogName = FormatUtils.replaceTokens(catalogName, parameterService.getReplacementValues(), true); } return catalogName; } diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/DataLoaderContext.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/DataLoaderContext.java index c8fc21b18f..fe06e269be 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/DataLoaderContext.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/DataLoaderContext.java @@ -26,7 +26,7 @@ import org.jumpmind.symmetric.common.logging.ILog; import org.jumpmind.symmetric.common.logging.LogFactory; import org.jumpmind.symmetric.db.BinaryEncoding; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.model.IncomingBatch; import org.jumpmind.symmetric.model.Node; import org.jumpmind.symmetric.model.NodeGroupLink; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IColumnFilter.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IColumnFilter.java index f51841cbbe..da4856ba34 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IColumnFilter.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IColumnFilter.java @@ -20,7 +20,7 @@ package org.jumpmind.symmetric.load; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.ext.IExtensionPoint; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IDataLoaderContext.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IDataLoaderContext.java index fa47831a85..1d4b2ea267 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IDataLoaderContext.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/IDataLoaderContext.java @@ -20,7 +20,7 @@ package org.jumpmind.symmetric.load; import org.jumpmind.symmetric.db.BinaryEncoding; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.ext.ICacheContext; import org.jumpmind.symmetric.model.IncomingBatch; import org.jumpmind.symmetric.model.Node; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/TableTemplate.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/TableTemplate.java index 99d69a6af2..3dd5e35cdf 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/TableTemplate.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/load/TableTemplate.java @@ -29,8 +29,8 @@ import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.util.ArgTypePreparedStatementSetter; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/DataMetaData.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/DataMetaData.java index 73e8be0477..dc4e1618eb 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/DataMetaData.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/DataMetaData.java @@ -20,7 +20,7 @@ package org.jumpmind.symmetric.model; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; /** * diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Trigger.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Trigger.java index d665951f6d..c8f00d974f 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Trigger.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Trigger.java @@ -31,8 +31,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; /** * Defines the trigger via which a table will be synchronized. diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerHistory.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerHistory.java index 2d09e1637c..a5646ab33c 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerHistory.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerHistory.java @@ -24,8 +24,8 @@ import java.io.Serializable; import java.util.Date; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; /** * Maps to the table sync audit table which tracks the history of sync trigger diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerRouter.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerRouter.java index ece2b09321..959920aaa4 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerRouter.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/model/TriggerRouter.java @@ -27,8 +27,8 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; /** * Defines the trigger via which a table will be synchronized. diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/profile/DefaultProfile.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/profile/DefaultProfile.java index ddc4a0751d..e44bf1bba4 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/profile/DefaultProfile.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/profile/DefaultProfile.java @@ -32,7 +32,7 @@ import org.jumpmind.symmetric.ISymmetricEngine; import org.jumpmind.symmetric.common.ParameterConstants; import org.jumpmind.symmetric.config.SymmetricPropertiesFiles; -import org.jumpmind.symmetric.db.SqlScript; +import org.jumpmind.symmetric.db.sql.SqlScript; import org.springframework.core.io.Resource; /** diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/route/DataGapRouteReader.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/route/DataGapRouteReader.java index 9a8de673a3..e39090e8fe 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/route/DataGapRouteReader.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/route/DataGapRouteReader.java @@ -35,6 +35,7 @@ import org.jumpmind.symmetric.service.IDataService; import org.jumpmind.symmetric.service.ISqlProvider; import org.jumpmind.symmetric.util.AppUtils; +import org.jumpmind.symmetric.util.FormatUtils; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.support.JdbcUtils; @@ -89,7 +90,7 @@ protected String qualifyUsingDataGaps(List dataGaps, int numberOfGapsTo gapClause.append("(d.data_id between ? and ?)"); } gapClause.append(")"); - return AppUtils.replace("dataRange", gapClause.toString(), sql); + return FormatUtils.replace("dataRange", gapClause.toString(), sql); } @Override diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/ITriggerRouterService.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/ITriggerRouterService.java index d6f34facab..0350f8580f 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/ITriggerRouterService.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/ITriggerRouterService.java @@ -25,7 +25,7 @@ import java.util.Set; import org.jumpmind.symmetric.config.ITriggerCreationListener; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.ext.IExtraConfigTables; import org.jumpmind.symmetric.model.NodeGroupLink; import org.jumpmind.symmetric.model.Router; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ConfigurationService.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ConfigurationService.java index b217df0556..b0585c0bdd 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ConfigurationService.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ConfigurationService.java @@ -33,10 +33,10 @@ import org.apache.commons.lang.StringUtils; import org.jumpmind.symmetric.common.ParameterConstants; -import org.jumpmind.symmetric.db.SqlScript; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.io.DatabaseIO; -import org.jumpmind.symmetric.db.ddl.model.Database; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.io.DatabaseIO; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.sql.SqlScript; import org.jumpmind.symmetric.model.Channel; import org.jumpmind.symmetric.model.ChannelMap; import org.jumpmind.symmetric.model.Node; @@ -382,8 +382,8 @@ private boolean buildTablesFromDdlUtilXmlIfProvided() { log.info("DatabaseSchemaBuilding", xml); Database database = new DatabaseIO().read(new InputStreamReader(fileUrl .openStream())); - Platform platform = dbDialect.getPlatform(); - platform.createTables(database, false, true); + IDatabasePlatform platform = dbDialect.getPlatform(); + platform.createDatabase(jdbcTemplate.getDataSource(), database, true, true); loaded = true; } catch (Exception e) { log.error(e); diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataExtractorService.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataExtractorService.java index 03034d86da..401721e6bd 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataExtractorService.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataExtractorService.java @@ -47,7 +47,7 @@ import org.jumpmind.symmetric.common.TableConstants; import org.jumpmind.symmetric.common.csv.CsvConstants; import org.jumpmind.symmetric.csv.CsvReader; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.extract.DataExtractorContext; import org.jumpmind.symmetric.extract.IDataExtractor; import org.jumpmind.symmetric.extract.IExtractorFilter; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java index 1967b3125c..31eb16c971 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java @@ -51,7 +51,7 @@ import org.jumpmind.symmetric.csv.CsvWriter; import org.jumpmind.symmetric.db.JdbcBatchPreparedStatementCallback; import org.jumpmind.symmetric.db.SequenceIdentifier; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.ext.IHeartbeatListener; import org.jumpmind.symmetric.load.IReloadListener; import org.jumpmind.symmetric.model.Data; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ParameterService.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ParameterService.java index 7a44895f5b..b94a4430f3 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ParameterService.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ParameterService.java @@ -36,6 +36,7 @@ import org.jumpmind.symmetric.model.DatabaseParameter; import org.jumpmind.symmetric.service.IParameterService; import org.jumpmind.symmetric.util.AppUtils; +import org.jumpmind.symmetric.util.FormatUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -282,10 +283,10 @@ protected String getWithHostName(String paramKey) { String value = getString(paramKey); if (!StringUtils.isBlank(value)) { if (value.contains("hostName")) { - value = AppUtils.replace("hostName", AppUtils.getHostName(), value); + value = FormatUtils.replace("hostName", AppUtils.getHostName(), value); } if (value.contains("ipAddress")) { - value = AppUtils.replace("ipAddress", AppUtils.getIpAddress(), value); + value = FormatUtils.replace("ipAddress", AppUtils.getIpAddress(), value); } } return value; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/RouterService.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/RouterService.java index 3ac3972276..6af22c1b3b 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/RouterService.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/RouterService.java @@ -35,7 +35,7 @@ import org.apache.commons.lang.StringUtils; import org.jumpmind.symmetric.common.Constants; import org.jumpmind.symmetric.common.ParameterConstants; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.model.Data; import org.jumpmind.symmetric.model.DataMetaData; import org.jumpmind.symmetric.model.Node; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/TriggerRouterService.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/TriggerRouterService.java index 1259170ea3..b00377a601 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/TriggerRouterService.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/TriggerRouterService.java @@ -41,7 +41,7 @@ import org.jumpmind.symmetric.config.ITriggerCreationListener; import org.jumpmind.symmetric.config.TriggerFailureListener; import org.jumpmind.symmetric.config.TriggerSelector; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.ext.IExtraConfigTables; import org.jumpmind.symmetric.model.Channel; import org.jumpmind.symmetric.model.DataEventType; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/AdditiveColumnTransform.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/AdditiveColumnTransform.java index 6f3c91d7f8..130bd0624f 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/AdditiveColumnTransform.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/AdditiveColumnTransform.java @@ -5,8 +5,8 @@ import org.apache.commons.lang.StringUtils; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.ext.IBuiltInExtensionPoint; import org.jumpmind.symmetric.ext.ICacheContext; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformDataLoader.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformDataLoader.java index 9a8659fbb9..4915284ff4 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformDataLoader.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformDataLoader.java @@ -25,7 +25,7 @@ import org.apache.commons.lang.ArrayUtils; import org.jumpmind.symmetric.SymmetricException; import org.jumpmind.symmetric.common.ParameterConstants; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.ext.IBuiltInExtensionPoint; import org.jumpmind.symmetric.load.IDataLoaderContext; diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformTable.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformTable.java index 28630b3ee7..9d9d9975ab 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformTable.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/transform/TransformTable.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.model.NodeGroupLink; public class TransformTable { diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/util/AppUtils.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/util/AppUtils.java index e8b1573fac..a0dfb3e595 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/util/AppUtils.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/util/AppUtils.java @@ -30,8 +30,6 @@ import java.util.Iterator; import java.util.Map; import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.sql.DataSource; @@ -64,8 +62,6 @@ public class AppUtils { private static FastDateFormat timezoneFormatter = FastDateFormat.getInstance("Z"); - private static Pattern pattern = Pattern.compile("\\$\\((.+?)\\)"); - /** * Get a unique identifier that represents the JVM instance this server is * currently running in. @@ -113,49 +109,6 @@ public static String getIpAddress() { return ipAddress; } - public static String replace(String prop, String replaceWith, String sourceString) { - return StringUtils.replace(sourceString, "$(" + prop + ")", replaceWith); - } - - public static String replaceTokens(String text, Map replacements, - boolean matchUsingPrefixSuffix) { - if (replacements != null && replacements.size() > 0) { - if (matchUsingPrefixSuffix) { - Matcher matcher = pattern.matcher(text); - StringBuffer buffer = new StringBuffer(); - while (matcher.find()) { - String[] match = matcher.group(1).split("\\|"); - String replacement = replacements.get(match[0]); - if (replacement != null) { - matcher.appendReplacement(buffer, ""); - if (match.length == 2) { - replacement = formatString(match[1], replacement); - } - buffer.append(replacement); - } - } - matcher.appendTail(buffer); - text = buffer.toString(); - } else { - for (Object key : replacements.keySet()) { - text = text.replaceAll(key.toString(), replacements.get(key)); - } - } - } - return text; - - } - - public static String formatString(String format, String arg) { - if (format.indexOf("d") >= 0 || format.indexOf("u") >= 0 || format.indexOf("i") >= 0) { - return String.format(format, Long.parseLong(arg)); - } else if (format.indexOf("e") >= 0 || format.indexOf("f") >= 0) { - return String.format(format, Double.valueOf(arg)); - } else { - return String.format(format, arg); - } - } - /** * This method will return the timezone in RFC822 format.

The format * ("-+HH:MM") has advantages over the older timezone codes ("AAA"). The diff --git a/symmetric/symmetric-core/src/test/java/org/jumpmind/symmetric/route/ConfigurationChangedDataRouterTest.java b/symmetric/symmetric-core/src/test/java/org/jumpmind/symmetric/route/ConfigurationChangedDataRouterTest.java index 23e83d25a8..4ec2e64000 100644 --- a/symmetric/symmetric-core/src/test/java/org/jumpmind/symmetric/route/ConfigurationChangedDataRouterTest.java +++ b/symmetric/symmetric-core/src/test/java/org/jumpmind/symmetric/route/ConfigurationChangedDataRouterTest.java @@ -8,7 +8,7 @@ import junit.framework.Assert; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.model.Data; import org.jumpmind.symmetric.model.DataEventType; import org.jumpmind.symmetric.model.DataMetaData; diff --git a/symmetric/symmetric-db/pom.xml b/symmetric/symmetric-db/pom.xml index 21f4ae2c7a..5943589520 100644 --- a/symmetric/symmetric-db/pom.xml +++ b/symmetric/symmetric-db/pom.xml @@ -64,6 +64,10 @@ commons-logging commons-logging + + commons-io + commons-io + commons-lang commons-lang diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/AbstractDatabasePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/AbstractDatabasePlatform.java new file mode 100644 index 0000000000..1a7843b46b --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/AbstractDatabasePlatform.java @@ -0,0 +1,227 @@ +package org.jumpmind.symmetric.db; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.StringWriter; +import java.sql.Connection; +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.sql.SqlException; +import org.jumpmind.symmetric.db.sql.SqlScript; +import org.jumpmind.symmetric.util.Log; +import org.jumpmind.symmetric.util.LogFactory; + +/* + * Base class for platform implementations. + */ +public abstract class AbstractDatabasePlatform implements IDatabasePlatform { + + /* The default name for models read from the database, if no name as given. */ + protected static final String MODEL_DEFAULT_NAME = "default"; + + /* The log for this platform. */ + protected Log log = LogFactory.getLog(getClass()); + + /* The platform info. */ + protected DatabasePlatformInfo info = new DatabasePlatformInfo(); + + /* The model reader for this platform. */ + protected JdbcModelReader modelReader; + + /* Whether script mode is on. */ + protected boolean scriptModeOn; + + /* Whether SQL comments are generated or not. */ + protected boolean sqlCommentsOn = false; + + /* Whether delimited identifiers are used or not. */ + protected boolean delimitedIdentifierModeOn; + + /* Whether identity override is enabled. */ + protected boolean identityOverrideOn; + + /* Whether read foreign keys shall be sorted alphabetically. */ + protected boolean foreignKeysSorted; + + public AbstractDatabasePlatform() { + } + + public void setLog(Log log) { + this.log = log; + } + + public JdbcModelReader getModelReader() { + return modelReader; + } + + public DatabasePlatformInfo getPlatformInfo() { + return info; + } + + public boolean isScriptModeOn() { + return scriptModeOn; + } + + public void setScriptModeOn(boolean scriptModeOn) { + this.scriptModeOn = scriptModeOn; + } + + public boolean isSqlCommentsOn() { + return sqlCommentsOn; + } + + public void setSqlCommentsOn(boolean sqlCommentsOn) { + if (!getPlatformInfo().isSqlCommentsSupported() && sqlCommentsOn) { + throw new DdlUtilsException("Platform does not support SQL comments"); + } + this.sqlCommentsOn = sqlCommentsOn; + } + + public boolean isDelimitedIdentifierModeOn() { + return delimitedIdentifierModeOn; + } + + public void setDelimitedIdentifierModeOn(boolean delimitedIdentifierModeOn) { + if (!getPlatformInfo().isDelimitedIdentifiersSupported() && delimitedIdentifierModeOn) { + throw new DdlUtilsException("Platform does not support delimited identifier"); + } + this.delimitedIdentifierModeOn = delimitedIdentifierModeOn; + } + + public boolean isIdentityOverrideOn() { + return identityOverrideOn; + } + + public void setIdentityOverrideOn(boolean identityOverrideOn) { + this.identityOverrideOn = identityOverrideOn; + } + + public boolean isForeignKeysSorted() { + return foreignKeysSorted; + } + + public void setForeignKeysSorted(boolean foreignKeysSorted) { + this.foreignKeysSorted = foreignKeysSorted; + } + + public void createDatabase(DataSource dataSource, Database targetDatabase, + boolean dropTablesFirst, boolean continueOnError) { + Database sourceDatabase = new Database(); + Table[] targetTables = targetDatabase.getTables(); + Connection connection = null; + try { + connection = dataSource.getConnection(); + for (Table targetTable : targetTables) { + Table sourceTable = readTableFromDatabase(connection, targetTable.getCatalog(), + targetTable.getSchema(), targetTable.getName()); + if (sourceTable != null) { + sourceDatabase.addTable(sourceTable); + } + } + } catch (SQLException ex) { + throw new SqlException(ex); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + } + } + } + + StringWriter writer = new StringWriter(); + SqlBuilder builder = createSqlBuilder(writer); + + if (builder.isAlterDatabase(sourceDatabase, targetDatabase)) { + String delimiter = info.getSqlCommandDelimiter(); + builder.alterDatabase(sourceDatabase, targetDatabase); + String alterSql = writer.toString(); + if (log.isDebugEnabled()) { + log.debug("TablesAutoUpdatingAlterSql", alterSql); + } + new SqlScript(alterSql, dataSource, !continueOnError, delimiter, null).execute(); + } + } + + public Database readDatabase(Connection connection, String name, String catalog, String schema, + String[] tableTypes) throws DatabaseOperationException { + try { + JdbcModelReader reader = getModelReader(); + Database model = reader.getDatabase(connection, name, catalog, schema, tableTypes); + + postprocessModelFromDatabase(model); + if ((model.getName() == null) || (model.getName().length() == 0)) { + model.setName(MODEL_DEFAULT_NAME); + } + return model; + } catch (SQLException ex) { + throw new DatabaseOperationException(ex); + } + } + + public Table readTableFromDatabase(Connection connection, String catalogName, + String schemaName, String tablename) throws SQLException { + return postprocessTableFromDatabase(modelReader.readTable(connection, catalogName, + schemaName, tablename)); + } + + /* + * Allows the platform to postprocess the model just read from the database. + * + * @param model The model + */ + protected void postprocessModelFromDatabase(Database model) { + // Default values for CHAR/VARCHAR/LONGVARCHAR columns have quotation + // marks + // around them which we'll remove now + for (int tableIdx = 0; tableIdx < model.getTableCount(); tableIdx++) { + postprocessTableFromDatabase(model.getTable(tableIdx)); + } + } + + protected Table postprocessTableFromDatabase(Table table) { + if (table != null) { + for (int columnIdx = 0; columnIdx < table.getColumnCount(); columnIdx++) { + Column column = table.getColumn(columnIdx); + + if (TypeMap.isTextType(column.getTypeCode()) + || TypeMap.isDateTimeType(column.getTypeCode())) { + String defaultValue = column.getDefaultValue(); + + if ((defaultValue != null) && (defaultValue.length() >= 2) + && defaultValue.startsWith("'") && defaultValue.endsWith("'")) { + defaultValue = defaultValue.substring(1, defaultValue.length() - 1); + column.setDefaultValue(defaultValue); + } + } + } + } + return table; + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/DatabaseOperationException.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabaseOperationException.java similarity index 94% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/DatabaseOperationException.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabaseOperationException.java index 80b4c63b4f..4ee7a66d6e 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/DatabaseOperationException.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabaseOperationException.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl; +package org.jumpmind.symmetric.db; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformFactory.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformFactory.java new file mode 100644 index 0000000000..6856783911 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformFactory.java @@ -0,0 +1,266 @@ +package org.jumpmind.symmetric.db; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +import org.jumpmind.symmetric.db.platform.derby.DerbyPlatform; +import org.jumpmind.symmetric.db.platform.firebird.FirebirdPlatform; +import org.jumpmind.symmetric.db.platform.greenplum.GreenplumPlatform; +import org.jumpmind.symmetric.db.platform.h2.H2Platform; +import org.jumpmind.symmetric.db.platform.hsqldb.HsqlDbPlatform; +import org.jumpmind.symmetric.db.platform.hsqldb2.HsqlDb2Platform; +import org.jumpmind.symmetric.db.platform.informix.InformixPlatform; +import org.jumpmind.symmetric.db.platform.interbase.InterbasePlatform; +import org.jumpmind.symmetric.db.platform.mssql.MSSqlPlatform; +import org.jumpmind.symmetric.db.platform.mysql.MySqlPlatform; +import org.jumpmind.symmetric.db.platform.oracle.OraclePlatform; +import org.jumpmind.symmetric.db.platform.postgresql.PostgreSqlPlatform; +import org.jumpmind.symmetric.db.platform.sqlite.SqLitePlatform; +import org.jumpmind.symmetric.db.platform.sybase.SybasePlatform; + +/* + * A factory of {@link IDatabasePlatform} instances based on a case + * insensitive database name. Note that this is a convenience class as the platforms + * can also simply be created via their constructors. + */ +public class DatabasePlatformFactory { + + /* The database name -> platform map. */ + private static Map> platforms = null; + + /* + * Returns the platform map. + * + * @return The platform list + */ + private static synchronized Map> getPlatforms() { + if (platforms == null) { + // lazy initialization + platforms = new HashMap>(); + registerPlatforms(); + } + return platforms; + } + + /* + * Creates a new platform for the given (case insensitive) database name or + * returns null if the database is not recognized. + * + * @param databaseName The name of the database (case is not important) + * + * @return The platform or null if the database is not + * supported + */ + public static synchronized IDatabasePlatform createNewPlatformInstance(String databaseName) + throws DdlUtilsException { + Class platformClass = getPlatforms().get( + databaseName.toLowerCase()); + + try { + return platformClass != null ? (IDatabasePlatform) platformClass.newInstance() : null; + } catch (Exception ex) { + throw new DdlUtilsException("Could not create platform for database " + databaseName, + ex); + } + } + + /* + * Creates a new platform for the specified database. This is a shortcut + * method that uses {@link PlatformUtils#determineDatabaseType(DataSource)} + * to determine the parameter for {@link + * #createNewPlatformInstance(String)}. Note that this method sets the data + * source at the returned platform instance (method {@link + * Platform#setDataSource(DataSource)}). + * + * @param dataSource The data source for the database + * + * @return The platform or null if the database is not + * supported + */ + public static synchronized IDatabasePlatform createNewPlatformInstance(DataSource dataSource) + throws DdlUtilsException { + // connects to the database and uses actual metadata info to get db name + // and version to determine platform + String nameVersion = determineDatabaseNameVersion(dataSource); + return createNewPlatformInstance(nameVersion); + } + + public static String determineDatabaseNameVersion(DataSource dataSource) + throws DatabaseOperationException { + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData metaData = connection.getMetaData(); + String productName = metaData.getDatabaseProductName(); + int majorVersion = metaData.getDatabaseMajorVersion(); + /* + * if the productName is PostgreSQL, it could be either PostgreSQL + * or Greenplum + */ + /* query the metadata to determine which one it is */ + if (productName.equalsIgnoreCase(PostgreSqlPlatform.DATABASENAME)) { + if (isGreenplumDatabase(connection)) { + productName = GreenplumPlatform.DATABASE; + majorVersion = getGreenplumVersion(connection); + } + } + String productString = productName; + if (majorVersion > 0) { + productString += majorVersion; + } + + return productString; + } catch (SQLException ex) { + throw new DatabaseOperationException("Error while reading the database metadata: " + + ex.getMessage(), ex); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (SQLException ex) { + // we ignore this one + } + } + } + } + + private static boolean isGreenplumDatabase(Connection connection) { + Statement stmt = null; + ResultSet rs = null; + String productName = null; + boolean isGreenplum = false; + try { + stmt = connection.createStatement(); + rs = stmt.executeQuery(GreenplumPlatform.SQL_GET_GREENPLUM_NAME); + while (rs.next()) { + productName = rs.getString(1); + } + if (productName != null && productName.equalsIgnoreCase(GreenplumPlatform.DATABASE)) { + isGreenplum = true; + } + } catch (SQLException ex) { + // ignore the exception, if it is caught, then this is most likely + // not + // a greenplum database + } finally { + try { + if (rs != null) { + rs.close(); + } + if (stmt != null) { + stmt.close(); + } + } catch (SQLException ex) { + } + } + return isGreenplum; + } + + private static int getGreenplumVersion(Connection connection) { + Statement stmt = null; + ResultSet rs = null; + String versionName = null; + int productVersion = 0; + try { + stmt = connection.createStatement(); + rs = stmt.executeQuery(GreenplumPlatform.SQL_GET_GREENPLUM_VERSION); + while (rs.next()) { + versionName = rs.getString(1); + } + // take up to the first "." for version number + if (versionName.indexOf('.') != -1) { + versionName = versionName.substring(0, versionName.indexOf('.')); + } + try { + productVersion = Integer.parseInt(versionName); + } catch (NumberFormatException ex) { + // if we can't convert this to a version number, leave it 0 + } + } catch (SQLException ex) { + // ignore the exception, if it is caught, then this is most likely + // not + // a greenplum database + } finally { + try { + rs.close(); + stmt.close(); + } catch (SQLException ex) { + } + } + return productVersion; + } + + /* + * Registers a new platform. + * + * @param platformName The platform name + * + * @param platformClass The platform class which must implement the {@link + * Platform} interface + */ + public static synchronized void registerPlatform(String platformName, + Class platformClass) { + addPlatform(getPlatforms(), platformName, platformClass); + } + + /* + * Registers the known platforms. + */ + private static void registerPlatforms() { + for (String name : H2Platform.DATABASENAMES) { + addPlatform(platforms, name, H2Platform.class); + } + addPlatform(platforms, SqLitePlatform.DATABASENAME, SqLitePlatform.class); + addPlatform(platforms, InformixPlatform.DATABASENAME, InformixPlatform.class); + addPlatform(platforms, DerbyPlatform.DATABASENAME, DerbyPlatform.class); + addPlatform(platforms, FirebirdPlatform.DATABASENAME, FirebirdPlatform.class); + addPlatform(platforms, GreenplumPlatform.DATABASENAME, GreenplumPlatform.class); + addPlatform(platforms, HsqlDbPlatform.DATABASENAME, HsqlDbPlatform.class); + addPlatform(platforms, HsqlDb2Platform.DATABASENAME, HsqlDb2Platform.class); + addPlatform(platforms, InterbasePlatform.DATABASENAME, InterbasePlatform.class); + addPlatform(platforms, MSSqlPlatform.DATABASENAME, MSSqlPlatform.class); + addPlatform(platforms, MySqlPlatform.DATABASENAME, MySqlPlatform.class); + addPlatform(platforms, OraclePlatform.DATABASENAME, OraclePlatform.class); + addPlatform(platforms, PostgreSqlPlatform.DATABASENAME, PostgreSqlPlatform.class); + addPlatform(platforms, SybasePlatform.DATABASENAME, SybasePlatform.class); + } + + private static synchronized void addPlatform( + Map> platformMap, String platformName, + Class platformClass) { + if (!IDatabasePlatform.class.isAssignableFrom(platformClass)) { + throw new IllegalArgumentException("Cannot register class " + platformClass.getName() + + " because it does not implement the " + IDatabasePlatform.class.getName() + + " interface"); + } + platformMap.put(platformName.toLowerCase(), platformClass); + + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformInfo.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformInfo.java similarity index 96% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformInfo.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformInfo.java index 64c804fd87..184c4ac829 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformInfo.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformInfo.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl; +package org.jumpmind.symmetric.db; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -32,10 +32,10 @@ /* * Contains information about the database platform such as supported features and native type mappings. */ -public class PlatformInfo +public class DatabasePlatformInfo { /* The Log to which logging calls will be made. */ - private final Log log = LogFactory.getLog(PlatformInfo.class); + private final Log log = LogFactory.getLog(DatabasePlatformInfo.class); // properties influencing the definition of columns @@ -158,7 +158,7 @@ public class PlatformInfo /* * Creates a new platform info object. */ - public PlatformInfo() + public DatabasePlatformInfo() { this.typesWithNullDefault.add(new Integer(Types.CHAR)); this.typesWithNullDefault.add(new Integer(Types.VARCHAR)); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformUtils.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformUtils.java new file mode 100644 index 0000000000..1aec3aa5c6 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DatabasePlatformUtils.java @@ -0,0 +1,320 @@ +package org.jumpmind.symmetric.db; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.HashMap; + +import javax.sql.DataSource; + +import org.jumpmind.symmetric.db.platform.db2.Db2Platform; +import org.jumpmind.symmetric.db.platform.derby.DerbyPlatform; +import org.jumpmind.symmetric.db.platform.firebird.FirebirdPlatform; +import org.jumpmind.symmetric.db.platform.hsqldb.HsqlDbPlatform; +import org.jumpmind.symmetric.db.platform.interbase.InterbasePlatform; +import org.jumpmind.symmetric.db.platform.mssql.MSSqlPlatform; +import org.jumpmind.symmetric.db.platform.mysql.MySqlPlatform; +import org.jumpmind.symmetric.db.platform.oracle.OraclePlatform; +import org.jumpmind.symmetric.db.platform.postgresql.PostgreSqlPlatform; +import org.jumpmind.symmetric.db.platform.sybase.SybasePlatform; + +/* + * Utility functions for dealing with database platforms. + */ +public class DatabasePlatformUtils { + private DatabasePlatformUtils() { + } + + // Extended drivers that support more than one database + + /* The DataDirect Connect DB2 jdbc driver. */ + public static final String JDBC_DRIVER_DATADIRECT_DB2 = "com.ddtek.jdbc.db2.DB2Driver"; + /* The DataDirect Connect SQLServer jdbc driver. */ + public static final String JDBC_DRIVER_DATADIRECT_SQLSERVER = "com.ddtek.jdbc.sqlserver.SQLServerDriver"; + /* The DataDirect Connect Oracle jdbc driver. */ + public static final String JDBC_DRIVER_DATADIRECT_ORACLE = "com.ddtek.jdbc.oracle.OracleDriver"; + /* The DataDirect Connect Sybase jdbc driver. */ + public static final String JDBC_DRIVER_DATADIRECT_SYBASE = "com.ddtek.jdbc.sybase.SybaseDriver"; + /* The i-net DB2 jdbc driver. */ + public static final String JDBC_DRIVER_INET_DB2 = "com.inet.drda.DRDADriver"; + /* The i-net Oracle jdbc driver. */ + public static final String JDBC_DRIVER_INET_ORACLE = "com.inet.ora.OraDriver"; + /* The i-net SQLServer jdbc driver. */ + public static final String JDBC_DRIVER_INET_SQLSERVER = "com.inet.tds.TdsDriver"; + /* The i-net Sybase jdbc driver. */ + public static final String JDBC_DRIVER_INET_SYBASE = "com.inet.syb.SybDriver"; + /* The i-net pooled jdbc driver for SQLServer and Sybase. */ + public static final String JDBC_DRIVER_INET_POOLED = "com.inet.pool.PoolDriver"; + /* The JNetDirect SQLServer jdbc driver. */ + public static final String JDBC_DRIVER_JSQLCONNECT_SQLSERVER = "com.jnetdirect.jsql.JSQLDriver"; + /* The jTDS jdbc driver for SQLServer and Sybase. */ + public static final String JDBC_DRIVER_JTDS = "net.sourceforge.jtds.jdbc.Driver"; + + /* The subprotocol used by the DataDirect DB2 driver. */ + public static final String JDBC_SUBPROTOCOL_DATADIRECT_DB2 = "datadirect:db2"; + /* The subprotocol used by the DataDirect SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_DATADIRECT_SQLSERVER = "datadirect:sqlserver"; + /* The subprotocol used by the DataDirect Oracle driver. */ + public static final String JDBC_SUBPROTOCOL_DATADIRECT_ORACLE = "datadirect:oracle"; + /* The subprotocol used by the DataDirect Sybase driver. */ + public static final String JDBC_SUBPROTOCOL_DATADIRECT_SYBASE = "datadirect:sybase"; + /* The subprotocol used by the i-net DB2 driver. */ + public static final String JDBC_SUBPROTOCOL_INET_DB2 = "inetdb2"; + /* The subprotocol used by the i-net Oracle driver. */ + public static final String JDBC_SUBPROTOCOL_INET_ORACLE = "inetora"; + /* A subprotocol used by the i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER = "inetdae"; + /* A subprotocol used by the i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER6 = "inetdae6"; + /* A subprotocol used by the i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7 = "inetdae7"; + /* A subprotocol used by the i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7A = "inetdae7a"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_1 = "inetpool:inetdae"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_1 = "inetpool:inetdae6"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_1 = "inetpool:inetdae7"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_1 = "inetpool:inetdae7a"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_2 = "inetpool:jdbc:inetdae"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_2 = "inetpool:jdbc:inetdae6"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_2 = "inetpool:jdbc:inetdae7"; + /* A subprotocol used by the pooled i-net SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_2 = "inetpool:jdbc:inetdae7a"; + /* The subprotocol used by the i-net Sybase driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SYBASE = "inetsyb"; + /* The subprotocol used by the pooled i-net Sybase driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_1 = "inetpool:inetsyb"; + /* The subprotocol used by the pooled i-net Sybase driver. */ + public static final String JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_2 = "inetpool:jdbc:inetsyb"; + /* The subprotocol used by the JNetDirect SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_JSQLCONNECT_SQLSERVER = "JSQLConnect"; + /* The subprotocol used by the jTDS SQLServer driver. */ + public static final String JDBC_SUBPROTOCOL_JTDS_SQLSERVER = "jtds:sqlserver"; + /* The subprotocol used by the jTDS Sybase driver. */ + public static final String JDBC_SUBPROTOCOL_JTDS_SYBASE = "jtds:sybase"; + + /* + * Maps the sub-protocl part of a jdbc connection url to a OJB platform + * name. + */ + private static HashMap jdbcSubProtocolToPlatform = new HashMap(); + + /* Maps the jdbc driver name to a OJB platform name. */ + private static HashMap jdbcDriverToPlatform = new HashMap(); + + /* + * Creates a new instance. + */ + static { + // Note that currently Sapdb and MaxDB have equal subprotocols and + // drivers so we have no means to distinguish them + jdbcSubProtocolToPlatform.put(Db2Platform.JDBC_SUBPROTOCOL, Db2Platform.DATABASENAME); + jdbcSubProtocolToPlatform.put(Db2Platform.JDBC_SUBPROTOCOL_OS390_1, + Db2Platform.DATABASENAME); + jdbcSubProtocolToPlatform.put(Db2Platform.JDBC_SUBPROTOCOL_OS390_2, + Db2Platform.DATABASENAME); + jdbcSubProtocolToPlatform + .put(Db2Platform.JDBC_SUBPROTOCOL_JTOPEN, Db2Platform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_DB2, + Db2Platform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_DB2, + Db2Platform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DerbyPlatform.JDBC_SUBPROTOCOL, DerbyPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(FirebirdPlatform.JDBC_SUBPROTOCOL, + FirebirdPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(HsqlDbPlatform.JDBC_SUBPROTOCOL, HsqlDbPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(InterbasePlatform.JDBC_SUBPROTOCOL, + InterbasePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(MSSqlPlatform.JDBC_SUBPROTOCOL, MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(MSSqlPlatform.JDBC_SUBPROTOCOL_NEW, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(MSSqlPlatform.JDBC_SUBPROTOCOL_INTERNAL, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_SQLSERVER, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER6, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7A, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_1, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_1, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_1, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_1, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_2, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_2, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_2, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put( + DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_2, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_JSQLCONNECT_SQLSERVER, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_JTDS_SQLSERVER, + MSSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(MySqlPlatform.JDBC_SUBPROTOCOL, MySqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(OraclePlatform.JDBC_SUBPROTOCOL_THIN, + OraclePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(OraclePlatform.JDBC_SUBPROTOCOL_OCI8, + OraclePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(OraclePlatform.JDBC_SUBPROTOCOL_THIN_OLD, + OraclePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_ORACLE, + OraclePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_ORACLE, + OraclePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(PostgreSqlPlatform.JDBC_SUBPROTOCOL, + PostgreSqlPlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(SybasePlatform.JDBC_SUBPROTOCOL, SybasePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_SYBASE, + SybasePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SYBASE, + SybasePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_1, + SybasePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_2, + SybasePlatform.DATABASENAME); + jdbcSubProtocolToPlatform.put(DatabasePlatformUtils.JDBC_SUBPROTOCOL_JTDS_SYBASE, + SybasePlatform.DATABASENAME); + + jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER, Db2Platform.DATABASENAME); + jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER_OLD1, Db2Platform.DATABASENAME); + jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER_OLD2, Db2Platform.DATABASENAME); + jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER_JTOPEN, Db2Platform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_DATADIRECT_DB2, + Db2Platform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_INET_DB2, + Db2Platform.DATABASENAME); + jdbcDriverToPlatform.put(DerbyPlatform.JDBC_DRIVER_EMBEDDED, DerbyPlatform.DATABASENAME); + jdbcDriverToPlatform.put(DerbyPlatform.JDBC_DRIVER, DerbyPlatform.DATABASENAME); + jdbcDriverToPlatform.put(FirebirdPlatform.JDBC_DRIVER, FirebirdPlatform.DATABASENAME); + jdbcDriverToPlatform.put(HsqlDbPlatform.JDBC_DRIVER, HsqlDbPlatform.DATABASENAME); + jdbcDriverToPlatform.put(InterbasePlatform.JDBC_DRIVER, InterbasePlatform.DATABASENAME); + jdbcDriverToPlatform.put(MSSqlPlatform.JDBC_DRIVER, MSSqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(MSSqlPlatform.JDBC_DRIVER_NEW, MSSqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_DATADIRECT_SQLSERVER, + MSSqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_INET_SQLSERVER, + MSSqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_JSQLCONNECT_SQLSERVER, + MSSqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(MySqlPlatform.JDBC_DRIVER, MySqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(MySqlPlatform.JDBC_DRIVER_OLD, MySqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(OraclePlatform.JDBC_DRIVER, OraclePlatform.DATABASENAME); + jdbcDriverToPlatform.put(OraclePlatform.JDBC_DRIVER_OLD, OraclePlatform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_DATADIRECT_ORACLE, + OraclePlatform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_INET_ORACLE, + OraclePlatform.DATABASENAME); + jdbcDriverToPlatform.put(PostgreSqlPlatform.JDBC_DRIVER, PostgreSqlPlatform.DATABASENAME); + jdbcDriverToPlatform.put(SybasePlatform.JDBC_DRIVER, SybasePlatform.DATABASENAME); + jdbcDriverToPlatform.put(SybasePlatform.JDBC_DRIVER_OLD, SybasePlatform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_DATADIRECT_SYBASE, + SybasePlatform.DATABASENAME); + jdbcDriverToPlatform.put(DatabasePlatformUtils.JDBC_DRIVER_INET_SYBASE, + SybasePlatform.DATABASENAME); + } + + public static String getDatabaseProductVersion(DataSource dataSource) { + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData metaData = connection.getMetaData(); + return metaData.getDatabaseProductVersion(); + } catch (SQLException ex) { + throw new DatabaseOperationException("Error while reading the database metadata: " + + ex.getMessage(), ex); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (SQLException ex) { + // we ignore this one + } + } + } + } + + public static int getDatabaseMajorVersion(DataSource dataSource) { + Connection connection = null; + try { + connection = dataSource.getConnection(); + DatabaseMetaData metaData = connection.getMetaData(); + return metaData.getDatabaseMajorVersion(); + } catch (SQLException ex) { + throw new DatabaseOperationException("Error while reading the database metadata: " + + ex.getMessage(), ex); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (SQLException ex) { + // we ignore this one + } + } + } + } + + public static int getDatabaseMinorVersion(DataSource dataSource) { + Connection connection = null; + try { + connection = dataSource.getConnection(); + DatabaseMetaData metaData = connection.getMetaData(); + return metaData.getDatabaseMinorVersion(); + } catch (SQLException ex) { + throw new DatabaseOperationException("Error while reading the database metadata: " + + ex.getMessage(), ex); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (SQLException ex) { + // we ignore this one + } + } + } + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/DdlUtilsException.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DdlUtilsException.java similarity index 86% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/DdlUtilsException.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DdlUtilsException.java index c8a15b6b18..ed90bbcccd 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/DdlUtilsException.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/DdlUtilsException.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl; +package org.jumpmind.symmetric.db; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,14 +19,11 @@ * under the License. */ -import org.apache.commons.lang.exception.NestableRuntimeException; /** * Base class for DdlUtils exceptions. - * - * @version $Revision: 289996 $ */ -public class DdlUtilsException extends NestableRuntimeException +public class DdlUtilsException extends RuntimeException { /** Constant for serializing instances of this class. */ private static final long serialVersionUID = 5624776387174310551L; diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/IDatabasePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/IDatabasePlatform.java new file mode 100644 index 0000000000..1c7ac539a2 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/IDatabasePlatform.java @@ -0,0 +1,184 @@ +package org.jumpmind.symmetric.db; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ +import java.io.Writer; +import java.sql.Connection; +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * A platform encapsulates the database-related functionality such as performing queries + * and manipulations. It also contains an sql builder that is specific to this platform. + */ +public interface IDatabasePlatform { + + public String getName(); + + /* + * Returns the info object for this platform. + * + * @return The info object + */ + public DatabasePlatformInfo getPlatformInfo(); + + /* + * Returns a new sql builder for the this platform. + * + * @return The sql builder + */ + public SqlBuilder createSqlBuilder(Writer writer); + + /* + * Returns the model reader (which reads a database model from a live + * database) for this platform. + * + * @return The model reader + */ + public JdbcModelReader getModelReader(); + + /* + * Determines whether script mode is on. This means that the generated SQL + * is not intended to be sent directly to the database but rather to be + * saved in a SQL script file. Per default, script mode is off. + * + * @return true if script mode is on + */ + public boolean isScriptModeOn(); + + /* + * Specifies whether script mode is on. This means that the generated SQL is + * not intended to be sent directly to the database but rather to be saved + * in a SQL script file. + * + * @param scriptModeOn true if script mode is on + */ + public void setScriptModeOn(boolean scriptModeOn); + + /* + * Determines whether delimited identifiers are used or normal SQL92 + * identifiers (which may only contain alphanumerical characters and the + * underscore, must start with a letter and cannot be a reserved keyword). + * Per default, delimited identifiers are not used + * + * @return true if delimited identifiers are used + */ + public boolean isDelimitedIdentifierModeOn(); + + /* + * Specifies whether delimited identifiers are used or normal SQL92 + * identifiers. + * + * @param delimitedIdentifierModeOn true if delimited + * identifiers shall be used + */ + public void setDelimitedIdentifierModeOn(boolean delimitedIdentifierModeOn); + + /* + * Determines whether SQL comments are generated. + * + * @return true if SQL comments shall be generated + */ + public boolean isSqlCommentsOn(); + + /* + * Specifies whether SQL comments shall be generated. + * + * @param sqlCommentsOn true if SQL comments shall be generated + */ + public void setSqlCommentsOn(boolean sqlCommentsOn); + + /* + * Determines whether SQL insert statements can specify values for identity + * columns. This setting is only relevant if the database supports it + * ({@link PlatformInfo#isIdentityOverrideAllowed()}). If this is off, then + * the insert methods will ignore values for identity columns. + * + * @return true if identity override is enabled (the default) + */ + public boolean isIdentityOverrideOn(); + + /* + * Specifies whether SQL insert statements can specify values for identity + * columns. This setting is only relevant if the database supports it + * ({@link PlatformInfo#isIdentityOverrideAllowed()}). If this is off, then + * the insert methods will ignore values for identity columns. + * + * @param identityOverrideOn true if identity override is + * enabled (the default) + */ + public void setIdentityOverrideOn(boolean identityOverrideOn); + + /* + * Determines whether foreign keys of a table read from a live database are + * alphabetically sorted. + * + * @return true if read foreign keys are sorted + */ + public boolean isForeignKeysSorted(); + + /* + * Specifies whether foreign keys read from a live database, shall be + * alphabetically sorted. + * + * @param foreignKeysSorted true if read foreign keys shall be + * sorted + */ + public void setForeignKeysSorted(boolean foreignKeysSorted); + + /* + * Reads the database model from the live database to which the given + * connection is pointing. + * + * @param connection The connection to the database + * + * @param name The name of the resulting database; null when + * the default name (the catalog) is desired which might be + * null itself though + * + * @param catalog The catalog to access in the database; use + * null for the default value + * + * @param schema The schema to access in the database; use null + * for the default value + * + * @param tableTypes The table types to process; use null or an + * empty list for the default ones + * + * @return The database model + * + * @throws DatabaseOperationException If an error occurred during reading + * the model + */ + public Database readDatabase(Connection connection, String name, String catalog, + String schema, String[] tableTypes) throws DatabaseOperationException; + + public Table readTableFromDatabase(Connection connection, String catalogName, + String schemaName, String tablename) throws SQLException; + + public void createDatabase(DataSource dataSource, Database targetDatabase, + boolean dropTablesFirst, boolean continueOnError); + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddColumnChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddColumnChange.java similarity index 90% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddColumnChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddColumnChange.java index 6881378790..116a113fc0 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddColumnChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddColumnChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,10 +19,10 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the addition of a column to a table. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddForeignKeyChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddForeignKeyChange.java similarity index 86% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddForeignKeyChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddForeignKeyChange.java index eddbb8a7f2..8c21cfca8c 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddForeignKeyChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddForeignKeyChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,10 +19,10 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the addition of a foreign key to a table. Note that for diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddIndexChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddIndexChange.java similarity index 84% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddIndexChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddIndexChange.java index 0ea1c881e8..83caafc96e 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddIndexChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddIndexChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,10 +19,10 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the addition of an index to a table. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddPrimaryKeyChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddPrimaryKeyChange.java similarity index 88% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddPrimaryKeyChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddPrimaryKeyChange.java index f87a0aca35..6520e30eeb 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddPrimaryKeyChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddPrimaryKeyChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the addition of a primary key to a table which does not have one. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddTableChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddTableChange.java similarity index 83% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddTableChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddTableChange.java index a7db92aca6..b340f2d46b 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/AddTableChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/AddTableChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,17 +19,15 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the addition of a table to a model. Note that this change does not include foreign keys * originating from the new table. - * - * @version $Revision: $ */ -public class AddTableChange implements ModelChange +public class AddTableChange implements IModelChange { /** The new table. */ private Table _newTable; diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnAutoIncrementChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnAutoIncrementChange.java similarity index 87% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnAutoIncrementChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnAutoIncrementChange.java index bf7af822a6..b42b30eb47 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnAutoIncrementChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnAutoIncrementChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the change of the auto-increment constraint of a column. Since it is a boolean value, diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnChange.java similarity index 88% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnChange.java index 84aad73610..2767eaad83 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,7 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; +import org.jumpmind.symmetric.db.model.Column; /** * Represents a change to a column of a table. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnDataTypeChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnDataTypeChange.java similarity index 88% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnDataTypeChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnDataTypeChange.java index 3c86937929..2f25801f34 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnDataTypeChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnDataTypeChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the change of the data type of a column. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnDefaultValueChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnDefaultValueChange.java similarity index 88% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnDefaultValueChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnDefaultValueChange.java index 7c640c4c78..772509df28 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnDefaultValueChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnDefaultValueChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the change of the default value of a column. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnRequiredChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnRequiredChange.java similarity index 87% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnRequiredChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnRequiredChange.java index 09d8fe699e..b360c310cd 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnRequiredChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnRequiredChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the change of the required constraint of a column. Since it is a boolean value, diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnSizeChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnSizeChange.java similarity index 88% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnSizeChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnSizeChange.java index 041d2d7a2c..0e9bdefc9c 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ColumnSizeChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ColumnSizeChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the change of the size or scale of a column. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ModelChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/IModelChange.java similarity index 84% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ModelChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/IModelChange.java index 11c5f3b3bf..c329bab048 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ModelChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/IModelChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,14 +19,12 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Database; +import org.jumpmind.symmetric.db.model.Database; /** * Marker interface for changes to a database model element. - * - * @version $Revision: $ */ -public interface ModelChange +public interface IModelChange { /** * Applies this change to the given database. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ModelComparator.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ModelComparator.java similarity index 52% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ModelComparator.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ModelComparator.java index cbddf49cdb..125a14387f 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/ModelComparator.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/ModelComparator.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -26,99 +26,96 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.DatabasePlatformInfo; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; /** * Compares two database models and creates change objects that express how to - * adapt the first model so that it becomes the second one. Neither of the models - * are changed in the process, however, it is also assumed that the models do not - * change in between. + * adapt the first model so that it becomes the second one. Neither of the + * models are changed in the process, however, it is also assumed that the + * models do not change in between. * - * TODO: Add support and tests for the change of the column order + * TODO: Add support and tests for the change of the column order */ -public class ModelComparator -{ +public class ModelComparator { /** The log for this comparator. */ private final Log _log = LogFactory.getLog(ModelComparator.class); /** The platform information. */ - private PlatformInfo _platformInfo; + private DatabasePlatformInfo _platformInfo; /** Whether comparison is case sensitive. */ private boolean _caseSensitive; /** * Creates a new model comparator object. * - * @param platformInfo The platform info - * @param caseSensitive Whether comparison is case sensitive + * @param platformInfo + * The platform info + * @param caseSensitive + * Whether comparison is case sensitive */ - public ModelComparator(PlatformInfo platformInfo, boolean caseSensitive) - { - _platformInfo = platformInfo; + public ModelComparator(DatabasePlatformInfo platformInfo, boolean caseSensitive) { + _platformInfo = platformInfo; _caseSensitive = caseSensitive; } /** - * Compares the two models and returns the changes necessary to create the second - * model from the first one. - * - * @param sourceModel The source model - * @param targetModel The target model + * Compares the two models and returns the changes necessary to create the + * second model from the first one. + * + * @param sourceModel + * The source model + * @param targetModel + * The target model * @return The changes */ - public List compare(Database sourceModel, Database targetModel) - { - ArrayList changes = new ArrayList(); + public List compare(Database sourceModel, Database targetModel) { + ArrayList changes = new ArrayList(); - for (int tableIdx = 0; tableIdx < targetModel.getTableCount(); tableIdx++) - { + for (int tableIdx = 0; tableIdx < targetModel.getTableCount(); tableIdx++) { Table targetTable = targetModel.getTable(tableIdx); Table sourceTable = sourceModel.findTable(targetTable.getName(), _caseSensitive); - if (sourceTable == null) - { - if (_log.isDebugEnabled()) - { + if (sourceTable == null) { + if (_log.isDebugEnabled()) { _log.debug("Table " + targetTable.getName() + " needs to be added"); } changes.add(new AddTableChange(targetTable)); - for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++) - { + for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++) { // we have to use target table's definition here because the // complete table is new - changes.add(new AddForeignKeyChange(targetTable, targetTable.getForeignKey(fkIdx))); + changes.add(new AddForeignKeyChange(targetTable, targetTable + .getForeignKey(fkIdx))); } - } - else - { + } else { changes.addAll(compareTables(sourceModel, sourceTable, targetModel, targetTable)); } } - for (int tableIdx = 0; tableIdx < sourceModel.getTableCount(); tableIdx++) - { + for (int tableIdx = 0; tableIdx < sourceModel.getTableCount(); tableIdx++) { Table sourceTable = sourceModel.getTable(tableIdx); Table targetTable = targetModel.findTable(sourceTable.getName(), _caseSensitive); - if ((targetTable == null) && (sourceTable.getName() != null) && (sourceTable.getName().length() > 0)) - { - if (_log.isDebugEnabled()) - { + if ((targetTable == null) && (sourceTable.getName() != null) + && (sourceTable.getName().length() > 0)) { + if (_log.isDebugEnabled()) { _log.debug("Table " + sourceTable.getName() + " needs to be removed"); } changes.add(new RemoveTableChange(sourceTable)); - // we assume that the target model is sound, ie. that there are no longer any foreign - // keys to this table in the target model; thus we already have removeFK changes for - // these from the compareTables method and we only need to create changes for the fks + // we assume that the target model is sound, ie. that there are + // no longer any foreign + // keys to this table in the target model; thus we already have + // removeFK changes for + // these from the compareTables method and we only need to + // create changes for the fks // originating from this table - for (int fkIdx = 0; fkIdx < sourceTable.getForeignKeyCount(); fkIdx++) - { - changes.add(new RemoveForeignKeyChange(sourceTable, sourceTable.getForeignKey(fkIdx))); + for (int fkIdx = 0; fkIdx < sourceTable.getForeignKeyCount(); fkIdx++) { + changes.add(new RemoveForeignKeyChange(sourceTable, sourceTable + .getForeignKey(fkIdx))); } } } @@ -126,78 +123,72 @@ public List compare(Database sourceModel, Database targetModel) } /** - * Compares the two tables and returns the changes necessary to create the second - * table from the first one. - * - * @param sourceModel The source model which contains the source table - * @param sourceTable The source table - * @param targetModel The target model which contains the target table - * @param targetTable The target table + * Compares the two tables and returns the changes necessary to create the + * second table from the first one. + * + * @param sourceModel + * The source model which contains the source table + * @param sourceTable + * The source table + * @param targetModel + * The target model which contains the target table + * @param targetTable + * The target table * @return The changes */ - public List compareTables(Database sourceModel, - Table sourceTable, - Database targetModel, - Table targetTable) - { - ArrayList changes = new ArrayList(); + public List compareTables(Database sourceModel, Table sourceTable, + Database targetModel, Table targetTable) { + ArrayList changes = new ArrayList(); - for (int fkIdx = 0; fkIdx < sourceTable.getForeignKeyCount(); fkIdx++) - { + for (int fkIdx = 0; fkIdx < sourceTable.getForeignKeyCount(); fkIdx++) { ForeignKey sourceFk = sourceTable.getForeignKey(fkIdx); ForeignKey targetFk = findCorrespondingForeignKey(targetTable, sourceFk); - if (targetFk == null) - { - if (_log.isDebugEnabled()) - { - _log.debug("Foreign key " + sourceFk + " needs to be removed from table " + sourceTable.getName()); + if (targetFk == null) { + if (_log.isDebugEnabled()) { + _log.debug("Foreign key " + sourceFk + " needs to be removed from table " + + sourceTable.getName()); } changes.add(new RemoveForeignKeyChange(sourceTable, sourceFk)); } } - for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++) - { + for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++) { ForeignKey targetFk = targetTable.getForeignKey(fkIdx); ForeignKey sourceFk = findCorrespondingForeignKey(sourceTable, targetFk); - if (sourceFk == null) - { - if (_log.isDebugEnabled()) - { - _log.debug("Foreign key " + targetFk + " needs to be created for table " + sourceTable.getName()); + if (sourceFk == null) { + if (_log.isDebugEnabled()) { + _log.debug("Foreign key " + targetFk + " needs to be created for table " + + sourceTable.getName()); } - // we have to use the target table here because the foreign key might + // we have to use the target table here because the foreign key + // might // reference a new column changes.add(new AddForeignKeyChange(targetTable, targetFk)); } } - for (int indexIdx = 0; indexIdx < sourceTable.getIndexCount(); indexIdx++) - { + for (int indexIdx = 0; indexIdx < sourceTable.getIndexCount(); indexIdx++) { Index sourceIndex = sourceTable.getIndex(indexIdx); Index targetIndex = findCorrespondingIndex(targetTable, sourceIndex); - if (targetIndex == null) - { - if (_log.isDebugEnabled()) - { - _log.debug("Index " + sourceIndex.getName() + " needs to be removed from table " + sourceTable.getName()); + if (targetIndex == null) { + if (_log.isDebugEnabled()) { + _log.debug("Index " + sourceIndex.getName() + + " needs to be removed from table " + sourceTable.getName()); } changes.add(new RemoveIndexChange(sourceTable, sourceIndex)); } } - for (int indexIdx = 0; indexIdx < targetTable.getIndexCount(); indexIdx++) - { + for (int indexIdx = 0; indexIdx < targetTable.getIndexCount(); indexIdx++) { Index targetIndex = targetTable.getIndex(indexIdx); Index sourceIndex = findCorrespondingIndex(sourceTable, targetIndex); - if (sourceIndex == null) - { - if (_log.isDebugEnabled()) - { - _log.debug("Index " + targetIndex.getName() + " needs to be created for table " + sourceTable.getName()); + if (sourceIndex == null) { + if (_log.isDebugEnabled()) { + _log.debug("Index " + targetIndex.getName() + " needs to be created for table " + + sourceTable.getName()); } // we have to use the target table here because the index might // reference a new column @@ -207,44 +198,38 @@ public List compareTables(Database sourceModel, HashMap addColumnChanges = new HashMap(); - for (int columnIdx = 0; columnIdx < targetTable.getColumnCount(); columnIdx++) - { + for (int columnIdx = 0; columnIdx < targetTable.getColumnCount(); columnIdx++) { Column targetColumn = targetTable.getColumn(columnIdx); Column sourceColumn = sourceTable.findColumn(targetColumn.getName(), _caseSensitive); - if (sourceColumn == null) - { - if (_log.isDebugEnabled()) - { - _log.debug("Column " + targetColumn.getName() + " needs to be created for table " + sourceTable.getName()); + if (sourceColumn == null) { + if (_log.isDebugEnabled()) { + _log.debug("Column " + targetColumn.getName() + + " needs to be created for table " + sourceTable.getName()); } - AddColumnChange change = new AddColumnChange(sourceTable, - targetColumn, - columnIdx > 0 ? targetTable.getColumn(columnIdx - 1) : null, - columnIdx < targetTable.getColumnCount() - 1 ? targetTable.getColumn(columnIdx + 1) : null); + AddColumnChange change = new AddColumnChange(sourceTable, targetColumn, + columnIdx > 0 ? targetTable.getColumn(columnIdx - 1) : null, + columnIdx < targetTable.getColumnCount() - 1 ? targetTable + .getColumn(columnIdx + 1) : null); changes.add(change); addColumnChanges.put(targetColumn, change); - } - else - { + } else { changes.addAll(compareColumns(sourceTable, sourceColumn, targetTable, targetColumn)); } } - // if the last columns in the target table are added, then we note this at the changes - for (int columnIdx = targetTable.getColumnCount() - 1; columnIdx >= 0; columnIdx--) - { - Column targetColumn = targetTable.getColumn(columnIdx); - AddColumnChange change = (AddColumnChange)addColumnChanges.get(targetColumn); - - if (change == null) - { - // column was not added, so we can ignore any columns before it that were added + // if the last columns in the target table are added, then we note this + // at the changes + for (int columnIdx = targetTable.getColumnCount() - 1; columnIdx >= 0; columnIdx--) { + Column targetColumn = targetTable.getColumn(columnIdx); + AddColumnChange change = (AddColumnChange) addColumnChanges.get(targetColumn); + + if (change == null) { + // column was not added, so we can ignore any columns before it + // that were added break; - } - else - { + } else { change.setAtEnd(true); } } @@ -252,63 +237,52 @@ public List compareTables(Database sourceModel, Column[] sourcePK = sourceTable.getPrimaryKeyColumns(); Column[] targetPK = targetTable.getPrimaryKeyColumns(); - if ((sourcePK.length == 0) && (targetPK.length > 0)) - { - if (_log.isDebugEnabled()) - { + if ((sourcePK.length == 0) && (targetPK.length > 0)) { + if (_log.isDebugEnabled()) { _log.debug("A primary key needs to be added to the table " + sourceTable.getName()); } - // we have to use the target table here because the primary key might + // we have to use the target table here because the primary key + // might // reference a new column changes.add(new AddPrimaryKeyChange(targetTable, targetPK)); - } - else if ((targetPK.length == 0) && (sourcePK.length > 0)) - { - if (_log.isDebugEnabled()) - { - _log.debug("The primary key needs to be removed from the table " + sourceTable.getName()); + } else if ((targetPK.length == 0) && (sourcePK.length > 0)) { + if (_log.isDebugEnabled()) { + _log.debug("The primary key needs to be removed from the table " + + sourceTable.getName()); } changes.add(new RemovePrimaryKeyChange(sourceTable, sourcePK)); - } - else if ((sourcePK.length > 0) && (targetPK.length > 0)) - { + } else if ((sourcePK.length > 0) && (targetPK.length > 0)) { boolean changePK = false; - if (sourcePK.length != targetPK.length) - { + if (sourcePK.length != targetPK.length) { changePK = true; - } - else - { - for (int pkColumnIdx = 0; (pkColumnIdx < sourcePK.length) && !changePK; pkColumnIdx++) - { - if ((_caseSensitive && !sourcePK[pkColumnIdx].getName().equals(targetPK[pkColumnIdx].getName())) || - (!_caseSensitive && !sourcePK[pkColumnIdx].getName().equalsIgnoreCase(targetPK[pkColumnIdx].getName()))) - { + } else { + for (int pkColumnIdx = 0; (pkColumnIdx < sourcePK.length) && !changePK; pkColumnIdx++) { + if ((_caseSensitive && !sourcePK[pkColumnIdx].getName().equals( + targetPK[pkColumnIdx].getName())) + || (!_caseSensitive && !sourcePK[pkColumnIdx].getName() + .equalsIgnoreCase(targetPK[pkColumnIdx].getName()))) { changePK = true; } } } - if (changePK) - { - if (_log.isDebugEnabled()) - { - _log.debug("The primary key of table " + sourceTable.getName() + " needs to be changed"); + if (changePK) { + if (_log.isDebugEnabled()) { + _log.debug("The primary key of table " + sourceTable.getName() + + " needs to be changed"); } changes.add(new PrimaryKeyChange(sourceTable, sourcePK, targetPK)); } } - - for (int columnIdx = 0; columnIdx < sourceTable.getColumnCount(); columnIdx++) - { + + for (int columnIdx = 0; columnIdx < sourceTable.getColumnCount(); columnIdx++) { Column sourceColumn = sourceTable.getColumn(columnIdx); Column targetColumn = targetTable.findColumn(sourceColumn.getName(), _caseSensitive); - if (targetColumn == null) - { - if (_log.isDebugEnabled()) - { - _log.debug("Column " + sourceColumn.getName() + " needs to be removed from table " + sourceTable.getName()); + if (targetColumn == null) { + if (_log.isDebugEnabled()) { + _log.debug("Column " + sourceColumn.getName() + + " needs to be removed from table " + sourceTable.getName()); } changes.add(new RemoveColumnChange(sourceTable, sourceColumn)); } @@ -318,113 +292,126 @@ else if ((sourcePK.length > 0) && (targetPK.length > 0)) } /** - * Compares the two columns and returns the changes necessary to create the second - * column from the first one. - * - * @param sourceTable The source table which contains the source column - * @param sourceColumn The source column - * @param targetTable The target table which contains the target column - * @param targetColumn The target column + * Compares the two columns and returns the changes necessary to create the + * second column from the first one. + * + * @param sourceTable + * The source table which contains the source column + * @param sourceColumn + * The source column + * @param targetTable + * The target table which contains the target column + * @param targetColumn + * The target column * @return The changes */ - public List compareColumns(Table sourceTable, - Column sourceColumn, - Table targetTable, - Column targetColumn) - { + public List compareColumns(Table sourceTable, Column sourceColumn, Table targetTable, + Column targetColumn) { ArrayList changes = new ArrayList(); - if (targetColumn.getTypeCode() != sourceColumn.getTypeCode() && _platformInfo.getTargetJdbcType(targetColumn.getTypeCode()) != sourceColumn.getTypeCode()) - { + if (targetColumn.getTypeCode() != sourceColumn.getTypeCode() + && _platformInfo.getTargetJdbcType(targetColumn.getTypeCode()) != sourceColumn + .getTypeCode()) { if (_log.isDebugEnabled()) { - _log.debug("The " + sourceColumn.getName() + " column on the " + sourceTable.getName() + " table changed type codes from " + sourceColumn.getTypeCode() + " to " + targetColumn.getTypeCode()); + _log.debug("The " + sourceColumn.getName() + " column on the " + + sourceTable.getName() + " table changed type codes from " + + sourceColumn.getTypeCode() + " to " + targetColumn.getTypeCode()); } - changes.add(new ColumnDataTypeChange(sourceTable, sourceColumn, targetColumn.getTypeCode())); + changes.add(new ColumnDataTypeChange(sourceTable, sourceColumn, targetColumn + .getTypeCode())); } - boolean sizeMatters = _platformInfo.hasSize(sourceColumn.getTypeCode()); + boolean sizeMatters = _platformInfo.hasSize(sourceColumn.getTypeCode()); boolean scaleMatters = _platformInfo.hasPrecisionAndScale(sourceColumn.getTypeCode()); String targetSize = targetColumn.getSize(); if (targetSize == null) { - Integer defaultSize = _platformInfo.getDefaultSize(_platformInfo.getTargetJdbcType(targetColumn.getTypeCode())); + Integer defaultSize = _platformInfo.getDefaultSize(_platformInfo + .getTargetJdbcType(targetColumn.getTypeCode())); if (defaultSize != null) { targetSize = defaultSize.toString(); } else { targetSize = "0"; } } - if (sizeMatters && - !StringUtils.equals(sourceColumn.getSize(), targetSize)) - { + if (sizeMatters && !StringUtils.equals(sourceColumn.getSize(), targetSize)) { if (_log.isDebugEnabled()) { - _log.debug("The " + sourceColumn.getName() + " column on the " + sourceTable.getName() + " table changed size from (" + sourceColumn.getSizeAsInt() + ") to (" + targetColumn.getSizeAsInt() + ")"); + _log.debug("The " + sourceColumn.getName() + " column on the " + + sourceTable.getName() + " table changed size from (" + + sourceColumn.getSizeAsInt() + ") to (" + targetColumn.getSizeAsInt() + + ")"); } - changes.add(new ColumnSizeChange(sourceTable, sourceColumn, targetColumn.getSizeAsInt(), targetColumn.getScale())); - } - else if (scaleMatters && - (!StringUtils.equals(sourceColumn.getSize(), targetSize) || - // ojdbc6.jar returns -127 for the scale of NUMBER that was not given a size or precision - (!(sourceColumn.getScale() < 0 && targetColumn.getScale() == 0) && - sourceColumn.getScale() != targetColumn.getScale()))) - { + changes.add(new ColumnSizeChange(sourceTable, sourceColumn, + targetColumn.getSizeAsInt(), targetColumn.getScale())); + } else if (scaleMatters && (!StringUtils.equals(sourceColumn.getSize(), targetSize) || + // ojdbc6.jar returns -127 for the scale of NUMBER that was not given a + // size or precision + (!(sourceColumn.getScale() < 0 && targetColumn.getScale() == 0) && sourceColumn + .getScale() != targetColumn.getScale()))) { if (_log.isDebugEnabled()) { - _log.debug("The " + sourceColumn.getName() + " column on the " + sourceTable.getName() + " table changed scale from (" + sourceColumn.getSizeAsInt() + ","+sourceColumn.getScale() + ") to (" + targetColumn.getSizeAsInt() + ","+targetColumn.getScale() + ")"); + _log.debug("The " + sourceColumn.getName() + " column on the " + + sourceTable.getName() + " table changed scale from (" + + sourceColumn.getSizeAsInt() + "," + sourceColumn.getScale() + ") to (" + + targetColumn.getSizeAsInt() + "," + targetColumn.getScale() + ")"); } - changes.add(new ColumnSizeChange(sourceTable, sourceColumn, targetColumn.getSizeAsInt(), targetColumn.getScale())); + changes.add(new ColumnSizeChange(sourceTable, sourceColumn, + targetColumn.getSizeAsInt(), targetColumn.getScale())); } Object sourceDefaultValue = sourceColumn.getParsedDefaultValue(); Object targetDefaultValue = targetColumn.getParsedDefaultValue(); - if (((sourceDefaultValue == null) && (targetDefaultValue != null)) || - ((sourceDefaultValue != null) && !sourceDefaultValue.equals(targetDefaultValue))) - { + if (((sourceDefaultValue == null) && (targetDefaultValue != null)) + || ((sourceDefaultValue != null) && !sourceDefaultValue.equals(targetDefaultValue))) { if (_log.isDebugEnabled()) { - _log.debug("The " + sourceColumn.getName() + " column on the " + sourceTable.getName() + " table changed default value from " + sourceColumn.getDefaultValue() + " to " + targetColumn.getDefaultValue()); + _log.debug("The " + sourceColumn.getName() + " column on the " + + sourceTable.getName() + " table changed default value from " + + sourceColumn.getDefaultValue() + " to " + targetColumn.getDefaultValue()); } - changes.add(new ColumnDefaultValueChange(sourceTable, sourceColumn, targetColumn.getDefaultValue())); + changes.add(new ColumnDefaultValueChange(sourceTable, sourceColumn, targetColumn + .getDefaultValue())); } - if (sourceColumn.isRequired() != targetColumn.isRequired()) - { + if (sourceColumn.isRequired() != targetColumn.isRequired()) { if (_log.isDebugEnabled()) { - _log.debug("The " + sourceColumn.getName() + " column on the " + sourceTable.getName() + " table changed required status from " + sourceColumn.isRequired() + " to " + targetColumn.isRequired()); + _log.debug("The " + sourceColumn.getName() + " column on the " + + sourceTable.getName() + " table changed required status from " + + sourceColumn.isRequired() + " to " + targetColumn.isRequired()); } changes.add(new ColumnRequiredChange(sourceTable, sourceColumn)); } - - if (sourceColumn.isAutoIncrement() != targetColumn.isAutoIncrement()) - { + + if (sourceColumn.isAutoIncrement() != targetColumn.isAutoIncrement()) { if (_log.isDebugEnabled()) { - _log.debug("The " + sourceColumn.getName() + " column on the " + sourceTable.getName() + " table changed auto increment status from " + sourceColumn.isAutoIncrement() + " to " + targetColumn.isAutoIncrement()); + _log.debug("The " + sourceColumn.getName() + " column on the " + + sourceTable.getName() + " table changed auto increment status from " + + sourceColumn.isAutoIncrement() + " to " + targetColumn.isAutoIncrement()); } changes.add(new ColumnAutoIncrementChange(sourceTable, sourceColumn)); } - + return changes; } /** - * Searches in the given table for a corresponding foreign key. If the given key - * has no name, then a foreign key to the same table with the same columns (but not - * necessarily in the same order) is searched. If the given key has a name, then the - * corresponding key also needs to have the same name, or no name at all, but not a - * different one. + * Searches in the given table for a corresponding foreign key. If the given + * key has no name, then a foreign key to the same table with the same + * columns (but not necessarily in the same order) is searched. If the given + * key has a name, then the corresponding key also needs to have the same + * name, or no name at all, but not a different one. * - * @param table The table to search in - * @param fk The original foreign key + * @param table + * The table to search in + * @param fk + * The original foreign key * @return The corresponding foreign key if found */ - private ForeignKey findCorrespondingForeignKey(Table table, ForeignKey fk) - { - for (int fkIdx = 0; fkIdx < table.getForeignKeyCount(); fkIdx++) - { + private ForeignKey findCorrespondingForeignKey(Table table, ForeignKey fk) { + for (int fkIdx = 0; fkIdx < table.getForeignKeyCount(); fkIdx++) { ForeignKey curFk = table.getForeignKey(fkIdx); - if ((_caseSensitive && fk.equals(curFk)) || - (!_caseSensitive && fk.equalsIgnoreCase(curFk))) - { + if ((_caseSensitive && fk.equals(curFk)) + || (!_caseSensitive && fk.equalsIgnoreCase(curFk))) { return curFk; } } @@ -434,22 +421,22 @@ private ForeignKey findCorrespondingForeignKey(Table table, ForeignKey fk) /** * Searches in the given table for a corresponding index. If the given index * has no name, then a index to the same table with the same columns in the - * same order is searched. If the given index has a name, then the a corresponding - * index also needs to have the same name, or no name at all, but not a different one. + * same order is searched. If the given index has a name, then the a + * corresponding index also needs to have the same name, or no name at all, + * but not a different one. * - * @param table The table to search in - * @param index The original index + * @param table + * The table to search in + * @param index + * The original index * @return The corresponding index if found */ - private Index findCorrespondingIndex(Table table, Index index) - { - for (int indexIdx = 0; indexIdx < table.getIndexCount(); indexIdx++) - { + private Index findCorrespondingIndex(Table table, Index index) { + for (int indexIdx = 0; indexIdx < table.getIndexCount(); indexIdx++) { Index curIndex = table.getIndex(indexIdx); - if ((_caseSensitive && index.equals(curIndex)) || - (!_caseSensitive && index.equalsIgnoreCase(curIndex))) - { + if ((_caseSensitive && index.equals(curIndex)) + || (!_caseSensitive && index.equalsIgnoreCase(curIndex))) { return curIndex; } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/PrimaryKeyChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/PrimaryKeyChange.java similarity index 90% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/PrimaryKeyChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/PrimaryKeyChange.java index bacd132c5b..4cdd9cbf4a 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/PrimaryKeyChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/PrimaryKeyChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the change of the primary key of a table. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveColumnChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveColumnChange.java similarity index 86% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveColumnChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveColumnChange.java index ec18c57897..d05965814e 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveColumnChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveColumnChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the removal of a column from a table. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveForeignKeyChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveForeignKeyChange.java similarity index 86% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveForeignKeyChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveForeignKeyChange.java index 924fac342c..fbb2448f6c 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveForeignKeyChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveForeignKeyChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,16 +19,14 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the removal of a foreign key from a table. Note that for * simplicity and because it fits the model, this change actually implements * table change for the table that the foreign key originates. - * - * @version $Revision: $ */ public class RemoveForeignKeyChange extends TableChangeImplBase { diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveIndexChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveIndexChange.java similarity index 86% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveIndexChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveIndexChange.java index e0e4ede5d1..847567d861 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveIndexChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveIndexChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the removal of an index from a table. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemovePrimaryKeyChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemovePrimaryKeyChange.java similarity index 88% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemovePrimaryKeyChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemovePrimaryKeyChange.java index 07c63aa90d..f09d609ad0 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemovePrimaryKeyChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemovePrimaryKeyChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,9 +19,9 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the removal of the primary key from a table. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveTableChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveTableChange.java similarity index 87% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveTableChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveTableChange.java index 343f633434..6f678d626a 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/RemoveTableChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/RemoveTableChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,8 +19,8 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; /** * Represents the removal of a table from a model. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/TableChange.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/TableChange.java similarity index 85% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/TableChange.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/TableChange.java index 3800dd89a7..333b305921 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/TableChange.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/TableChange.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,14 +19,14 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; /** * Represents a change to a table or sub-element of a table (e.g. a column). * * @version $Revision: $ */ -public interface TableChange extends ModelChange +public interface TableChange extends IModelChange { /** * Returns the affected table from the original model. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/TableChangeImplBase.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/TableChangeImplBase.java similarity index 89% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/TableChangeImplBase.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/TableChangeImplBase.java index 4d33396631..35ade7a9d0 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/TableChangeImplBase.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/TableChangeImplBase.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.alteration; +package org.jumpmind.symmetric.db.alter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,7 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; /** * Base class for change implementations. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/alteration/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/alter/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/Platform.java deleted file mode 100644 index 559429f1c0..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/Platform.java +++ /dev/null @@ -1,616 +0,0 @@ -package org.jumpmind.symmetric.db.ddl; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Map; - -import javax.sql.DataSource; - -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.CreationParameters; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; - -/* - * A platform encapsulates the database-related functionality such as performing queries - * and manipulations. It also contains an sql builder that is specific to this platform. - * - * @version $Revision: 231110 $ - */ -public interface Platform -{ - /* - * Returns the name of the database that this platform is for. - * - * @return The name - */ - public String getName(); - - /* - * Returns the info object for this platform. - * - * @return The info object - */ - public PlatformInfo getPlatformInfo(); - - /* - * Returns the sql builder for the this platform. - * - * @return The sql builder - */ - public SqlBuilder getSqlBuilder(); - - /* - * Returns the model reader (which reads a database model from a live database) for this platform. - * - * @return The model reader - */ - public JdbcModelReader getModelReader(); - - /* - * Returns the data source that this platform uses to access the database. - * - * @return The data source - */ - public DataSource getDataSource(); - - /* - * Sets the data source that this platform shall use to access the database. - * - * @param dataSource The data source - */ - public void setDataSource(DataSource dataSource); - - /* - * Returns the username that this platform shall use to access the database. - * - * @return The username - */ - public String getUsername(); - - /* - * Sets the username that this platform shall use to access the database. - * - * @param username The username - */ - public void setUsername(String username); - - /* - * Returns the password that this platform shall use to access the database. - * - * @return The password - */ - public String getPassword(); - - /* - * Sets the password that this platform shall use to access the database. - * - * @param password The password - */ - public void setPassword(String password); - - /* - * Determines whether script mode is on. This means that the generated SQL is not - * intended to be sent directly to the database but rather to be saved in a SQL - * script file. Per default, script mode is off. - * - * @return true if script mode is on - */ - public boolean isScriptModeOn(); - - /* - * Specifies whether script mode is on. This means that the generated SQL is not - * intended to be sent directly to the database but rather to be saved in a SQL - * script file. - * - * @param scriptModeOn true if script mode is on - */ - public void setScriptModeOn(boolean scriptModeOn); - - /* - * Determines whether delimited identifiers are used or normal SQL92 identifiers - * (which may only contain alphanumerical characters and the underscore, must start - * with a letter and cannot be a reserved keyword). - * Per default, delimited identifiers are not used - * - * @return true if delimited identifiers are used - */ - public boolean isDelimitedIdentifierModeOn(); - - /* - * Specifies whether delimited identifiers are used or normal SQL92 identifiers. - * - * @param delimitedIdentifierModeOn true if delimited identifiers shall be used - */ - public void setDelimitedIdentifierModeOn(boolean delimitedIdentifierModeOn); - - /* - * Determines whether SQL comments are generated. - * - * @return true if SQL comments shall be generated - */ - public boolean isSqlCommentsOn(); - - /* - * Specifies whether SQL comments shall be generated. - * - * @param sqlCommentsOn true if SQL comments shall be generated - */ - public void setSqlCommentsOn(boolean sqlCommentsOn); - - /* - * Determines whether SQL insert statements can specify values for identity columns. - * This setting is only relevant if the database supports it - * ({@link PlatformInfo#isIdentityOverrideAllowed()}). If this is off, then the - * insert methods will ignore values for identity columns. - * - * @return true if identity override is enabled (the default) - */ - public boolean isIdentityOverrideOn(); - - /* - * Specifies whether SQL insert statements can specify values for identity columns. - * This setting is only relevant if the database supports it - * ({@link PlatformInfo#isIdentityOverrideAllowed()}). If this is off, then the - * insert methods will ignore values for identity columns. - * - * @param identityOverrideOn true if identity override is enabled (the default) - */ - public void setIdentityOverrideOn(boolean identityOverrideOn); - - /* - * Determines whether foreign keys of a table read from a live database - * are alphabetically sorted. - * - * @return true if read foreign keys are sorted - */ - public boolean isForeignKeysSorted(); - - /* - * Specifies whether foreign keys read from a live database, shall be - * alphabetically sorted. - * - * @param foreignKeysSorted true if read foreign keys shall be sorted - */ - public void setForeignKeysSorted(boolean foreignKeysSorted); - - /* - * Returns a (new) JDBC connection from the data source. - * - * @return The connection - */ - public Connection borrowConnection() throws DatabaseOperationException; - - /* - * Closes the given JDBC connection (returns it back to the pool if the datasource is poolable). - * - * @param connection The connection - */ - public void returnConnection(Connection connection); - - /* - * Performs a shutdown at the database. This is necessary for some embedded databases which otherwise - * would be locked and thus would refuse other connections. Note that this does not change the database - * structure or data in it in any way. - */ - public void shutdownDatabase() throws DatabaseOperationException; - - /* - * Performs a shutdown at the database. This is necessary for some embedded databases which otherwise - * would be locked and thus would refuse other connections. Note that this does not change the database - * structure or data in it in any way. - * - * @param connection The connection to the database - */ - public void shutdownDatabase(Connection connection) throws DatabaseOperationException; - - /* - * Creates the database specified by the given parameters. Please note that this method does not - * use a data source set via {@link #setDataSource(DataSource)} because it is not possible to - * retrieve the connection information from it without establishing a connection.
- * The given connection url is the url that you'd use to connect to the already-created - * database.
- * On some platforms, this method suppurts additional parameters. These are documented in the - * manual section for the individual platforms. - * - * @param jdbcDriverClassName The jdbc driver class name - * @param connectionUrl The url to connect to the database if it were already created - * @param username The username for creating the database - * @param password The password for creating the database - * @param parameters Additional parameters relevant to database creation (which are platform specific) - */ - public void createDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password, Map parameters) throws DatabaseOperationException, UnsupportedOperationException; - - /* - * Drops the database specified by the given parameters. Please note that this method does not - * use a data source set via {@link #setDataSource(DataSource)} because it is not possible to - * retrieve the connection information from it without establishing a connection. - * - * @param jdbcDriverClassName The jdbc driver class name - * @param connectionUrl The url to connect to the database - * @param username The username for creating the database - * @param password The password for creating the database - */ - public void dropDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password) throws DatabaseOperationException, UnsupportedOperationException; - - /* - * Creates the tables defined in the database model. - * - * @param model The database model - * @param dropTablesFirst Whether to drop the tables prior to creating them (anew) - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void createTables(Database model, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException; - - /* - * Creates the tables defined in the database model. - * - * @param connection The connection to the database - * @param model The database model - * @param dropTablesFirst Whether to drop the tables prior to creating them (anew) - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void createTables(Connection connection, Database model, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for creating the tables defined in the database model. - * - * @param model The database model - * @param dropTablesFirst Whether to drop the tables prior to creating them (anew) - * @param continueOnError Whether to continue executing the sql commands when an error occurred - * @return The SQL statements - */ - public String getCreateTablesSql(Database model, boolean dropTablesFirst, boolean continueOnError); - - /* - * Creates the tables defined in the database model. - * - * @param model The database model - * @param params The parameters used in the creation - * @param dropTablesFirst Whether to drop the tables prior to creating them (anew) - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void createTables(Database model, CreationParameters params, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException; - - /* - * Creates the tables defined in the database model. - * - * @param connection The connection to the database - * @param model The database model - * @param params The parameters used in the creation - * @param dropTablesFirst Whether to drop the tables prior to creating them (anew) - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void createTables(Connection connection, Database model, CreationParameters params, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for creating the tables defined in the database model. - * - * @param model The database model - * @param params The parameters used in the creation - * @param dropTablesFirst Whether to drop the tables prior to creating them (anew) - * @param continueOnError Whether to continue executing the sql commands when an error occurred - * @return The SQL statements - */ - public String getCreateTablesSql(Database model, CreationParameters params, boolean dropTablesFirst, boolean continueOnError); - - /* - * Alters the database schema so that it match the given model. - * - * @param desiredDb The desired database schema - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(Database desiredDb, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param desiredDb The desired database schema - * @return The SQL statements - */ - public String getAlterTablesSql(Database desiredDb) throws DatabaseOperationException; - - /* - * Alters the database schema so that it match the given model. - * - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(Database desiredDb, CreationParameters params, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @return The SQL statements - */ - public String getAlterTablesSql(Database desiredDb, CreationParameters params) throws DatabaseOperationException; - - /* - * Alters the database schema so that it match the given model. - * - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(String catalog, String schema, String[] tableTypes, Database desiredDb, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @return The SQL statements - */ - public String getAlterTablesSql(String catalog, String schema, String[] tableTypes, Database desiredDb) throws DatabaseOperationException; - - /* - * Alters the database schema so that it match the given model. - * - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(String catalog, String schema, String[] tableTypes, Database desiredDb, CreationParameters params, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @return The SQL statements - */ - public String getAlterTablesSql(String catalog, String schema, String[] tableTypes, Database desiredDb, CreationParameters params) throws DatabaseOperationException; - - /* - * Alters the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param desiredDb The desired database schema - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(Connection connection, Database desiredDb, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param desiredDb The desired database schema - * @return The SQL statements - */ - public String getAlterTablesSql(Connection connection, Database desiredDb) throws DatabaseOperationException; - - /* - * Alters the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(Connection connection, Database desiredDb, CreationParameters params, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @return The SQL statements - */ - public String getAlterTablesSql(Connection connection, Database desiredDb, CreationParameters params) throws DatabaseOperationException; - - /* - * Alters the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredDb, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @return The SQL statements - */ - public String getAlterTablesSql(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredDb) throws DatabaseOperationException; - - /* - * Alters the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @param continueOnError Whether to continue with the next sql statement when an error occurred - */ - public void alterTables(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredDb, CreationParameters params, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for altering the database schema so that it match the given model. - * - * @param connection A connection to the existing database that shall be modified - * @param catalog The catalog in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param schema The schema in the existing database to read (can be a pattern); - * use null for the platform-specific default value - * @param tableTypes The table types to read from the existing database; - * use null or an empty array for the platform-specific default value - * @param desiredDb The desired database schema - * @param params The parameters used in the creation - * @return The SQL statements - */ - public String getAlterTablesSql(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredDb, CreationParameters params) throws DatabaseOperationException; - - /* - * Drops the specified table and all foreign keys pointing to it. - * - * @param model The database model - * @param table The table to drop - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void dropTable(Database model, Table table, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for dropping the given table and all foreign keys pointing to it. - * - * @param model The database model - * @param table The table to drop - * @param continueOnError Whether to continue executing the sql commands when an error occurred - * @return The SQL statements - */ - public String getDropTableSql(Database model, Table table, boolean continueOnError); - - /* - * Drops the specified table and all foreign keys pointing to it. - * - * @param connection The connection to the database - * @param model The database model - * @param table The table to drop - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void dropTable(Connection connection, Database model, Table table, boolean continueOnError) throws DatabaseOperationException; - - /* - * Drops the tables defined in the given database. - * - * @param model The database model - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void dropTables(Database model, boolean continueOnError) throws DatabaseOperationException; - - /* - * Returns the SQL for dropping the tables defined in the given database. - * - * @param model The database model - * @param continueOnError Whether to continue executing the sql commands when an error occurred - * @return The SQL statements - */ - public String getDropTablesSql(Database model, boolean continueOnError); - - /* - * Drops the tables defined in the given database. - * - * @param connection The connection to the database - * @param model The database model - * @param continueOnError Whether to continue executing the sql commands when an error occurred - */ - public void dropTables(Connection connection, Database model, boolean continueOnError) throws DatabaseOperationException; - - /* - * Reads the database model from the live database as specified by the data source set for - * this platform. - * - * @param name The name of the resulting database; null when the default name (the catalog) - * is desired which might be null itself though - * @return The database model - * @throws DatabaseOperationException If an error occurred during reading the model - */ - public Database readModelFromDatabase(String name) throws DatabaseOperationException; - - /* - * Reads the database model from the live database as specified by the data source set for - * this platform. - * - * @param name The name of the resulting database; null when the default name (the catalog) - * is desired which might be null itself though - * @param catalog The catalog to access in the database; use null for the default value - * @param schema The schema to access in the database; use null for the default value - * @param tableTypes The table types to process; use null or an empty list for the default ones - * @return The database model - * @throws DatabaseOperationException If an error occurred during reading the model - */ - public Database readModelFromDatabase(String name, String catalog, String schema, String[] tableTypes) throws DatabaseOperationException; - - /* - * Reads the database model from the live database to which the given connection is pointing. - * - * @param connection The connection to the database - * @param name The name of the resulting database; null when the default name (the catalog) - * is desired which might be null itself though - * @return The database model - * @throws DatabaseOperationException If an error occurred during reading the model - */ - public Database readModelFromDatabase(Connection connection, String name) throws DatabaseOperationException; - - /* - * Reads the database model from the live database to which the given connection is pointing. - * - * @param connection The connection to the database - * @param name The name of the resulting database; null when the default name (the catalog) - * is desired which might be null itself though - * @param catalog The catalog to access in the database; use null for the default value - * @param schema The schema to access in the database; use null for the default value - * @param tableTypes The table types to process; use null or an empty list for the default ones - * @return The database model - * @throws DatabaseOperationException If an error occurred during reading the model - */ - public Database readModelFromDatabase(Connection connection, String name, String catalog, String schema, String[] tableTypes) throws DatabaseOperationException; - - - public Table readTableFromDatabase(Connection connection, String catalogName, String schemaName, String tablename) throws SQLException; - -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformFactory.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformFactory.java deleted file mode 100644 index f3cfede4c1..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformFactory.java +++ /dev/null @@ -1,231 +0,0 @@ -package org.jumpmind.symmetric.db.ddl; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.util.HashMap; -import java.util.Map; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.platform.cloudscape.CloudscapePlatform; -import org.jumpmind.symmetric.db.ddl.platform.db2.Db2v8Platform; -import org.jumpmind.symmetric.db.ddl.platform.derby.DerbyPlatform; -import org.jumpmind.symmetric.db.ddl.platform.firebird.FirebirdPlatform; -import org.jumpmind.symmetric.db.ddl.platform.greenplum.GreenplumPlatform; -import org.jumpmind.symmetric.db.ddl.platform.h2.H2Platform; -import org.jumpmind.symmetric.db.ddl.platform.hsqldb.HsqlDbPlatform; -import org.jumpmind.symmetric.db.ddl.platform.hsqldb2.HsqlDb2Platform; -import org.jumpmind.symmetric.db.ddl.platform.informix.InformixPlatform; -import org.jumpmind.symmetric.db.ddl.platform.interbase.InterbasePlatform; -import org.jumpmind.symmetric.db.ddl.platform.mssql.MSSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.mysql.MySql50Platform; -import org.jumpmind.symmetric.db.ddl.platform.mysql.MySqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle10Platform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle8Platform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle9Platform; -import org.jumpmind.symmetric.db.ddl.platform.postgresql.PostgreSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.sqlite.SqLitePlatform; -import org.jumpmind.symmetric.db.ddl.platform.sybase.SybaseASE15Platform; -import org.jumpmind.symmetric.db.ddl.platform.sybase.SybasePlatform; - -/* - * A factory of {@link org.jumpmind.symmetric.ddl.Platform} instances based on a case - * insensitive database name. Note that this is a convenience class as the platforms - * can also simply be created via their constructors. - * - * @version $Revision: 209952 $ - */ -public class PlatformFactory -{ - /* The log for this platform. */ - private static final Log _log = LogFactory.getLog(PlatformFactory.class); - - /* The database name -> platform map. */ - private static Map> _platforms = null; - - /* - * Returns the platform map. - * - * @return The platform list - */ - private static synchronized Map> getPlatforms() - { - if (_platforms == null) - { - // lazy initialization - _platforms = new HashMap>(); - registerPlatforms(); - } - return _platforms; - } - - /* - * Creates a new platform for the given (case insensitive) database name - * or returns null if the database is not recognized. - * - * @param databaseName The name of the database (case is not important) - * @return The platform or null if the database is not supported - */ - public static synchronized Platform createNewPlatformInstance(String databaseName) throws DdlUtilsException - { - Class platformClass = getPlatforms().get(databaseName.toLowerCase()); - - try - { - return platformClass != null ? (Platform)platformClass.newInstance() : null; - } - catch (Exception ex) - { - throw new DdlUtilsException("Could not create platform for database "+databaseName, ex); - } - } - - /* - * Creates a new platform for the specified database. This is a shortcut method that uses - * {@link PlatformUtils#determineDatabaseType(String, String)} to determine the parameter - * for {@link #createNewPlatformInstance(String)}. Note that no database connection is - * established when using this method. - * - * @param jdbcDriver The jdbc driver - * @param jdbcConnectionUrl The connection url - * @return The platform or null if the database is not supported - */ - public static synchronized Platform createNewPlatformInstance(String jdbcDriver, String jdbcConnectionUrl) throws DdlUtilsException - { - return createNewPlatformInstance(PlatformUtils.determineDatabaseType(jdbcDriver, jdbcConnectionUrl)); - } - - /* - * Creates a new platform for the specified database. This is a shortcut method that uses - * {@link PlatformUtils#determineDatabaseType(DataSource)} to determine the parameter - * for {@link #createNewPlatformInstance(String)}. Note that this method sets the data source - * at the returned platform instance (method {@link Platform#setDataSource(DataSource)}). - * - * @param dataSource The data source for the database - * @return The platform or null if the database is not supported - */ - public static synchronized Platform createNewPlatformInstance(DataSource dataSource) throws DdlUtilsException - { - //connects to the database and uses actual metadata info to get db name and version - //to determine platform - String nameVersion = PlatformUtils.determineDatabaseNameVersion(dataSource); - Platform platform = createNewPlatformInstance(nameVersion); - if (platform == null) { - //uses the driver info to try and infer a platform - String dbType = PlatformUtils.determineDatabaseType(dataSource); - _log.debug("The name/version pair returned for the database, " - + nameVersion - + ", was not mapped to a known database platform. Defaulting to using just the database type of " - + dbType); - platform = createNewPlatformInstance(dbType); - } - platform.setDataSource(dataSource); - return platform; - } - - /* - * Returns a list of all supported platforms. - * - * @return The names of the currently registered platforms - */ - public static synchronized String[] getSupportedPlatforms() - { - return (String[])getPlatforms().keySet().toArray(new String[0]); - } - - /* - * Determines whether the indicated platform is supported. - * - * @param platformName The name of the platform - * @return true if the platform is supported - */ - public static boolean isPlatformSupported(String platformName) - { - return getPlatforms().containsKey(platformName.toLowerCase()); - } - - /* - * Registers a new platform. - * - * @param platformName The platform name - * @param platformClass The platform class which must implement the {@link Platform} interface - */ - public static synchronized void registerPlatform(String platformName, Class platformClass) - { - addPlatform(getPlatforms(), platformName, platformClass); - } - - /* - * Registers the known platforms. - */ - private static void registerPlatforms() - { - for (String name : H2Platform.DATABASENAMES) { - addPlatform(_platforms, name, - H2Platform.class); - } - addPlatform(_platforms, SqLitePlatform.DATABASENAME, SqLitePlatform.class); - addPlatform(_platforms, InformixPlatform.DATABASENAME, InformixPlatform.class); - addPlatform(_platforms, CloudscapePlatform.DATABASENAME, CloudscapePlatform.class); - addPlatform(_platforms, Db2v8Platform.DATABASENAMES, Db2v8Platform.class); - addPlatform(_platforms, DerbyPlatform.DATABASENAME, DerbyPlatform.class); - addPlatform(_platforms, FirebirdPlatform.DATABASENAME, FirebirdPlatform.class); - addPlatform(_platforms, GreenplumPlatform.DATABASENAME, GreenplumPlatform.class); - addPlatform(_platforms, HsqlDbPlatform.DATABASENAME, HsqlDbPlatform.class); - addPlatform(_platforms, HsqlDb2Platform.DATABASENAME, HsqlDb2Platform.class); - addPlatform(_platforms, InterbasePlatform.DATABASENAME, InterbasePlatform.class); - addPlatform(_platforms, MSSqlPlatform.DATABASENAME, MSSqlPlatform.class); - addPlatform(_platforms, MySqlPlatform.DATABASENAME, MySqlPlatform.class); - addPlatform(_platforms, MySql50Platform.DATABASENAME, MySql50Platform.class); - addPlatform(_platforms, Oracle8Platform.DATABASENAME, Oracle8Platform.class); - addPlatform(_platforms, Oracle9Platform.DATABASENAME, Oracle9Platform.class); - addPlatform(_platforms, Oracle10Platform.DATABASENAME10, Oracle10Platform.class); - addPlatform(_platforms, Oracle10Platform.DATABASENAME11, Oracle10Platform.class); - addPlatform(_platforms, PostgreSqlPlatform.DATABASENAME, PostgreSqlPlatform.class); - addPlatform(_platforms, SybasePlatform.DATABASENAME, SybasePlatform.class); - addPlatform(_platforms, SybaseASE15Platform.DATABASENAME, SybaseASE15Platform.class); - } - - /* - * Registers a new platform. - * - * @param platformMap The map to add the platform info to - * @param platformName The platform name - * @param platformClass The platform class which must implement the {@link Platform} interface - */ - private static synchronized void addPlatform(Map> platformMap, String[] platformNames, Class platformClass) - { - for (String platformName : platformNames) { - addPlatform(platformMap, platformName, platformClass); - } - } - - private static synchronized void addPlatform(Map> platformMap, String platformName, Class platformClass) - { - if (!Platform.class.isAssignableFrom(platformClass)) - { - throw new IllegalArgumentException("Cannot register class "+platformClass.getName()+" because it does not implement the "+Platform.class.getName()+" interface"); - } - platformMap.put(platformName.toLowerCase(), platformClass); - - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformUtils.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformUtils.java deleted file mode 100644 index 6a6707c1b7..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/PlatformUtils.java +++ /dev/null @@ -1,448 +0,0 @@ -package org.jumpmind.symmetric.db.ddl; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import javax.sql.DataSource; - -import org.jumpmind.symmetric.db.ddl.platform.cloudscape.CloudscapePlatform; -import org.jumpmind.symmetric.db.ddl.platform.db2.Db2Platform; -import org.jumpmind.symmetric.db.ddl.platform.derby.DerbyPlatform; -import org.jumpmind.symmetric.db.ddl.platform.firebird.FirebirdPlatform; -import org.jumpmind.symmetric.db.ddl.platform.greenplum.GreenplumPlatform; -import org.jumpmind.symmetric.db.ddl.platform.hsqldb.HsqlDbPlatform; -import org.jumpmind.symmetric.db.ddl.platform.interbase.InterbasePlatform; -import org.jumpmind.symmetric.db.ddl.platform.mssql.MSSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.mysql.MySqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle8Platform; -import org.jumpmind.symmetric.db.ddl.platform.postgresql.PostgreSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.sybase.SybasePlatform; - -/* - * Utility functions for dealing with database platforms. - * - * @version $Revision: 279421 $ - */ -public class PlatformUtils -{ - private PlatformUtils() { - } - - // Extended drivers that support more than one database - - /* The DataDirect Connect DB2 jdbc driver. */ - public static final String JDBC_DRIVER_DATADIRECT_DB2 = "com.ddtek.jdbc.db2.DB2Driver"; - /* The DataDirect Connect SQLServer jdbc driver. */ - public static final String JDBC_DRIVER_DATADIRECT_SQLSERVER = "com.ddtek.jdbc.sqlserver.SQLServerDriver"; - /* The DataDirect Connect Oracle jdbc driver. */ - public static final String JDBC_DRIVER_DATADIRECT_ORACLE = "com.ddtek.jdbc.oracle.OracleDriver"; - /* The DataDirect Connect Sybase jdbc driver. */ - public static final String JDBC_DRIVER_DATADIRECT_SYBASE = "com.ddtek.jdbc.sybase.SybaseDriver"; - /* The i-net DB2 jdbc driver. */ - public static final String JDBC_DRIVER_INET_DB2 = "com.inet.drda.DRDADriver"; - /* The i-net Oracle jdbc driver. */ - public static final String JDBC_DRIVER_INET_ORACLE = "com.inet.ora.OraDriver"; - /* The i-net SQLServer jdbc driver. */ - public static final String JDBC_DRIVER_INET_SQLSERVER = "com.inet.tds.TdsDriver"; - /* The i-net Sybase jdbc driver. */ - public static final String JDBC_DRIVER_INET_SYBASE = "com.inet.syb.SybDriver"; - /* The i-net pooled jdbc driver for SQLServer and Sybase. */ - public static final String JDBC_DRIVER_INET_POOLED = "com.inet.pool.PoolDriver"; - /* The JNetDirect SQLServer jdbc driver. */ - public static final String JDBC_DRIVER_JSQLCONNECT_SQLSERVER = "com.jnetdirect.jsql.JSQLDriver"; - /* The jTDS jdbc driver for SQLServer and Sybase. */ - public static final String JDBC_DRIVER_JTDS = "net.sourceforge.jtds.jdbc.Driver"; - - /* The subprotocol used by the DataDirect DB2 driver. */ - public static final String JDBC_SUBPROTOCOL_DATADIRECT_DB2 = "datadirect:db2"; - /* The subprotocol used by the DataDirect SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_DATADIRECT_SQLSERVER = "datadirect:sqlserver"; - /* The subprotocol used by the DataDirect Oracle driver. */ - public static final String JDBC_SUBPROTOCOL_DATADIRECT_ORACLE = "datadirect:oracle"; - /* The subprotocol used by the DataDirect Sybase driver. */ - public static final String JDBC_SUBPROTOCOL_DATADIRECT_SYBASE = "datadirect:sybase"; - /* The subprotocol used by the i-net DB2 driver. */ - public static final String JDBC_SUBPROTOCOL_INET_DB2 = "inetdb2"; - /* The subprotocol used by the i-net Oracle driver. */ - public static final String JDBC_SUBPROTOCOL_INET_ORACLE = "inetora"; - /* A subprotocol used by the i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER = "inetdae"; - /* A subprotocol used by the i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER6 = "inetdae6"; - /* A subprotocol used by the i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7 = "inetdae7"; - /* A subprotocol used by the i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7A = "inetdae7a"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_1 = "inetpool:inetdae"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_1 = "inetpool:inetdae6"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_1 = "inetpool:inetdae7"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_1 = "inetpool:inetdae7a"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_2 = "inetpool:jdbc:inetdae"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_2 = "inetpool:jdbc:inetdae6"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_2 = "inetpool:jdbc:inetdae7"; - /* A subprotocol used by the pooled i-net SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_2 = "inetpool:jdbc:inetdae7a"; - /* The subprotocol used by the i-net Sybase driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SYBASE = "inetsyb"; - /* The subprotocol used by the pooled i-net Sybase driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_1 = "inetpool:inetsyb"; - /* The subprotocol used by the pooled i-net Sybase driver. */ - public static final String JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_2 = "inetpool:jdbc:inetsyb"; - /* The subprotocol used by the JNetDirect SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_JSQLCONNECT_SQLSERVER = "JSQLConnect"; - /* The subprotocol used by the jTDS SQLServer driver. */ - public static final String JDBC_SUBPROTOCOL_JTDS_SQLSERVER = "jtds:sqlserver"; - /* The subprotocol used by the jTDS Sybase driver. */ - public static final String JDBC_SUBPROTOCOL_JTDS_SYBASE = "jtds:sybase"; - - /* Maps the sub-protocl part of a jdbc connection url to a OJB platform name. */ - private static HashMap jdbcSubProtocolToPlatform = new HashMap(); - /* Maps the jdbc driver name to a OJB platform name. */ - private static HashMap jdbcDriverToPlatform = new HashMap(); - - /* - * Creates a new instance. - */ - static - { - // Note that currently Sapdb and MaxDB have equal subprotocols and - // drivers so we have no means to distinguish them - jdbcSubProtocolToPlatform.put(CloudscapePlatform.JDBC_SUBPROTOCOL_1, CloudscapePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(CloudscapePlatform.JDBC_SUBPROTOCOL_2, CloudscapePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(Db2Platform.JDBC_SUBPROTOCOL, Db2Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(Db2Platform.JDBC_SUBPROTOCOL_OS390_1, Db2Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(Db2Platform.JDBC_SUBPROTOCOL_OS390_2, Db2Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(Db2Platform.JDBC_SUBPROTOCOL_JTOPEN, Db2Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_DB2, Db2Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_DB2, Db2Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(DerbyPlatform.JDBC_SUBPROTOCOL, DerbyPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(FirebirdPlatform.JDBC_SUBPROTOCOL, FirebirdPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(HsqlDbPlatform.JDBC_SUBPROTOCOL, HsqlDbPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(InterbasePlatform.JDBC_SUBPROTOCOL, InterbasePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(MSSqlPlatform.JDBC_SUBPROTOCOL, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(MSSqlPlatform.JDBC_SUBPROTOCOL_NEW, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(MSSqlPlatform.JDBC_SUBPROTOCOL_INTERNAL, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_SQLSERVER, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER6, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7A, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_1, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_1, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_1, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_1, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER_POOLED_2, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER6_POOLED_2, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7_POOLED_2, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SQLSERVER7A_POOLED_2, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_JSQLCONNECT_SQLSERVER, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_JTDS_SQLSERVER, MSSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(MySqlPlatform.JDBC_SUBPROTOCOL, MySqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(Oracle8Platform.JDBC_SUBPROTOCOL_THIN, Oracle8Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(Oracle8Platform.JDBC_SUBPROTOCOL_OCI8, Oracle8Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(Oracle8Platform.JDBC_SUBPROTOCOL_THIN_OLD, Oracle8Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_ORACLE, Oracle8Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_ORACLE, Oracle8Platform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PostgreSqlPlatform.JDBC_SUBPROTOCOL, PostgreSqlPlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(SybasePlatform.JDBC_SUBPROTOCOL, SybasePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_DATADIRECT_SYBASE, SybasePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SYBASE, SybasePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_1, SybasePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_INET_SYBASE_POOLED_2, SybasePlatform.DATABASENAME); - jdbcSubProtocolToPlatform.put(PlatformUtils.JDBC_SUBPROTOCOL_JTDS_SYBASE, SybasePlatform.DATABASENAME); - - jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER, Db2Platform.DATABASENAME); - jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER_OLD1, Db2Platform.DATABASENAME); - jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER_OLD2, Db2Platform.DATABASENAME); - jdbcDriverToPlatform.put(Db2Platform.JDBC_DRIVER_JTOPEN, Db2Platform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_DATADIRECT_DB2, Db2Platform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_INET_DB2, Db2Platform.DATABASENAME); - jdbcDriverToPlatform.put(DerbyPlatform.JDBC_DRIVER_EMBEDDED, DerbyPlatform.DATABASENAME); - jdbcDriverToPlatform.put(DerbyPlatform.JDBC_DRIVER, DerbyPlatform.DATABASENAME); - jdbcDriverToPlatform.put(FirebirdPlatform.JDBC_DRIVER, FirebirdPlatform.DATABASENAME); - jdbcDriverToPlatform.put(HsqlDbPlatform.JDBC_DRIVER, HsqlDbPlatform.DATABASENAME); - jdbcDriverToPlatform.put(InterbasePlatform.JDBC_DRIVER, InterbasePlatform.DATABASENAME); - jdbcDriverToPlatform.put(MSSqlPlatform.JDBC_DRIVER, MSSqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(MSSqlPlatform.JDBC_DRIVER_NEW, MSSqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_DATADIRECT_SQLSERVER, MSSqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_INET_SQLSERVER, MSSqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_JSQLCONNECT_SQLSERVER, MSSqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(MySqlPlatform.JDBC_DRIVER, MySqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(MySqlPlatform.JDBC_DRIVER_OLD, MySqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(Oracle8Platform.JDBC_DRIVER, Oracle8Platform.DATABASENAME); - jdbcDriverToPlatform.put(Oracle8Platform.JDBC_DRIVER_OLD, Oracle8Platform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_DATADIRECT_ORACLE, Oracle8Platform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_INET_ORACLE, Oracle8Platform.DATABASENAME); - jdbcDriverToPlatform.put(PostgreSqlPlatform.JDBC_DRIVER, PostgreSqlPlatform.DATABASENAME); - jdbcDriverToPlatform.put(SybasePlatform.JDBC_DRIVER, SybasePlatform.DATABASENAME); - jdbcDriverToPlatform.put(SybasePlatform.JDBC_DRIVER_OLD, SybasePlatform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_DATADIRECT_SYBASE, SybasePlatform.DATABASENAME); - jdbcDriverToPlatform.put(PlatformUtils.JDBC_DRIVER_INET_SYBASE, SybasePlatform.DATABASENAME); - } - - /* - * Tries to determine the database type for the given data source. Note that this will establish - * a connection to the database. - * - * @param dataSource The data source - * @return The database type or null if the database type couldn't be determined - */ - public static String determineDatabaseType(DataSource dataSource) throws DatabaseOperationException - { - Connection connection = null; - - try - { - connection = dataSource.getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - return determineDatabaseType(metaData.getDriverName(), metaData.getURL()); - } - catch (SQLException ex) - { - throw new DatabaseOperationException("Error while reading the database metadata: " + ex.getMessage(), ex); - } - finally - { - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException ex) - { - // we ignore this one - } - } - } - } - - public static String getDatabaseProductVersion(DataSource dataSource) { - Connection connection = null; - - try { - connection = dataSource.getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - return metaData.getDatabaseProductVersion(); - } catch (SQLException ex) { - throw new DatabaseOperationException("Error while reading the database metadata: " - + ex.getMessage(), ex); - } finally { - if (connection != null) { - try { - connection.close(); - } catch (SQLException ex) { - // we ignore this one - } - } - } - } - - public static int getDatabaseMajorVersion(DataSource dataSource) { - Connection connection = null; - try { - connection = dataSource.getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - return metaData.getDatabaseMajorVersion(); - } catch (SQLException ex) { - throw new DatabaseOperationException("Error while reading the database metadata: " - + ex.getMessage(), ex); - } finally { - if (connection != null) { - try { - connection.close(); - } catch (SQLException ex) { - // we ignore this one - } - } - } - } - - public static int getDatabaseMinorVersion(DataSource dataSource) { - Connection connection = null; - try { - connection = dataSource.getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - return metaData.getDatabaseMinorVersion(); - } catch (SQLException ex) { - throw new DatabaseOperationException("Error while reading the database metadata: " - + ex.getMessage(), ex); - } finally { - if (connection != null) { - try { - connection.close(); - } catch (SQLException ex) { - // we ignore this one - } - } - } - } - - public static String determineDatabaseNameVersion(DataSource dataSource) throws DatabaseOperationException { - Connection connection = null; - - try { - connection = dataSource.getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - String productName = metaData.getDatabaseProductName(); - int majorVersion = metaData.getDatabaseMajorVersion(); - /* if the productName is PostgreSQL, it could be either PostgreSQL or Greenplum */ - /* query the metadata to determine which one it is */ - if (productName.equalsIgnoreCase(PostgreSqlPlatform.DATABASENAME)) { - if (isGreenplumDatabase(connection)) { - productName = GreenplumPlatform.DATABASE; - majorVersion = getGreenplumVersion(connection); - } - } - String productString = productName; - if (majorVersion > 0) { - productString += majorVersion; - } - - return productString; - } catch (SQLException ex) { - throw new DatabaseOperationException("Error while reading the database metadata: " - + ex.getMessage(), ex); - } finally { - if (connection != null) { - try { - connection.close(); - } catch (SQLException ex) { - // we ignore this one - } - } - } - } - - private static boolean isGreenplumDatabase(Connection connection) { - Statement stmt = null; - ResultSet rs = null; - String productName = null; - boolean isGreenplum = false; - try { - stmt = connection.createStatement(); - rs = stmt.executeQuery(GreenplumPlatform.SQL_GET_GREENPLUM_NAME); - while (rs.next()) { - productName = rs.getString(1); - } - if (productName != null && productName.equalsIgnoreCase(GreenplumPlatform.DATABASE)) { - isGreenplum = true; - } - }catch (SQLException ex) { - // ignore the exception, if it is caught, then this is most likely not - // a greenplum database - } finally { - try { - if (rs != null) { - rs.close(); - } - if (stmt != null) { - stmt.close(); - } - } - catch (SQLException ex) { - } - } - return isGreenplum; - } - - private static int getGreenplumVersion(Connection connection) { - Statement stmt = null; - ResultSet rs = null; - String versionName = null; - int productVersion = 0; - try { - stmt = connection.createStatement(); - rs = stmt.executeQuery(GreenplumPlatform.SQL_GET_GREENPLUM_VERSION); - while (rs.next()) { - versionName = rs.getString(1); - } - //take up to the first "." for version number - if (versionName.indexOf('.') != -1) { - versionName = versionName.substring(0,versionName.indexOf('.')); - } - try { - productVersion = Integer.parseInt(versionName); - } - catch (NumberFormatException ex) { - // if we can't convert this to a version number, leave it 0 - } - } - catch (SQLException ex) { - // ignore the exception, if it is caught, then this is most likely not - // a greenplum database - } - finally { - try { - rs.close(); - stmt.close(); - } - catch (SQLException ex) { - } - } - return productVersion; - } - - /* - * Tries to determine the database type for the given jdbc driver and connection url. - * - * @param driverName The fully qualified name of the JDBC driver - * @param jdbcConnectionUrl The connection url - * @return The database type or null if the database type couldn't be determined - */ - public static String determineDatabaseType(String driverName, String jdbcConnectionUrl) - { - if (jdbcDriverToPlatform.containsKey(driverName)) - { - return (String)jdbcDriverToPlatform.get(driverName); - } - if (jdbcConnectionUrl == null) - { - return null; - } - for (Iterator> it = jdbcSubProtocolToPlatform.entrySet().iterator(); it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - String curSubProtocol = "jdbc:" + (String)entry.getKey() + ":"; - - if (jdbcConnectionUrl.startsWith(curSubProtocol)) - { - return (String)entry.getValue(); - } - } - return null; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/CreationParameters.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/CreationParameters.java deleted file mode 100644 index acbe7e63b6..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/CreationParameters.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.collections.map.ListOrderedMap; -import org.jumpmind.symmetric.db.ddl.model.Table; - -/** - * Contains parameters used in the table creation. Note that the definition - * order is retained (per table), so if a parameter should be applied before - * some other parameter, then add it before the other one. - * - * @version $Revision: 331006 $ - */ -public class CreationParameters -{ - /** The parameter maps keyed by the tables. */ - private Map _parametersPerTable = new HashMap(); - - /** - * Returns the parameters for the given table. - * - * @param table The table - * @return The parameters - */ - public Map getParametersFor(Table table) - { - ListOrderedMap result = new ListOrderedMap(); - Map globalParams = (Map)_parametersPerTable.get(null); - Map tableParams = (Map)_parametersPerTable.get(table); - - if (globalParams != null) - { - result.putAll(globalParams); - } - if (tableParams != null) - { - result.putAll(tableParams); - } - return result; - } - - /** - * Adds a parameter. - * - * @param table The table; if null then the parameter is for all tables - * @param paramName The name of the parameter - * @param paramValue The value of the parameter - */ - public void addParameter(Table table, String paramName, String paramValue) - { - Map params = (Map)_parametersPerTable.get(table); - - if (params == null) - { - // we're using a list orderered map to retain the order - params = new ListOrderedMap(); - _parametersPerTable.put(table, params); - } - params.put(paramName, paramValue); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/PlatformImplBase.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/PlatformImplBase.java deleted file mode 100644 index 94e8e3243a..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/PlatformImplBase.java +++ /dev/null @@ -1,1247 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.math.BigDecimal; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Statement; -import java.sql.Types; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.DatabaseOperationException; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; -import org.jumpmind.symmetric.db.ddl.util.JdbcSupport; -import org.jumpmind.symmetric.db.ddl.util.SqlTokenizer; - -/* - * Base class for platform implementations. - * - * @version $Revision: 231110 $ - */ -public abstract class PlatformImplBase extends JdbcSupport implements Platform -{ - /* The default name for models read from the database, if no name as given.*/ - protected static final String MODEL_DEFAULT_NAME = "default"; - - /* The log for this platform. */ - private final Log _log = LogFactory.getLog(getClass()); - - /* The platform info. */ - private PlatformInfo _info = new PlatformInfo(); - /* The sql builder for this platform. */ - private SqlBuilder _builder; - /* The model reader for this platform. */ - private JdbcModelReader _modelReader; - /* Whether script mode is on. */ - private boolean _scriptModeOn; - /* Whether SQL comments are generated or not. */ - private boolean _sqlCommentsOn = false; - /* Whether delimited identifiers are used or not. */ - private boolean _delimitedIdentifierModeOn; - /* Whether identity override is enabled. */ - private boolean _identityOverrideOn; - /* Whether read foreign keys shall be sorted alphabetically. */ - private boolean _foreignKeysSorted; - - /* - * {@inheritDoc} - */ - public SqlBuilder getSqlBuilder() - { - return _builder; - } - - /* - * Sets the sql builder for this platform. - * - * @param builder The sql builder - */ - protected void setSqlBuilder(SqlBuilder builder) - { - _builder = builder; - } - - /* - * {@inheritDoc} - */ - public JdbcModelReader getModelReader() - { - if (_modelReader == null) - { - _modelReader = new JdbcModelReader(this); - } - return _modelReader; - } - - /* - * Sets the model reader for this platform. - * - * @param modelReader The model reader - */ - protected void setModelReader(JdbcModelReader modelReader) - { - _modelReader = modelReader; - } - - /* - * {@inheritDoc} - */ - public PlatformInfo getPlatformInfo() - { - return _info; - } - - /* - * {@inheritDoc} - */ - public boolean isScriptModeOn() - { - return _scriptModeOn; - } - - /* - * {@inheritDoc} - */ - public void setScriptModeOn(boolean scriptModeOn) - { - _scriptModeOn = scriptModeOn; - } - - /* - * {@inheritDoc} - */ - public boolean isSqlCommentsOn() - { - return _sqlCommentsOn; - } - - /* - * {@inheritDoc} - */ - public void setSqlCommentsOn(boolean sqlCommentsOn) - { - if (!getPlatformInfo().isSqlCommentsSupported() && sqlCommentsOn) - { - throw new DdlUtilsException("Platform " + getName() + " does not support SQL comments"); - } - _sqlCommentsOn = sqlCommentsOn; - } - - /* - * {@inheritDoc} - */ - public boolean isDelimitedIdentifierModeOn() - { - return _delimitedIdentifierModeOn; - } - - /* - * {@inheritDoc} - */ - public void setDelimitedIdentifierModeOn(boolean delimitedIdentifierModeOn) - { - if (!getPlatformInfo().isDelimitedIdentifiersSupported() && delimitedIdentifierModeOn) - { - throw new DdlUtilsException("Platform " + getName() + " does not support delimited identifier"); - } - _delimitedIdentifierModeOn = delimitedIdentifierModeOn; - } - - /* - * {@inheritDoc} - */ - public boolean isIdentityOverrideOn() - { - return _identityOverrideOn; - } - - /* - * {@inheritDoc} - */ - public void setIdentityOverrideOn(boolean identityOverrideOn) - { - _identityOverrideOn = identityOverrideOn; - } - - /* - * {@inheritDoc} - */ - public boolean isForeignKeysSorted() - { - return _foreignKeysSorted; - } - - /* - * {@inheritDoc} - */ - public void setForeignKeysSorted(boolean foreignKeysSorted) - { - _foreignKeysSorted = foreignKeysSorted; - } - - /* - * Returns the log for this platform. - * - * @return The log - */ - protected Log getLog() - { - return _log; - } - - /* - * Logs any warnings associated to the given connection. Note that the connection needs - * to be open for this. - * - * @param connection The open connection - */ - protected void logWarnings(Connection connection) throws SQLException - { - SQLWarning warning = connection.getWarnings(); - - while (warning != null) - { - getLog().warn(warning.getLocalizedMessage(), warning.getCause()); - warning = warning.getNextWarning(); - } - } - - /* - * {@inheritDoc} - */ - public int evaluateBatch(String sql, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - return evaluateBatch(connection, sql, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public int evaluateBatch(Connection connection, String sql, boolean continueOnError) throws DatabaseOperationException - { - Statement statement = null; - int errors = 0; - int commandCount = 0; - - // we tokenize the SQL along the delimiters, and we also make sure that only delimiters - // at the end of a line or the end of the string are used (row mode) - try - { - statement = connection.createStatement(); - - SqlTokenizer tokenizer = new SqlTokenizer(sql); - - while (tokenizer.hasMoreStatements()) - { - String command = tokenizer.getNextStatement(); - - // ignore whitespace - command = command.trim(); - if (command.length() == 0) - { - continue; - } - - commandCount++; - - if (_log.isDebugEnabled()) - { - _log.debug("Executing SQL: " + command); - } - try - { - int results = statement.executeUpdate(command); - - if (_log.isDebugEnabled()) - { - _log.debug("After execution, " + results + " row(s) have been changed"); - } - } - catch (SQLException ex) - { - if (continueOnError) - { - // Since the user deciced to ignore this error, we log the error - // on level warn, and the exception itself on level debug - _log.warn("SQL Command " + command + " failed with: " + ex.getMessage()); - if (_log.isDebugEnabled()) - { - _log.debug(ex); - } - errors++; - } - else - { - throw new DatabaseOperationException("Error while executing SQL "+command, ex); - } - } - - // lets display any warnings - SQLWarning warning = connection.getWarnings(); - - while (warning != null) - { - _log.warn(warning.toString()); - warning = warning.getNextWarning(); - } - connection.clearWarnings(); - } - _log.info("Executed "+ commandCount + " SQL command(s) with " + errors + " error(s)"); - } - catch (SQLException ex) - { - throw new DatabaseOperationException("Error while executing SQL", ex); - } - finally - { - closeStatement(statement); - } - - return errors; - } - - /* - * {@inheritDoc} - */ - public void shutdownDatabase() throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - shutdownDatabase(connection); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void shutdownDatabase(Connection connection) throws DatabaseOperationException - { - // Per default do nothing as most databases don't need this - } - - /* - * {@inheritDoc} - */ - public void createDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password, Map parameters) throws DatabaseOperationException, UnsupportedOperationException - { - throw new UnsupportedOperationException("Database creation is not supported for the database platform "+getName()); - } - - /* - * {@inheritDoc} - */ - public void dropDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password) throws DatabaseOperationException, UnsupportedOperationException - { - throw new UnsupportedOperationException("Database deletion is not supported for the database platform "+getName()); - } - - /* - * {@inheritDoc} - */ - public void createTables(Database model, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - createTables(connection, model, dropTablesFirst, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void createTables(Connection connection, Database model, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException - { - String sql = getCreateTablesSql(model, dropTablesFirst, continueOnError); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public String getCreateTablesSql(Database model, boolean dropTablesFirst, boolean continueOnError) - { - String sql = null; - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().createTables(model, dropTablesFirst); - sql = buffer.toString(); - } - catch (IOException e) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public void createTables(Database model, CreationParameters params, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - createTables(connection, model, params, dropTablesFirst, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void createTables(Connection connection, Database model, CreationParameters params, boolean dropTablesFirst, boolean continueOnError) throws DatabaseOperationException - { - String sql = getCreateTablesSql(model, params, dropTablesFirst, continueOnError); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public String getCreateTablesSql(Database model, CreationParameters params, boolean dropTablesFirst, boolean continueOnError) - { - String sql = null; - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().createTables(model, params, dropTablesFirst); - sql = buffer.toString(); - } - catch (IOException e) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public void alterTables(Database desiredDb, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - alterTables(connection, desiredDb, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(Database desiredDb) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - return getAlterTablesSql(connection, desiredDb); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void alterTables(Database desiredDb, CreationParameters params, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - alterTables(connection, desiredDb, params, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(Database desiredDb, CreationParameters params) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - return getAlterTablesSql(connection, desiredDb, params); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void alterTables(Connection connection, Database desiredModel, boolean continueOnError) throws DatabaseOperationException - { - String sql = getAlterTablesSql(connection, desiredModel); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(Connection connection, Database desiredModel) throws DatabaseOperationException - { - String sql = null; - Database currentModel = readModelFromDatabase(connection, desiredModel.getName()); - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().alterDatabase(currentModel, desiredModel, null); - sql = buffer.toString(); - } - catch (IOException ex) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public void alterTables(Connection connection, Database desiredModel, CreationParameters params, boolean continueOnError) throws DatabaseOperationException - { - String sql = getAlterTablesSql(connection, desiredModel, params); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(Connection connection, Database desiredModel, CreationParameters params) throws DatabaseOperationException - { - String sql = null; - Database currentModel = readModelFromDatabase(connection, desiredModel.getName()); - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().alterDatabase(currentModel, desiredModel, params); - sql = buffer.toString(); - } - catch (IOException ex) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public void alterTables(String catalog, String schema, String[] tableTypes, Database desiredModel, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - alterTables(connection, catalog, schema, tableTypes, desiredModel, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(String catalog, String schema, String[] tableTypes, Database desiredModel) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - return getAlterTablesSql(connection, catalog, schema, tableTypes, desiredModel); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void alterTables(String catalog, String schema, String[] tableTypes, Database desiredModel, CreationParameters params, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - alterTables(connection, catalog, schema, tableTypes, desiredModel, params, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(String catalog, String schema, String[] tableTypes, Database desiredModel, CreationParameters params) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - return getAlterTablesSql(connection, catalog, schema, tableTypes, desiredModel, params); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void alterTables(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredModel, boolean continueOnError) throws DatabaseOperationException - { - String sql = getAlterTablesSql(connection, catalog, schema, tableTypes, desiredModel); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredModel) throws DatabaseOperationException - { - String sql = null; - Database currentModel = readModelFromDatabase(connection, desiredModel.getName(), catalog, schema, tableTypes); - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().alterDatabase(currentModel, desiredModel, null); - sql = buffer.toString(); - } - catch (IOException ex) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public void alterTables(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredModel, CreationParameters params, boolean continueOnError) throws DatabaseOperationException - { - String sql = getAlterTablesSql(connection, catalog, schema, tableTypes, desiredModel, params); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public String getAlterTablesSql(Connection connection, String catalog, String schema, String[] tableTypes, Database desiredModel, CreationParameters params) throws DatabaseOperationException - { - String sql = null; - Database currentModel = readModelFromDatabase(connection, desiredModel.getName(), catalog, schema, tableTypes); - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().alterDatabase(currentModel, desiredModel, params); - sql = buffer.toString(); - } - catch (IOException ex) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public void dropTable(Connection connection, Database model, Table table, boolean continueOnError) throws DatabaseOperationException - { - String sql = getDropTableSql(model, table, continueOnError); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public void dropTable(Database model, Table table, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - dropTable(connection, model, table, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public String getDropTableSql(Database model, Table table, boolean continueOnError) - { - String sql = null; - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().dropTable(model, table); - sql = buffer.toString(); - } - catch (IOException e) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public void dropTables(Database model, boolean continueOnError) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - dropTables(connection, model, continueOnError); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public void dropTables(Connection connection, Database model, boolean continueOnError) throws DatabaseOperationException - { - String sql = getDropTablesSql(model, continueOnError); - - evaluateBatch(connection, sql, continueOnError); - } - - /* - * {@inheritDoc} - */ - public String getDropTablesSql(Database model, boolean continueOnError) - { - String sql = null; - - try - { - StringWriter buffer = new StringWriter(); - - getSqlBuilder().setWriter(buffer); - getSqlBuilder().dropTables(model); - sql = buffer.toString(); - } - catch (IOException e) - { - // won't happen because we're using a string writer - } - return sql; - } - - /* - * {@inheritDoc} - */ - public Database readModelFromDatabase(String name) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - return readModelFromDatabase(connection, name); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public Database readModelFromDatabase(Connection connection, String name) throws DatabaseOperationException - { - try - { - Database model = getModelReader().getDatabase(connection, name); - - postprocessModelFromDatabase(model); - return model; - } - catch (SQLException ex) - { - throw new DatabaseOperationException(ex); - } - } - - /* - * {@inheritDoc} - */ - public Database readModelFromDatabase(String name, String catalog, String schema, String[] tableTypes) throws DatabaseOperationException - { - Connection connection = borrowConnection(); - - try - { - return readModelFromDatabase(connection, name, catalog, schema, tableTypes); - } - finally - { - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - public Database readModelFromDatabase(Connection connection, String name, String catalog, String schema, String[] tableTypes) throws DatabaseOperationException - { - try - { - JdbcModelReader reader = getModelReader(); - Database model = reader.getDatabase(connection, name, catalog, schema, tableTypes); - - postprocessModelFromDatabase(model); - if ((model.getName() == null) || (model.getName().length() == 0)) - { - model.setName(MODEL_DEFAULT_NAME); - } - return model; - } - catch (SQLException ex) - { - throw new DatabaseOperationException(ex); - } - } - - public Table readTableFromDatabase(Connection connection, String catalogName, - String schemaName, String tablename) throws SQLException { - return postprocessTableFromDatabase(_modelReader.readTable(connection, catalogName, schemaName, tablename)); - } - - /* - * Allows the platform to postprocess the model just read from the database. - * - * @param model The model - */ - protected void postprocessModelFromDatabase(Database model) - { - // Default values for CHAR/VARCHAR/LONGVARCHAR columns have quotation marks - // around them which we'll remove now - for (int tableIdx = 0; tableIdx < model.getTableCount(); tableIdx++) - { - postprocessTableFromDatabase(model.getTable(tableIdx)); - } - } - - protected Table postprocessTableFromDatabase(Table table) { - if (table != null) { - for (int columnIdx = 0; columnIdx < table.getColumnCount(); columnIdx++) { - Column column = table.getColumn(columnIdx); - - if (TypeMap.isTextType(column.getTypeCode()) - || TypeMap.isDateTimeType(column.getTypeCode())) { - String defaultValue = column.getDefaultValue(); - - if ((defaultValue != null) && (defaultValue.length() >= 2) - && defaultValue.startsWith("'") && defaultValue.endsWith("'")) { - defaultValue = defaultValue.substring(1, defaultValue.length() - 1); - column.setDefaultValue(defaultValue); - } - } - } - } - return table; - } - - /* - * This is the core method to set the parameter of a prepared statement to a given value. - * The primary purpose of this method is to call the appropriate method on the statement, - * and to give database-specific implementations the ability to change this behavior. - * - * @param statement The statement - * @param sqlIndex The parameter index - * @param typeCode The JDBC type code - * @param value The value - * @throws SQLException If an error occurred while setting the parameter value - */ - protected void setStatementParameterValue(PreparedStatement statement, int sqlIndex, int typeCode, Object value) throws SQLException - { - if (value == null) - { - statement.setNull(sqlIndex, typeCode); - } - else if (value instanceof String) - { - statement.setString(sqlIndex, (String)value); - } - else if (value instanceof byte[]) - { - statement.setBytes(sqlIndex, (byte[])value); - } - else if (value instanceof Boolean) - { - statement.setBoolean(sqlIndex, ((Boolean)value).booleanValue()); - } - else if (value instanceof Byte) - { - statement.setByte(sqlIndex, ((Byte)value).byteValue()); - } - else if (value instanceof Short) - { - statement.setShort(sqlIndex, ((Short)value).shortValue()); - } - else if (value instanceof Integer) - { - statement.setInt(sqlIndex, ((Integer)value).intValue()); - } - else if (value instanceof Long) - { - statement.setLong(sqlIndex, ((Long)value).longValue()); - } - else if (value instanceof BigDecimal) - { - // setObject assumes a scale of 0, so we rather use the typed setter - statement.setBigDecimal(sqlIndex, (BigDecimal)value); - } - else if (value instanceof Float) - { - statement.setFloat(sqlIndex, ((Float)value).floatValue()); - } - else if (value instanceof Double) - { - statement.setDouble(sqlIndex, ((Double)value).doubleValue()); - } - else - { - statement.setObject(sqlIndex, value, typeCode); - } - } - - /* - * Helper method esp. for the {@link ModelBasedResultSetIterator} class that retrieves - * the value for a column from the given result set. If a table was specified, - * and it contains the column, then the jdbc type defined for the column is used for extracting - * the value, otherwise the object directly retrieved from the result set is returned.
- * The method is defined here rather than in the {@link ModelBasedResultSetIterator} class - * so that concrete platforms can modify its behavior. - * - * @param resultSet The result set - * @param columnName The name of the column - * @param table The table - * @return The value - */ - protected Object getObjectFromResultSet(ResultSet resultSet, String columnName, Table table) throws SQLException - { - Column column = (table == null ? null : table.findColumn(columnName, isDelimitedIdentifierModeOn())); - Object value = null; - - if (column != null) - { - int originalJdbcType = column.getTypeCode(); - int targetJdbcType = getPlatformInfo().getTargetJdbcType(originalJdbcType); - int jdbcType = originalJdbcType; - - // in general we're trying to retrieve the value using the original type - // but sometimes we also need the target type: - if ((originalJdbcType == Types.BLOB) && (targetJdbcType != Types.BLOB)) - { - // we should not use the Blob interface if the database doesn't map to this type - jdbcType = targetJdbcType; - } - if ((originalJdbcType == Types.CLOB) && (targetJdbcType != Types.CLOB)) - { - // we should not use the Clob interface if the database doesn't map to this type - jdbcType = targetJdbcType; - } - value = extractColumnValue(resultSet, columnName, 0, jdbcType); - } - else - { - value = resultSet.getObject(columnName); - } - return resultSet.wasNull() ? null : value; - } - - /* - * Helper method for retrieving the value for a column from the given result set - * using the type code of the column. - * - * @param resultSet The result set - * @param column The column - * @param idx The value's index in the result set (starting from 1) - * @return The value - */ - protected Object getObjectFromResultSet(ResultSet resultSet, Column column, int idx) throws SQLException - { - int originalJdbcType = column.getTypeCode(); - int targetJdbcType = getPlatformInfo().getTargetJdbcType(originalJdbcType); - int jdbcType = originalJdbcType; - Object value = null; - - // in general we're trying to retrieve the value using the original type - // but sometimes we also need the target type: - if ((originalJdbcType == Types.BLOB) && (targetJdbcType != Types.BLOB)) - { - // we should not use the Blob interface if the database doesn't map to this type - jdbcType = targetJdbcType; - } - if ((originalJdbcType == Types.CLOB) && (targetJdbcType != Types.CLOB)) - { - // we should not use the Clob interface if the database doesn't map to this type - jdbcType = targetJdbcType; - } - value = extractColumnValue(resultSet, null, idx, jdbcType); - return resultSet.wasNull() ? null : value; - } - - /* - * This is the core method to retrieve a value for a column from a result set. Its primary - * purpose is to call the appropriate method on the result set, and to provide an extension - * point where database-specific implementations can change this behavior. - * - * @param resultSet The result set to extract the value from - * @param columnName The name of the column; can be null in which case the - * columnIdx will be used instead - * @param columnIdx The index of the column's value in the result set; is only used if - * columnName is null - * @param jdbcType The jdbc type to extract - * @return The value - * @throws SQLException If an error occurred while accessing the result set - */ - protected Object extractColumnValue(ResultSet resultSet, String columnName, int columnIdx, int jdbcType) throws SQLException - { - boolean useIdx = (columnName == null); - Object value; - - switch (jdbcType) - { - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - value = useIdx ? resultSet.getString(columnIdx) : resultSet.getString(columnName); - break; - case Types.NUMERIC: - case Types.DECIMAL: - value = useIdx ? resultSet.getBigDecimal(columnIdx) : resultSet.getBigDecimal(columnName); - break; - case Types.BIT: - value = new Boolean(useIdx ? resultSet.getBoolean(columnIdx) : resultSet.getBoolean(columnName)); - break; - case Types.TINYINT: - case Types.SMALLINT: - case Types.INTEGER: - value = new Integer(useIdx ? resultSet.getInt(columnIdx) : resultSet.getInt(columnName)); - break; - case Types.BIGINT: - value = new Long(useIdx ? resultSet.getLong(columnIdx) : resultSet.getLong(columnName)); - break; - case Types.REAL: - value = new Float(useIdx ? resultSet.getFloat(columnIdx) : resultSet.getFloat(columnName)); - break; - case Types.FLOAT: - case Types.DOUBLE: - value = new Double(useIdx ? resultSet.getDouble(columnIdx) : resultSet.getDouble(columnName)); - break; - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - value = useIdx ? resultSet.getBytes(columnIdx) : resultSet.getBytes(columnName); - break; - case Types.DATE: - value = useIdx ? resultSet.getDate(columnIdx) : resultSet.getDate(columnName); - break; - case Types.TIME: - value = useIdx ? resultSet.getTime(columnIdx) : resultSet.getTime(columnName); - break; - case Types.TIMESTAMP: - value = useIdx ? resultSet.getTimestamp(columnIdx) : resultSet.getTimestamp(columnName); - break; - case Types.CLOB: - Clob clob = useIdx ? resultSet.getClob(columnIdx) : resultSet.getClob(columnName); - - if (clob == null) - { - value = null; - } - else - { - long length = clob.length(); - - if (length > Integer.MAX_VALUE) - { - value = clob; - } - else if (length == 0) - { - // the javadoc is not clear about whether Clob.getSubString - // can be used with a substring length of 0 - // thus we do the safe thing and handle it ourselves - value = ""; - } - else - { - value = clob.getSubString(1l, (int)length); - } - } - break; - case Types.BLOB: - Blob blob = useIdx ? resultSet.getBlob(columnIdx) : resultSet.getBlob(columnName); - - if (blob == null) - { - value = null; - } - else - { - long length = blob.length(); - - if (length > Integer.MAX_VALUE) - { - value = blob; - } - else if (length == 0) - { - // the javadoc is not clear about whether Blob.getBytes - // can be used with for 0 bytes to be copied - // thus we do the safe thing and handle it ourselves - value = new byte[0]; - } - else - { - value = blob.getBytes(1l, (int)length); - } - } - break; - case Types.ARRAY: - value = useIdx ? resultSet.getArray(columnIdx) : resultSet.getArray(columnName); - break; - case Types.REF: - value = useIdx ? resultSet.getRef(columnIdx) : resultSet.getRef(columnName); - break; - default: - // special handling for Java 1.4/JDBC 3 types - if (Jdbc3Utils.supportsJava14JdbcTypes() && - (jdbcType == Jdbc3Utils.determineBooleanTypeCode())) - { - value = new Boolean(useIdx ? resultSet.getBoolean(columnIdx) : resultSet.getBoolean(columnName)); - } - else - { - value = useIdx ? resultSet.getObject(columnIdx) : resultSet.getObject(columnName); - } - break; - } - return resultSet.wasNull() ? null : value; - } - -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/SqlBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/SqlBuilder.java deleted file mode 100644 index eb2469b052..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/SqlBuilder.java +++ /dev/null @@ -1,2783 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.io.Writer; -import java.rmi.server.UID; -import java.sql.Types; -import java.text.DateFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.collections.Closure; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.Predicate; -import org.apache.commons.collections.map.ListOrderedMap; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddForeignKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddIndexChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddTableChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnAutoIncrementChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDataTypeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDefaultValueChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnRequiredChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnSizeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ModelChange; -import org.jumpmind.symmetric.db.ddl.alteration.ModelComparator; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveForeignKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveIndexChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveTableChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.IndexColumn; -import org.jumpmind.symmetric.db.ddl.model.ModelException; -import org.jumpmind.symmetric.db.ddl.model.Reference; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.util.CallbackClosure; -import org.jumpmind.symmetric.db.ddl.util.MultiInstanceofPredicate; - -/** - * This class is a collection of Strategy methods for creating the DDL required to create and drop - * databases and tables. - * - * It is hoped that just a single implementation of this class, for each database should make creating DDL - * for each physical database fairly straightforward. - * - * An implementation of this class can always delegate down to some templating technology such as Velocity if - * it requires. Though often that can be quite complex when attempting to reuse code across many databases. - * Hopefully only a small amount code needs to be changed on a per database basis. - * - * @version $Revision: 518498 $ - */ -public abstract class SqlBuilder -{ - /** The line separator for in between sql commands. */ - private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n"); - /** The placeholder for the size value in the native type spec. */ - protected static final String SIZE_PLACEHOLDER = "{0}"; - - /** The Log to which logging calls will be made. */ - protected final Log _log = LogFactory.getLog(SqlBuilder.class); - - /** The platform that this builder belongs to. */ - private Platform _platform; - /** The current Writer used to output the SQL to. */ - private Writer _writer; - /** The indentation used to indent commands. */ - private String _indent = " "; - /** An optional locale specification for number and date formatting. */ - private String _valueLocale; - /** The date formatter. */ - private DateFormat _valueDateFormat; - /** The date time formatter. */ - private DateFormat _valueTimeFormat; - /** The number formatter. */ - private NumberFormat _valueNumberFormat; - /** Helper object for dealing with default values. */ - private DefaultValueHelper _defaultValueHelper = new DefaultValueHelper(); - /** The character sequences that need escaping. */ - private Map _charSequencesToEscape = new ListOrderedMap(); - - // - // Configuration - // - - /** - * Creates a new sql builder. - * - * @param platform The plaftform this builder belongs to - */ - public SqlBuilder(Platform platform) - { - _platform = platform; - } - - /** - * Returns the platform object. - * - * @return The platform - */ - public Platform getPlatform() - { - return _platform; - } - - /** - * Returns the platform info object. - * - * @return The info object - */ - public PlatformInfo getPlatformInfo() - { - return _platform.getPlatformInfo(); - } - - /** - * Returns the writer that the DDL is printed to. - * - * @return The writer - */ - public Writer getWriter() - { - return _writer; - } - - /** - * Sets the writer for printing the DDL to. - * - * @param writer The writer - */ - public void setWriter(Writer writer) - { - _writer = writer; - } - - /** - * Returns the default value helper. - * - * @return The default value helper - */ - public DefaultValueHelper getDefaultValueHelper() - { - return _defaultValueHelper; - } - - /** - * Returns the string used to indent the SQL. - * - * @return The indentation string - */ - public String getIndent() - { - return _indent; - } - - /** - * Sets the string used to indent the SQL. - * - * @param indent The indentation string - */ - public void setIndent(String indent) - { - _indent = indent; - } - - /** - * Returns the locale that is used for number and date formatting - * (when printing default values and in generates insert/update/delete - * statements). - * - * @return The locale or null if default formatting is used - */ - public String getValueLocale() - { - return _valueLocale; - } - - /** - * Sets the locale that is used for number and date formatting - * (when printing default values and in generates insert/update/delete - * statements). - * - * @param localeStr The new locale or null if default formatting - * should be used; Format is "language[_country[_variant]]" - */ - public void setValueLocale(String localeStr) - { - if (localeStr != null) - { - int sepPos = localeStr.indexOf('_'); - String language = null; - String country = null; - String variant = null; - - if (sepPos > 0) - { - language = localeStr.substring(0, sepPos); - country = localeStr.substring(sepPos + 1); - sepPos = country.indexOf('_'); - if (sepPos > 0) - { - variant = country.substring(sepPos + 1); - country = country.substring(0, sepPos); - } - } - else - { - language = localeStr; - } - if (language != null) - { - Locale locale = null; - - if (variant != null) - { - locale = new Locale(language, country, variant); - } - else if (country != null) - { - locale = new Locale(language, country); - } - else - { - locale = new Locale(language); - } - - _valueLocale = localeStr; - setValueDateFormat(DateFormat.getDateInstance(DateFormat.SHORT, locale)); - setValueTimeFormat(DateFormat.getTimeInstance(DateFormat.SHORT, locale)); - setValueNumberFormat(NumberFormat.getNumberInstance(locale)); - return; - } - } - _valueLocale = null; - setValueDateFormat(null); - setValueTimeFormat(null); - setValueNumberFormat(null); - } - - /** - * Returns the format object for formatting dates in the specified locale. - * - * @return The date format object or null if no locale is set - */ - protected DateFormat getValueDateFormat() - { - return _valueDateFormat; - } - - /** - * Sets the format object for formatting dates in the specified locale. - * - * @param format The date format object - */ - protected void setValueDateFormat(DateFormat format) - { - _valueDateFormat = format; - } - - /** - * Returns the format object for formatting times in the specified locale. - * - * @return The time format object or null if no locale is set - */ - protected DateFormat getValueTimeFormat() - { - return _valueTimeFormat; - } - - /** - * Sets the date format object for formatting times in the specified locale. - * - * @param format The time format object - */ - protected void setValueTimeFormat(DateFormat format) - { - _valueTimeFormat = format; - } - - /** - * Returns the format object for formatting numbers in the specified locale. - * - * @return The number format object or null if no locale is set - */ - protected NumberFormat getValueNumberFormat() - { - return _valueNumberFormat; - } - - /** - * Returns a new date format object for formatting numbers in the specified locale. - * Platforms can override this if necessary. - * - * @param format The number format object - */ - protected void setValueNumberFormat(NumberFormat format) - { - _valueNumberFormat = format; - } - - /** - * Adds a char sequence that needs escaping, and its escaped version. - * - * @param charSequence The char sequence - * @param escapedVersion The escaped version - */ - protected void addEscapedCharSequence(String charSequence, String escapedVersion) - { - _charSequencesToEscape.put(charSequence, escapedVersion); - } - - /** - * Returns the maximum number of characters that a table name can have. - * This method is intended to give platform specific builder implementations - * more control over the maximum length. - * - * @return The number of characters, or -1 if not limited - */ - public int getMaxTableNameLength() - { - return getPlatformInfo().getMaxTableNameLength(); - } - - /** - * Returns the maximum number of characters that a column name can have. - * This method is intended to give platform specific builder implementations - * more control over the maximum length. - * - * @return The number of characters, or -1 if not limited - */ - public int getMaxColumnNameLength() - { - return getPlatformInfo().getMaxColumnNameLength(); - } - - /** - * Returns the maximum number of characters that a constraint name can have. - * This method is intended to give platform specific builder implementations - * more control over the maximum length. - * - * @return The number of characters, or -1 if not limited - */ - public int getMaxConstraintNameLength() - { - return getPlatformInfo().getMaxConstraintNameLength(); - } - - /** - * Returns the maximum number of characters that a foreign key name can have. - * This method is intended to give platform specific builder implementations - * more control over the maximum length. - * - * @return The number of characters, or -1 if not limited - */ - public int getMaxForeignKeyNameLength() - { - return getPlatformInfo().getMaxForeignKeyNameLength(); - } - - // - // public interface - // - - /** - * Outputs the DDL required to drop and (re)create all tables in the database model. - * - * @param database The database model - */ - public void createTables(Database database) throws IOException - { - createTables(database, null, true); - } - - /** - * Outputs the DDL required to drop (if requested) and (re)create all tables in the database model. - * - * @param database The database - * @param dropTables Whether to drop tables before creating them - */ - public void createTables(Database database, boolean dropTables) throws IOException - { - createTables(database, null, dropTables); - } - - /** - * Outputs the DDL required to drop (if requested) and (re)create all tables in the database model. - * - * @param database The database - * @param params The parameters used in the creation - * @param dropTables Whether to drop tables before creating them - */ - public void createTables(Database database, CreationParameters params, boolean dropTables) throws IOException - { - if (dropTables) - { - dropTables(database); - } - - for (int idx = 0; idx < database.getTableCount(); idx++) - { - Table table = database.getTable(idx); - - writeTableComment(table); - createTable(database, - table, - params == null ? null : params.getParametersFor(table)); - } - - // we're writing the external foreignkeys last to ensure that all referenced tables are already defined - createExternalForeignKeys(database); - } - - /** - * Generates the DDL to modify an existing database so the schema matches - * the specified database schema by using drops, modifications and additions. - * Database-specific implementations can change aspect of this algorithm by - * redefining the individual methods that compromise it. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - */ - public void alterDatabase(Database currentModel, Database desiredModel, CreationParameters params) throws IOException - { - ModelComparator comparator = new ModelComparator(getPlatformInfo(), - getPlatform().isDelimitedIdentifierModeOn()); - List changes = comparator.compare(currentModel, desiredModel); - - processChanges(currentModel, desiredModel, changes, params); - } - - public boolean isAlterDatabase(Database currentModel, Database desiredModel, CreationParameters params) throws IOException - { - ModelComparator comparator = new ModelComparator(getPlatformInfo(), - getPlatform().isDelimitedIdentifierModeOn()); - List changes = comparator.compare(currentModel, desiredModel); - - return changes.size() > 0; - } - - /** - * Calls the given closure for all changes that are of one of the given types, and - * then removes them from the changes collection. - * - * @param changes The changes - * @param changeTypes The types to search for - * @param closure The closure to invoke - */ - protected void applyForSelectedChanges(Collection changes, Class[] changeTypes, final Closure closure) - { - final Predicate predicate = new MultiInstanceofPredicate(changeTypes); - - // basically we filter the changes for all objects where the above predicate - // returns true, and for these filtered objects we invoke the given closure - CollectionUtils.filter(changes, - new Predicate() - { - public boolean evaluate(Object obj) - { - if (predicate.evaluate(obj)) - { - closure.execute(obj); - return false; - } - else - { - return true; - } - } - }); - } - - /** - * Processes the changes. The default argument performs several passes: - *
    - *
  1. {@link org.jumpmind.symmetric.db.ddl.alteration.RemoveForeignKeyChange} and - * {@link org.jumpmind.symmetric.db.ddl.alteration.RemoveIndexChange} come first - * to allow for e.g. subsequent primary key changes or column removal.
  2. - *
  3. {@link org.jumpmind.symmetric.db.ddl.alteration.RemoveTableChange} - * comes after the removal of foreign keys and indices.
  4. - *
  5. These are all handled together:
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.ColumnAutoIncrementChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.ColumnDefaultValueChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.ColumnRequiredChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.ColumnDataTypeChange}
    - * {@link org.jumpmind.symmetric.db.ddl.alteration.ColumnSizeChange}
    - * The reason for this is that the default algorithm rebuilds the table for these - * changes and thus their order is irrelevant.
  6. - *
  7. {@link org.jumpmind.symmetric.db.ddl.alteration.AddTableChange}
    - * needs to come after the table removal (so that tables of the same name are - * removed) and before the addition of foreign keys etc.
  8. - *
  9. {@link org.jumpmind.symmetric.db.ddl.alteration.AddForeignKeyChange} and - * {@link org.jumpmind.symmetric.db.ddl.alteration.AddIndexChange} come last - * after table/column/primary key additions or changes.
  10. - *
- * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param changes The changes - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - */ - protected void processChanges(Database currentModel, - Database desiredModel, - List changes, - CreationParameters params) throws IOException - { - CallbackClosure callbackClosure = new CallbackClosure(this, - "processChange", - new Class[] { Database.class, Database.class, CreationParameters.class, null }, - new Object[] { currentModel, desiredModel, params, null }); - - // 1st pass: removing external constraints and indices - applyForSelectedChanges(changes, - new Class[] { RemoveForeignKeyChange.class, - RemoveIndexChange.class }, - callbackClosure); - - // 2nd pass: removing tables - applyForSelectedChanges(changes, - new Class[] { RemoveTableChange.class }, - callbackClosure); - - // 3rd pass: changing the structure of tables - Predicate predicate = new MultiInstanceofPredicate(new Class[] { RemovePrimaryKeyChange.class, - AddPrimaryKeyChange.class, - PrimaryKeyChange.class, - RemoveColumnChange.class, - AddColumnChange.class, - ColumnAutoIncrementChange.class, - ColumnDefaultValueChange.class, - ColumnRequiredChange.class, - ColumnDataTypeChange.class, - ColumnSizeChange.class }); - - processTableStructureChanges(currentModel, - desiredModel, - params, - CollectionUtils.select(changes, predicate)); - - // 4th pass: adding tables - applyForSelectedChanges(changes, - new Class[] { AddTableChange.class }, - callbackClosure); - // 5th pass: adding external constraints and indices - applyForSelectedChanges(changes, - new Class[] { AddForeignKeyChange.class, - AddIndexChange.class }, - callbackClosure); - } - - /** - * This is a fall-through callback which generates a warning because a specific - * change type wasn't handled. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - CreationParameters params, - ModelChange change) throws IOException - { - _log.warn("Change of type " + change.getClass() + " was not handled"); - } - - /** - * Processes the change representing the removal of a foreign key. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - CreationParameters params, - RemoveForeignKeyChange change) throws IOException - { - writeExternalForeignKeyDropStmt(change.getChangedTable(), change.getForeignKey()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /** - * Processes the change representing the removal of an index. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - CreationParameters params, - RemoveIndexChange change) throws IOException - { - writeExternalIndexDropStmt(change.getChangedTable(), change.getIndex()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /** - * Processes the change representing the removal of a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - CreationParameters params, - RemoveTableChange change) throws IOException - { - dropTable(change.getChangedTable()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /** - * Processes the change representing the addition of a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - CreationParameters params, - AddTableChange change) throws IOException - { - createTable(desiredModel, change.getNewTable(), params == null ? null : params.getParametersFor(change.getNewTable())); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /** - * Processes the change representing the addition of a foreign key. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - CreationParameters params, - AddForeignKeyChange change) throws IOException - { - writeExternalForeignKeyCreateStmt(desiredModel, - change.getChangedTable(), - change.getNewForeignKey()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /** - * Processes the change representing the addition of an index. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - CreationParameters params, - AddIndexChange change) throws IOException - { - writeExternalIndexCreateStmt(change.getChangedTable(), change.getNewIndex()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /** - * Processes the changes to the structure of tables. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param params The parameters used in the creation of new tables. Note that for existing - * tables, the parameters won't be applied - * @param changes The change objects - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - CreationParameters params, - Collection changes) throws IOException - { - ListOrderedMap changesPerTable = new ListOrderedMap(); - ListOrderedMap unchangedFKs = new ListOrderedMap(); - boolean caseSensitive = getPlatform().isDelimitedIdentifierModeOn(); - - // we first sort the changes for the tables - // however since the changes might contain source or target tables - // we use the names rather than the table objects - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = changeIt.next(); - String name = change.getChangedTable().getName(); - - if (!caseSensitive) - { - name = name.toUpperCase(); - } - - List changesForTable = (List)changesPerTable.get(name); - - if (changesForTable == null) - { - changesForTable = new ArrayList(); - changesPerTable.put(name, changesForTable); - unchangedFKs.put(name, getUnchangedForeignKeys(currentModel, desiredModel, name)); - } - changesForTable.add(change); - } - // we also need to drop the foreign keys of the unchanged tables referencing the changed tables - addRelevantFKsFromUnchangedTables(currentModel, desiredModel, changesPerTable.keySet(), unchangedFKs); - - // we're dropping the unchanged foreign keys - for (Iterator tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext();) - { - Map.Entry entry = (Map.Entry)tableFKIt.next(); - Table targetTable = desiredModel.findTable((String)entry.getKey(), caseSensitive); - - for (Iterator fkIt = ((List)entry.getValue()).iterator(); fkIt.hasNext();) - { - writeExternalForeignKeyDropStmt(targetTable, (ForeignKey)fkIt.next()); - } - } - - // We're using a copy of the current model so that the table structure changes can - // modify it - Database copyOfCurrentModel = null; - - try - { - copyOfCurrentModel = (Database)currentModel.clone(); - } - catch (CloneNotSupportedException ex) - { - throw new DdlUtilsException(ex); - } - - for (Iterator tableChangeIt = changesPerTable.entrySet().iterator(); tableChangeIt.hasNext();) - { - Map.Entry entry = (Map.Entry)tableChangeIt.next(); - Table targetTable = desiredModel.findTable((String)entry.getKey(), caseSensitive); - - processTableStructureChanges(copyOfCurrentModel, - desiredModel, - (String)entry.getKey(), - params == null ? null : params.getParametersFor(targetTable), - (List)entry.getValue()); - } - // and finally we're re-creating the unchanged foreign keys - for (Iterator tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext();) - { - Map.Entry entry = (Map.Entry)tableFKIt.next(); - Table targetTable = desiredModel.findTable((String)entry.getKey(), caseSensitive); - - for (Iterator fkIt = ((List)entry.getValue()).iterator(); fkIt.hasNext();) - { - writeExternalForeignKeyCreateStmt(desiredModel, targetTable, (ForeignKey)fkIt.next()); - } - } - } - - /** - * Determines the unchanged foreign keys of the indicated table. - * - * @param currentModel The current model - * @param desiredModel The desired model - * @param tableName The name of the table - * @return The list of unchanged foreign keys - */ - private List getUnchangedForeignKeys(Database currentModel, - Database desiredModel, - String tableName) - { - ArrayList unchangedFKs = new ArrayList(); - boolean caseSensitive = getPlatform().isDelimitedIdentifierModeOn(); - Table sourceTable = currentModel.findTable(tableName, caseSensitive); - Table targetTable = desiredModel.findTable(tableName, caseSensitive); - - for (int idx = 0; idx < targetTable.getForeignKeyCount(); idx++) - { - ForeignKey targetFK = targetTable.getForeignKey(idx); - ForeignKey sourceFK = sourceTable.findForeignKey(targetFK, caseSensitive); - - if (sourceFK != null) - { - unchangedFKs.add(targetFK); - } - } - return unchangedFKs; - } - - /** - * Adds the foreign keys of the unchanged tables that reference changed tables - * to the given map. - * - * @param currentModel The current model - * @param desiredModel The desired model - * @param namesOfKnownChangedTables The known names of changed tables - * @param fksPerTable The map table name -> foreign keys to which - * found foreign keys will be added to - */ - private void addRelevantFKsFromUnchangedTables(Database currentModel, - Database desiredModel, - Set namesOfKnownChangedTables, - Map fksPerTable) - { - boolean caseSensitive = getPlatform().isDelimitedIdentifierModeOn(); - - for (int tableIdx = 0; tableIdx < desiredModel.getTableCount(); tableIdx++) - { - Table targetTable = desiredModel.getTable(tableIdx); - String name = targetTable.getName(); - Table sourceTable = currentModel.findTable(name, caseSensitive); - List relevantFks = null; - - if (!caseSensitive) - { - name = name.toUpperCase(); - } - if ((sourceTable != null) && !namesOfKnownChangedTables.contains(name)) - { - for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++) - { - ForeignKey targetFk = targetTable.getForeignKey(fkIdx); - ForeignKey sourceFk = sourceTable.findForeignKey(targetFk, caseSensitive); - String refName = targetFk.getForeignTableName(); - - if (!caseSensitive) - { - refName = refName.toUpperCase(); - } - if ((sourceFk != null) && namesOfKnownChangedTables.contains(refName)) - { - if (relevantFks == null) - { - relevantFks = new ArrayList(); - fksPerTable.put(name, relevantFks); - } - relevantFks.add(targetFk); - } - } - } - } - } - - /** - * Processes the changes to the structure of a single table. Database-specific - * implementations might redefine this method, but it is usually sufficient to - * redefine the {@link #processTableStructureChanges(Database, Database, Table, Table, Map, List)} - * method instead. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param tableName The name of the changed table - * @param parameters The creation parameters for the desired table - * @param changes The change objects for this table - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - String tableName, - Map parameters, - List changes) throws IOException - { - Table sourceTable = currentModel.findTable(tableName, getPlatform().isDelimitedIdentifierModeOn()); - Table targetTable = desiredModel.findTable(tableName, getPlatform().isDelimitedIdentifierModeOn()); - - // we're enforcing a full rebuild in case of the addition of a required - // column without a default value that is not autoincrement - boolean requiresFullRebuild = false; - - for (Iterator changeIt = changes.iterator(); !requiresFullRebuild && changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; - - if (addColumnChange.getNewColumn().isRequired() && - (addColumnChange.getNewColumn().getDefaultValue() == null) && - !addColumnChange.getNewColumn().isAutoIncrement()) - { - requiresFullRebuild = true; - } - } - } - if (!requiresFullRebuild) - { - processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, parameters, changes); - } - - if (!changes.isEmpty()) - { - // we can only copy the data if no required columns without default value and - // non-autoincrement have been added - boolean canMigrateData = true; - - for (Iterator it = changes.iterator(); canMigrateData && it.hasNext();) - { - TableChange change = (TableChange)it.next(); - - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; - - if (addColumnChange.getNewColumn().isRequired() && - !addColumnChange.getNewColumn().isAutoIncrement() && - (addColumnChange.getNewColumn().getDefaultValue() == null)) - { - _log.warn("Data cannot be retained in table " + change.getChangedTable().getName() + - " because of the addition of the required column " + addColumnChange.getNewColumn().getName()); - canMigrateData = false; - } - } - } - - Table realTargetTable = getRealTargetTableFor(desiredModel, sourceTable, targetTable); - - if (canMigrateData) - { - Table tempTable = getTemporaryTableFor(desiredModel, targetTable); - - createTemporaryTable(desiredModel, tempTable, parameters); - writeCopyDataStatement(sourceTable, tempTable); - // Note that we don't drop the indices here because the DROP TABLE will take care of that - // Likewise, foreign keys have already been dropped as necessary - dropTable(sourceTable); - createTable(desiredModel, realTargetTable, parameters); - writeCopyDataStatement(tempTable, targetTable); - dropTemporaryTable(desiredModel, tempTable); - writeFixLastIdentityValues(targetTable); - } - else - { - dropTable(sourceTable); - createTable(desiredModel, realTargetTable, parameters); - } - } - } - - /** - * Allows database-specific implementations to handle changes in a database - * specific manner. Any handled change should be applied to the given current - * model (which is a copy of the real original model) and be removed from the - * list of changes.
- * In the default implementation, all {@link AddPrimaryKeyChange} changes are - * applied via an ALTER TABLE ADD CONSTRAINT statement. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param sourceTable The original table - * @param targetTable The desired table - * @param parameters The creation parameters for the table - * @param changes The change objects for the target table - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { - if (changes.size() == 1) - { - TableChange change = (TableChange)changes.get(0); - - if (change instanceof AddPrimaryKeyChange) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); - changes.clear(); - } - } - } - - /** - * Creates a temporary table object that corresponds to the given table. - * Database-specific implementations may redefine this method if e.g. the - * database directly supports temporary tables. The default implementation - * simply appends an underscore to the table name and uses that as the - * table name. - * - * @param targetModel The target database - * @param targetTable The target table - * @return The temporary table - */ - protected Table getTemporaryTableFor(Database targetModel, Table targetTable) throws IOException - { - return getTemporaryTableFor(targetModel, targetTable, "_"); - } - - public Table getBackupTableFor(Database model, Table sourceTable) throws IOException - { - return getTemporaryTableFor(model, sourceTable, "x"); - } - - public Table createBackupTableFor(Database model, Table sourceTable) throws IOException - { - Table backupTable = getBackupTableFor(model, sourceTable); - writeTableCreationStmt(model, backupTable, null); - printEndOfStatement(); - writeCopyDataStatement(sourceTable, backupTable); - return backupTable; - } - - public void restoreTableFromBackup(Table backupTable, Table targetTable, ListOrderedMap columnMap) throws IOException - { - print("DELETE FROM "); - printIdentifier(getTableName(targetTable)); - printEndOfStatement(); - writeCopyDataStatement(backupTable, targetTable, columnMap); - } - - protected Table getTemporaryTableFor(Database targetModel, Table targetTable, String suffix) throws IOException - { - Table table = new Table(); - - table.setCatalog(targetTable.getCatalog()); - table.setSchema(targetTable.getSchema()); - table.setName(targetTable.getName() + suffix); - table.setType(targetTable.getType()); - for (int idx = 0; idx < targetTable.getColumnCount(); idx++) - { - try - { - table.addColumn((Column)targetTable.getColumn(idx).clone()); - } - catch (CloneNotSupportedException ex) - { - throw new DdlUtilsException(ex); - } - } - - return table; - } - - /** - * Outputs the DDL to create the given temporary table. Per default this is simply - * a call to {@link #createTable(Database, Table, Map)}. - * - * @param database The database model - * @param table The table - * @param parameters Additional platform-specific parameters for the table creation - */ - protected void createTemporaryTable(Database database, Table table, Map parameters) throws IOException - { - createTable(database, table, parameters); - } - - /** - * Outputs the DDL to drop the given temporary table. Per default this is simply - * a call to {@link #dropTable(Table)}. - * - * @param database The database model - * @param table The table - */ - protected void dropTemporaryTable(Database database, Table table) throws IOException - { - dropTable(table); - } - - /** - * Creates the target table object that differs from the given target table only in the - * indices. More specifically, only those indices are used that have not changed. - * - * @param targetModel The target database - * @param sourceTable The source table - * @param targetTable The target table - * @return The table - */ - protected Table getRealTargetTableFor(Database targetModel, Table sourceTable, Table targetTable) throws IOException - { - Table table = new Table(); - - table.setCatalog(targetTable.getCatalog()); - table.setSchema(targetTable.getSchema()); - table.setName(targetTable.getName()); - table.setType(targetTable.getType()); - for (int idx = 0; idx < targetTable.getColumnCount(); idx++) - { - try - { - table.addColumn((Column)targetTable.getColumn(idx).clone()); - } - catch (CloneNotSupportedException ex) - { - throw new DdlUtilsException(ex); - } - } - - boolean caseSensitive = getPlatform().isDelimitedIdentifierModeOn(); - - for (int idx = 0; idx < targetTable.getIndexCount(); idx++) - { - Index targetIndex = targetTable.getIndex(idx); - Index sourceIndex = sourceTable.findIndex(targetIndex.getName(), caseSensitive); - - if (sourceIndex != null) - { - if ((caseSensitive && sourceIndex.equals(targetIndex)) || - (!caseSensitive && sourceIndex.equalsIgnoreCase(targetIndex))) - { - table.addIndex(targetIndex); - } - } - } - - return table; - } - - /** - * Writes a statement that copies the data from the source to the target table. Note - * that this copies only those columns that are in both tables. - * Database-specific implementations might redefine this method though they usually - * it suffices to redefine the {@link #writeCastExpression(Column, Column)} method. - * - * @param sourceTable The source table - * @param targetTable The target table - */ - public void writeCopyDataStatement(Table sourceTable, Table targetTable) throws IOException - { - ListOrderedMap columnMap = getCopyDataColumnMapping(sourceTable, targetTable); - writeCopyDataStatement(sourceTable, targetTable, columnMap); - } - - public void writeCopyDataStatement(Table sourceTable, Table targetTable, ListOrderedMap columnMap) throws IOException - { - print("INSERT INTO "); - printIdentifier(getTableName(targetTable)); - print(" ("); - for (Iterator columnIt = columnMap.values().iterator(); columnIt.hasNext();) - { - printIdentifier(getColumnName((Column)columnIt.next())); - if (columnIt.hasNext()) - { - print(","); - } - } - print(") SELECT "); - for (Iterator columnsIt = columnMap.entrySet().iterator(); columnsIt.hasNext();) - { - Map.Entry entry = (Map.Entry)columnsIt.next(); - - writeCastExpression((Column)entry.getKey(), - (Column)entry.getValue()); - if (columnsIt.hasNext()) - { - print(","); - } - } - print(" FROM "); - printIdentifier(getTableName(sourceTable)); - printEndOfStatement(); - } - - public ListOrderedMap getCopyDataColumnMapping(Table sourceTable, Table targetTable) - { - ListOrderedMap columns = new ListOrderedMap(); - - for (int idx = 0; idx < sourceTable.getColumnCount(); idx++) - { - Column sourceColumn = sourceTable.getColumn(idx); - Column targetColumn = targetTable.findColumn(sourceColumn.getName(), - getPlatform().isDelimitedIdentifierModeOn()); - - - if (targetColumn != null) - { - columns.put(sourceColumn, targetColumn); - } - } - return columns; - } - - public ListOrderedMap getCopyDataColumnOrderedMapping(Table sourceTable, Table targetTable) - { - ListOrderedMap columns = new ListOrderedMap(); - - for (int idx = 0; idx < sourceTable.getColumnCount(); idx++) - { - columns.put(sourceTable.getColumn(idx), targetTable.getColumn(idx)); - } - return columns; - } - - /** - * Writes a cast expression that converts the value of the source column to the data type - * of the target column. Per default, simply the name of the source column is written - * thereby assuming that any casts happen implicitly. - * - * @param sourceColumn The source column - * @param targetColumn The target column - */ - protected void writeCastExpression(Column sourceColumn, Column targetColumn) throws IOException - { - printIdentifier(getColumnName(sourceColumn)); - } - - /** - * Processes the addition of a primary key to a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - AddPrimaryKeyChange change) throws IOException - { - writeExternalPrimaryKeysCreateStmt(change.getChangedTable(), change.getPrimaryKeyColumns()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /** - * Searches in the given table for a corresponding foreign key. If the given key - * has no name, then a foreign key to the same table with the same columns in the - * same order is searched. If the given key has a name, then the a corresponding - * key also needs to have the same name, or no name at all, but not a different one. - * - * @param table The table to search in - * @param fk The original foreign key - * @return The corresponding foreign key if found - */ - protected ForeignKey findCorrespondingForeignKey(Table table, ForeignKey fk) - { - boolean caseMatters = getPlatform().isDelimitedIdentifierModeOn(); - boolean checkFkName = (fk.getName() != null) && (fk.getName().length() > 0); - Reference[] refs = fk.getReferences(); - ArrayList curRefs = new ArrayList(); - - for (int fkIdx = 0; fkIdx < table.getForeignKeyCount(); fkIdx++) - { - ForeignKey curFk = table.getForeignKey(fkIdx); - boolean checkCurFkName = checkFkName && - (curFk.getName() != null) && (curFk.getName().length() > 0); - - if ((!checkCurFkName || areEqual(fk.getName(), curFk.getName(), caseMatters)) && - areEqual(fk.getForeignTableName(), curFk.getForeignTableName(), caseMatters)) - { - curRefs.clear(); - CollectionUtils.addAll(curRefs, curFk.getReferences()); - - // the order is not fixed, so we have to take this long way - if (curRefs.size() == refs.length) - { - for (int refIdx = 0; refIdx < refs.length; refIdx++) - { - boolean found = false; - - for (int curRefIdx = 0; !found && (curRefIdx < curRefs.size()); curRefIdx++) - { - Reference curRef = (Reference)curRefs.get(curRefIdx); - - if ((caseMatters && refs[refIdx].equals(curRef)) || - (!caseMatters && refs[refIdx].equalsIgnoreCase(curRef))) - { - curRefs.remove(curRefIdx); - found = true; - } - } - } - if (curRefs.isEmpty()) - { - return curFk; - } - } - } - } - return null; - } - - /** - * Compares the two strings. - * - * @param string1 The first string - * @param string2 The second string - * @param caseMatters Whether case matters in the comparison - * @return true if the string are equal - */ - protected boolean areEqual(String string1, String string2, boolean caseMatters) - { - return (caseMatters && string1.equals(string2)) || - (!caseMatters && string1.equalsIgnoreCase(string2)); - } - - /** - * Outputs the DDL to create the table along with any non-external constraints as well - * as with external primary keys and indices (but not foreign keys). - * - * @param database The database model - * @param table The table - */ - public void createTable(Database database, Table table) throws IOException - { - createTable(database, table, null); - } - - /** - * Outputs the DDL to create the table along with any non-external constraints as well - * as with external primary keys and indices (but not foreign keys). - * - * @param database The database model - * @param table The table - * @param parameters Additional platform-specific parameters for the table creation - */ - public void createTable(Database database, Table table, Map parameters) throws IOException - { - writeTableCreationStmt(database, table, parameters); - writeTableCreationStmtEnding(table, parameters); - - if (!getPlatformInfo().isPrimaryKeyEmbedded()) - { - writeExternalPrimaryKeysCreateStmt(table, table.getPrimaryKeyColumns()); - } - if (!getPlatformInfo().isIndicesEmbedded()) - { - writeExternalIndicesCreateStmt(table); - } - } - - /** - * Creates the external foreignkey creation statements for all tables in the database. - * - * @param database The database - */ - public void createExternalForeignKeys(Database database) throws IOException - { - for (int idx = 0; idx < database.getTableCount(); idx++) - { - createExternalForeignKeys(database, database.getTable(idx)); - } - } - - /** - * Creates external foreignkey creation statements if necessary. - * - * @param database The database model - * @param table The table - */ - public void createExternalForeignKeys(Database database, Table table) throws IOException - { - if (!getPlatformInfo().isForeignKeysEmbedded()) - { - for (int idx = 0; idx < table.getForeignKeyCount(); idx++) - { - writeExternalForeignKeyCreateStmt(database, table, table.getForeignKey(idx)); - } - } - } - - /** - * Outputs the DDL required to drop the database. - * - * @param database The database - */ - public void dropTables(Database database) throws IOException - { - // we're dropping the external foreignkeys first - for (int idx = database.getTableCount() - 1; idx >= 0; idx--) - { - Table table = database.getTable(idx); - - if ((table.getName() != null) && - (table.getName().length() > 0)) - { - dropExternalForeignKeys(table); - } - } - - // Next we drop the tables in reverse order to avoid referencial problems - // TODO: It might be more useful to either (or both) - // * determine an order in which the tables can be dropped safely (via the foreignkeys) - // * alter the tables first to drop the internal foreignkeys - for (int idx = database.getTableCount() - 1; idx >= 0; idx--) - { - Table table = database.getTable(idx); - - if ((table.getName() != null) && - (table.getName().length() > 0)) - { - writeTableComment(table); - dropTable(table); - } - } - } - - /** - * Outputs the DDL required to drop the given table. This method also - * drops foreign keys to the table. - * - * @param database The database - * @param table The table - */ - public void dropTable(Database database, Table table) throws IOException - { - // we're dropping the foreignkeys to the table first - for (int idx = database.getTableCount() - 1; idx >= 0; idx--) - { - Table otherTable = database.getTable(idx); - ForeignKey[] fks = otherTable.getForeignKeys(); - - for (int fkIdx = 0; (fks != null) && (fkIdx < fks.length); fkIdx++) - { - if (fks[fkIdx].getForeignTable().equals(table)) - { - writeExternalForeignKeyDropStmt(otherTable, fks[fkIdx]); - } - } - } - // and the foreign keys from the table - dropExternalForeignKeys(table); - - writeTableComment(table); - dropTable(table); - } - - /** - * Outputs the DDL to drop the table. Note that this method does not drop - * foreign keys to this table. Use {@link #dropTable(Database, Table)} - * if you want that. - * - * @param table The table to drop - */ - public void dropTable(Table table) throws IOException - { - print("DROP TABLE "); - printIdentifier(getTableName(table)); - printEndOfStatement(); - } - - /** - * Creates external foreignkey drop statements. - * - * @param table The table - */ - public void dropExternalForeignKeys(Table table) throws IOException - { - if (!getPlatformInfo().isForeignKeysEmbedded()) - { - for (int idx = 0; idx < table.getForeignKeyCount(); idx++) - { - writeExternalForeignKeyDropStmt(table, table.getForeignKey(idx)); - } - } - } - - /** - * Creates the SQL for inserting an object into the specified table. - * If values are given then a concrete insert statement is created, otherwise an - * insert statement usable in a prepared statement is build. - * - * @param table The table - * @param columnValues The columns values indexed by the column names - * @param genPlaceholders Whether to generate value placeholders for a - * prepared statement - * @return The insertion sql - */ - public String getInsertSql(Table table, Map columnValues, boolean genPlaceholders) - { - StringBuffer buffer = new StringBuffer("INSERT INTO "); - boolean addComma = false; - - buffer.append(getDelimitedIdentifier(getTableName(table))); - buffer.append(" ("); - - for (int idx = 0; idx < table.getColumnCount(); idx++) - { - Column column = table.getColumn(idx); - - if (columnValues.containsKey(column.getName())) - { - if (addComma) - { - buffer.append(", "); - } - buffer.append(getDelimitedIdentifier(column.getName())); - addComma = true; - } - } - buffer.append(") VALUES ("); - if (genPlaceholders) - { - addComma = false; - for (int idx = 0; idx < columnValues.size(); idx++) - { - if (addComma) - { - buffer.append(", "); - } - buffer.append("?"); - addComma = true; - } - } - else - { - addComma = false; - for (int idx = 0; idx < table.getColumnCount(); idx++) - { - Column column = table.getColumn(idx); - - if (columnValues.containsKey(column.getName())) - { - if (addComma) - { - buffer.append(", "); - } - buffer.append(getValueAsString(column, columnValues.get(column.getName()))); - addComma = true; - } - } - } - buffer.append(")"); - return buffer.toString(); - } - - /** - * Creates the SQL for updating an object in the specified table. - * If values are given then a concrete update statement is created, otherwise an - * update statement usable in a prepared statement is build. - * - * @param table The table - * @param columnValues Contains the values for the columns to update, and should also - * contain the primary key values to identify the object to update - * in case genPlaceholders is false - * @param genPlaceholders Whether to generate value placeholders for a - * prepared statement (both for the pk values and the object values) - * @return The update sql - */ - public String getUpdateSql(Table table, Map columnValues, boolean genPlaceholders) - { - StringBuffer buffer = new StringBuffer("UPDATE "); - boolean addSep = false; - - buffer.append(getDelimitedIdentifier(getTableName(table))); - buffer.append(" SET "); - - for (int idx = 0; idx < table.getColumnCount(); idx++) - { - Column column = table.getColumn(idx); - - if (!column.isPrimaryKey() && columnValues.containsKey(column.getName())) - { - if (addSep) - { - buffer.append(", "); - } - buffer.append(getDelimitedIdentifier(column.getName())); - buffer.append(" = "); - if (genPlaceholders) - { - buffer.append("?"); - } - else - { - buffer.append(getValueAsString(column, columnValues.get(column.getName()))); - } - addSep = true; - } - } - buffer.append(" WHERE "); - addSep = false; - for (int idx = 0; idx < table.getColumnCount(); idx++) - { - Column column = table.getColumn(idx); - - if (column.isPrimaryKey() && columnValues.containsKey(column.getName())) - { - if (addSep) - { - buffer.append(" AND "); - } - buffer.append(getDelimitedIdentifier(column.getName())); - buffer.append(" = "); - if (genPlaceholders) - { - buffer.append("?"); - } - else - { - buffer.append(getValueAsString(column, columnValues.get(column.getName()))); - } - addSep = true; - } - } - return buffer.toString(); - } - - /** - * Creates the SQL for deleting an object from the specified table. - * If values are given then a concrete delete statement is created, otherwise an - * delete statement usable in a prepared statement is build. - * - * @param table The table - * @param pkValues The primary key values indexed by the column names, can be empty - * @param genPlaceholders Whether to generate value placeholders for a - * prepared statement - * @return The delete sql - */ - public String getDeleteSql(Table table, Map pkValues, boolean genPlaceholders) - { - StringBuffer buffer = new StringBuffer("DELETE FROM "); - boolean addSep = false; - - buffer.append(getDelimitedIdentifier(getTableName(table))); - if ((pkValues != null) && !pkValues.isEmpty()) - { - buffer.append(" WHERE "); - for (Iterator it = pkValues.entrySet().iterator(); it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - Column column = table.findColumn((String)entry.getKey()); - - if (addSep) - { - buffer.append(" AND "); - } - buffer.append(getDelimitedIdentifier(entry.getKey().toString())); - buffer.append(" = "); - if (genPlaceholders) - { - buffer.append("?"); - } - else - { - buffer.append(column == null ? entry.getValue() : getValueAsString(column, entry.getValue())); - } - addSep = true; - } - } - return buffer.toString(); - } - - /** - * Generates the string representation of the given value. - * - * @param column The column - * @param value The value - * @return The string representation - */ - protected String getValueAsString(Column column, Object value) - { - if (value == null) - { - return "NULL"; - } - - StringBuffer result = new StringBuffer(); - - // TODO: Handle binary types (BINARY, VARBINARY, LONGVARBINARY, BLOB) - switch (column.getTypeCode()) - { - case Types.DATE: - result.append(getPlatformInfo().getValueQuoteToken()); - if (!(value instanceof String) && (getValueDateFormat() != null)) - { - // TODO: Can the format method handle java.sql.Date properly ? - result.append(getValueDateFormat().format(value)); - } - else - { - result.append(value.toString()); - } - result.append(getPlatformInfo().getValueQuoteToken()); - break; - case Types.TIME: - result.append(getPlatformInfo().getValueQuoteToken()); - if (!(value instanceof String) && (getValueTimeFormat() != null)) - { - // TODO: Can the format method handle java.sql.Date properly ? - result.append(getValueTimeFormat().format(value)); - } - else - { - result.append(value.toString()); - } - result.append(getPlatformInfo().getValueQuoteToken()); - break; - case Types.TIMESTAMP: - result.append(getPlatformInfo().getValueQuoteToken()); - // TODO: SimpleDateFormat does not support nano seconds so we would - // need a custom date formatter for timestamps - result.append(value.toString()); - result.append(getPlatformInfo().getValueQuoteToken()); - break; - case Types.REAL: - case Types.NUMERIC: - case Types.FLOAT: - case Types.DOUBLE: - case Types.DECIMAL: - result.append(getPlatformInfo().getValueQuoteToken()); - if (!(value instanceof String) && (getValueNumberFormat() != null)) - { - result.append(getValueNumberFormat().format(value)); - } - else - { - result.append(value.toString()); - } - result.append(getPlatformInfo().getValueQuoteToken()); - break; - default: - result.append(getPlatformInfo().getValueQuoteToken()); - result.append(escapeStringValue(value.toString())); - result.append(getPlatformInfo().getValueQuoteToken()); - break; - } - return result.toString(); - } - - /** - * Generates the SQL for querying the id that was created in the last insertion - * operation. This is obviously only useful for pk fields that are auto-incrementing. - * A database that does not support this, will return null. - * - * @param table The table - * @return The sql, or null if the database does not support this - */ - public String getSelectLastIdentityValues(Table table) - { - // No default possible as the databases are quite different in this respect - return null; - } - - /** - * Generates the SQL to execute that sets the current sequence number. - * - * @param table - * @param id - * @return - */ - public String fixLastIdentityValues(Table table) - { - return null; - } - - public void writeFixLastIdentityValues(Table table) throws IOException - { - String sql = fixLastIdentityValues(table); - if (sql != null) { - print(sql); - printEndOfStatement(); - } - } - - // - // implementation methods that may be overridden by specific database builders - // - - /** - * Generates a version of the name that has at most the specified - * length. - * - * @param name The original name - * @param desiredLength The desired maximum length - * @return The shortened version - */ - public String shortenName(String name, int desiredLength) - { - // TODO: Find an algorithm that generates unique names - int originalLength = name.length(); - - if ((desiredLength <= 0) || (originalLength <= desiredLength)) - { - return name; - } - - int delta = originalLength - desiredLength; - int startCut = desiredLength / 2; - - StringBuffer result = new StringBuffer(); - - result.append(name.substring(0, startCut)); - if (((startCut == 0) || (name.charAt(startCut - 1) != '_')) && - ((startCut + delta + 1 == originalLength) || (name.charAt(startCut + delta + 1) != '_'))) - { - // just to make sure that there isn't already a '_' right before or right - // after the cutting place (which would look odd with an aditional one) - result.append("_"); - } - result.append(name.substring(startCut + delta + 1, originalLength)); - return result.toString(); - } - - /** - * Returns the table name. This method takes care of length limitations imposed by some databases. - * - * @param table The table - * @return The table name - */ - public String getTableName(Table table) - { - return shortenName(table.getName(), getMaxTableNameLength()); - } - - /** - * Outputs a comment for the table. - * - * @param table The table - */ - protected void writeTableComment(Table table) throws IOException - { - printComment("-----------------------------------------------------------------------"); - printComment(getTableName(table)); - printComment("-----------------------------------------------------------------------"); - println(); - } - - /** - * Generates the first part of the ALTER TABLE statement including the - * table name. - * - * @param table The table being altered - */ - protected void writeTableAlterStmt(Table table) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(table)); - printIndent(); - } - - /** - * Writes the table creation statement without the statement end. - * - * @param database The model - * @param table The table - * @param parameters Additional platform-specific parameters for the table creation - */ - protected void writeTableCreationStmt(Database database, Table table, Map parameters) throws IOException - { - print("CREATE TABLE "); - printlnIdentifier(getTableName(table)); - println("("); - - writeColumns(table); - - if (getPlatformInfo().isPrimaryKeyEmbedded()) - { - writeEmbeddedPrimaryKeysStmt(table); - } - if (getPlatformInfo().isForeignKeysEmbedded()) - { - writeEmbeddedForeignKeysStmt(database, table); - } - if (getPlatformInfo().isIndicesEmbedded()) - { - writeEmbeddedIndicesStmt(table); - } - println(); - print(")"); - } - - /** - * Writes the end of the table creation statement. Per default, - * only the end of the statement is written, but this can be changed - * in subclasses. - * - * @param table The table - * @param parameters Additional platform-specific parameters for the table creation - */ - protected void writeTableCreationStmtEnding(Table table, Map parameters) throws IOException - { - printEndOfStatement(); - } - - /** - * Writes the columns of the given table. - * - * @param table The table - */ - protected void writeColumns(Table table) throws IOException - { - for (int idx = 0; idx < table.getColumnCount(); idx++) - { - printIndent(); - writeColumn(table, table.getColumn(idx)); - if (idx < table.getColumnCount() - 1) - { - println(","); - } - } - } - - /** - * Returns the column name. This method takes care of length limitations imposed by some databases. - * - * @param column The column - * @return The column name - */ - protected String getColumnName(Column column) throws IOException - { - return shortenName(column.getName(), getMaxColumnNameLength()); - } - - /** - * Outputs the DDL for the specified column. - * - * @param table The table containing the column - * @param column The column - */ - protected void writeColumn(Table table, Column column) throws IOException - { - //see comments in columnsDiffer about null/"" defaults - printIdentifier(getColumnName(column)); - print(" "); - print(getSqlType(column)); - writeColumnDefaultValueStmt(table, column); - if (column.isRequired()) - { - print(" "); - writeColumnNotNullableStmt(); - } - else if (getPlatformInfo().isNullAsDefaultValueRequired() && - getPlatformInfo().hasNullDefault(column.getTypeCode())) - { - print(" "); - writeColumnNullableStmt(); - } - if (column.isAutoIncrement() && !getPlatformInfo().isDefaultValueUsedForIdentitySpec()) - { - if (!getPlatformInfo().isNonPKIdentityColumnsSupported() && !column.isPrimaryKey()) - { - throw new ModelException("Column "+column.getName()+" in table "+table.getName()+" is auto-incrementing but not a primary key column, which is not supported by the platform"); - } - print(" "); - writeColumnAutoIncrementStmt(table, column); - } - } - - /** - * Returns the full SQL type specification (including size and precision/scale) for the - * given column. - * - * @param column The column - * @return The full SQL type string including the size - */ - protected String getSqlType(Column column) - { - String nativeType = getNativeType(column); - int sizePos = nativeType.indexOf(SIZE_PLACEHOLDER); - StringBuffer sqlType = new StringBuffer(); - - sqlType.append(sizePos >= 0 ? nativeType.substring(0, sizePos) : nativeType); - - Object sizeSpec = column.getSize(); - - if (sizeSpec == null) - { - sizeSpec = getPlatformInfo().getDefaultSize(column.getTypeCode()); - } - if (sizeSpec != null) - { - if (getPlatformInfo().hasSize(column.getTypeCode())) - { - sqlType.append("("); - sqlType.append(sizeSpec.toString()); - sqlType.append(")"); - } - else if (getPlatformInfo().hasPrecisionAndScale(column.getTypeCode())) - { - sqlType.append("("); - sqlType.append(column.getSizeAsInt()); - sqlType.append(","); - sqlType.append(column.getScale()); - sqlType.append(")"); - } - } - sqlType.append(sizePos >= 0 ? nativeType.substring(sizePos + SIZE_PLACEHOLDER.length()) : ""); - - return sqlType.toString(); - } - - /** - * Returns the database-native type for the given column. - * - * @param column The column - * @return The native type - */ - protected String getNativeType(Column column) - { - String nativeType = (String)getPlatformInfo().getNativeType(column.getTypeCode()); - - return nativeType == null ? column.getType() : nativeType; - } - - /** - * Returns the bare database-native type for the given column without any size specifies. - * - * @param column The column - * @return The native type - */ - protected String getBareNativeType(Column column) - { - String nativeType = getNativeType(column); - int sizePos = nativeType.indexOf(SIZE_PLACEHOLDER); - - return sizePos >= 0 ? nativeType.substring(0, sizePos) : nativeType; - } - - /** - * Returns the native default value for the column. - * - * @param column The column - * @return The native default value - */ - protected String getNativeDefaultValue(Column column) - { - return column.getDefaultValue(); - } - - /** - * Escapes the necessary characters in given string value. - * - * @param value The value - * @return The corresponding string with the special characters properly escaped - */ - protected String escapeStringValue(String value) - { - String result = value; - - for (Iterator it = _charSequencesToEscape.entrySet().iterator(); it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - - result = StringUtils.replace(result, (String)entry.getKey(), (String)entry.getValue()); - } - return result; - } - - /** - * Determines whether the given default spec is a non-empty spec that shall be used in a DEFAULT - * expression. E.g. if the spec is an empty string and the type is a numeric type, then it is - * no valid default value whereas if it is a string type, then it is valid. - * - * @param defaultSpec The default value spec - * @param typeCode The JDBC type code - * @return true if the default value spec is valid - */ - protected boolean isValidDefaultValue(String defaultSpec, int typeCode) - { - return (defaultSpec != null) && - ((defaultSpec.length() > 0) || - (!TypeMap.isNumericType(typeCode) && !TypeMap.isDateTimeType(typeCode))); - } - - /** - * Prints the default value stmt part for the column. - * - * @param table The table - * @param column The column - */ - protected void writeColumnDefaultValueStmt(Table table, Column column) throws IOException - { - Object parsedDefault = column.getParsedDefaultValue(); - - if (parsedDefault != null) - { - if (!getPlatformInfo().isDefaultValuesForLongTypesSupported() && - ((column.getTypeCode() == Types.LONGVARBINARY) || (column.getTypeCode() == Types.LONGVARCHAR))) - { - throw new ModelException("The platform does not support default values for LONGVARCHAR or LONGVARBINARY columns"); - } - // we write empty default value strings only if the type is not a numeric or date/time type - if (isValidDefaultValue(column.getDefaultValue(), column.getTypeCode())) - { - print(" DEFAULT "); - writeColumnDefaultValue(table, column); - } - } - else if (getPlatformInfo().isDefaultValueUsedForIdentitySpec() && column.isAutoIncrement()) - { - print(" DEFAULT "); - writeColumnDefaultValue(table, column); - } - } - - /** - * Prints the default value of the column. - * - * @param table The table - * @param column The column - */ - protected void writeColumnDefaultValue(Table table, Column column) throws IOException - { - printDefaultValue(getNativeDefaultValue(column), column.getTypeCode()); - } - - /** - * Prints the default value of the column. - * - * @param defaultValue The default value - * @param typeCode The type code to write the default value for - */ - protected void printDefaultValue(Object defaultValue, int typeCode) throws IOException - { - if (defaultValue != null) - { - boolean shouldUseQuotes = !TypeMap.isNumericType(typeCode); - - if (shouldUseQuotes) - { - // characters are only escaped when within a string literal - print(getPlatformInfo().getValueQuoteToken()); - print(escapeStringValue(defaultValue.toString())); - print(getPlatformInfo().getValueQuoteToken()); - } - else - { - print(defaultValue.toString()); - } - } - } - - /** - * Prints that the column is an auto increment column. - * - * @param table The table - * @param column The column - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { - print("IDENTITY"); - } - - /** - * Prints that a column is nullable. - */ - protected void writeColumnNullableStmt() throws IOException - { - print("NULL"); - } - - /** - * Prints that a column is not nullable. - */ - protected void writeColumnNotNullableStmt() throws IOException - { - print("NOT NULL"); - } - - /** - * Compares the current column in the database with the desired one. - * Type, nullability, size, scale, default value, and precision radix are - * the attributes checked. Currently default values are compared, and - * null and empty string are considered equal. - * - * @param currentColumn The current column as it is in the database - * @param desiredColumn The desired column - * @return true if the column specifications differ - */ - protected boolean columnsDiffer(Column currentColumn, Column desiredColumn) - { - //The createColumn method leaves off the default clause if column.getDefaultValue() - //is null. mySQL interprets this as a default of "" or 0, and thus the columns - //are always different according to this method. alterDatabase will generate - //an alter statement for the column, but it will be the exact same definition - //as before. In order to avoid this situation I am ignoring the comparison - //if the desired default is null. In order to "un-default" a column you'll - //have to have a default="" or default="0" in the schema xml. - //If this is bad for other databases, it is recommended that the createColumn - //method use a "DEFAULT NULL" statement if that is what is needed. - //A good way to get this would be to require a defaultValue="" in the - //schema xml if you really want null and not just unspecified. - - String desiredDefault = desiredColumn.getDefaultValue(); - String currentDefault = currentColumn.getDefaultValue(); - boolean defaultsEqual = (desiredDefault == null) || desiredDefault.equals(currentDefault); - boolean sizeMatters = getPlatformInfo().hasSize(currentColumn.getTypeCode()) && - (desiredColumn.getSize() != null); - - // We're comparing the jdbc type that corresponds to the native type for the - // desired type, in order to avoid repeated altering of a perfectly valid column - if ((getPlatformInfo().getTargetJdbcType(desiredColumn.getTypeCode()) != currentColumn.getTypeCode()) || - (desiredColumn.isRequired() != currentColumn.isRequired()) || - (sizeMatters && !StringUtils.equals(desiredColumn.getSize(), currentColumn.getSize())) || - !defaultsEqual) - { - return true; - } - else - { - return false; - } - } - - /** - * Returns the name to be used for the given foreign key. If the foreign key has no - * specified name, this method determines a unique name for it. The name will also - * be shortened to honor the maximum identifier length imposed by the platform. - * - * @param table The table for whith the foreign key is defined - * @param fk The foreign key - * @return The name - */ - public String getForeignKeyName(Table table, ForeignKey fk) - { - String fkName = fk.getName(); - boolean needsName = (fkName == null) || (fkName.length() == 0); - - if (needsName) - { - StringBuffer name = new StringBuffer(); - - for (int idx = 0; idx < fk.getReferenceCount(); idx++) - { - name.append(fk.getReference(idx).getLocalColumnName()); - name.append("_"); - } - name.append(fk.getForeignTableName()); - fkName = getConstraintName(null, table, "FK", name.toString()); - } - fkName = shortenName(fkName, getMaxForeignKeyNameLength()); - - if (needsName) - { - _log.warn("Encountered a foreign key in table " + table.getName() + " that has no name. " + - "DdlUtils will use the auto-generated and shortened name " + fkName + " instead."); - } - - return fkName; - } - - /** - * Returns the constraint name. This method takes care of length limitations imposed by some databases. - * - * @param prefix The constraint prefix, can be null - * @param table The table that the constraint belongs to - * @param secondPart The second name part, e.g. the name of the constraint column - * @param suffix The constraint suffix, e.g. a counter (can be null) - * @return The constraint name - */ - public String getConstraintName(String prefix, Table table, String secondPart, String suffix) - { - StringBuffer result = new StringBuffer(); - - if (prefix != null) - { - result.append(prefix); - result.append("_"); - } - result.append(table.getName()); - result.append("_"); - result.append(secondPart); - if (suffix != null) - { - result.append("_"); - result.append(suffix); - } - return shortenName(result.toString(), getMaxConstraintNameLength()); - } - - /** - * Writes the primary key constraints of the table inside its definition. - * - * @param table The table - */ - protected void writeEmbeddedPrimaryKeysStmt(Table table) throws IOException - { - Column[] primaryKeyColumns = table.getPrimaryKeyColumns(); - - if ((primaryKeyColumns.length > 0) && shouldGeneratePrimaryKeys(primaryKeyColumns)) - { - printStartOfEmbeddedStatement(); - writePrimaryKeyStmt(table, primaryKeyColumns); - } - } - - /** - * Writes the primary key constraints of the table as alter table statements. - * - * @param table The table - * @param primaryKeyColumns The primary key columns - */ - protected void writeExternalPrimaryKeysCreateStmt(Table table, Column[] primaryKeyColumns) throws IOException - { - if ((primaryKeyColumns.length > 0) && shouldGeneratePrimaryKeys(primaryKeyColumns)) - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(table)); - printIndent(); - print("ADD CONSTRAINT "); - printIdentifier(getConstraintName(null, table, "PK", null)); - print(" "); - writePrimaryKeyStmt(table, primaryKeyColumns); - printEndOfStatement(); - } - } - - /** - * Determines whether we should generate a primary key constraint for the given - * primary key columns. - * - * @param primaryKeyColumns The pk columns - * @return true if a pk statement should be generated for the columns - */ - protected boolean shouldGeneratePrimaryKeys(Column[] primaryKeyColumns) - { - return true; - } - - /** - * Writes a primary key statement for the given columns. - * - * @param table The table - * @param primaryKeyColumns The primary columns - */ - protected void writePrimaryKeyStmt(Table table, Column[] primaryKeyColumns) throws IOException - { - print("PRIMARY KEY ("); - for (int idx = 0; idx < primaryKeyColumns.length; idx++) - { - printIdentifier(getColumnName(primaryKeyColumns[idx])); - if (idx < primaryKeyColumns.length - 1) - { - print(", "); - } - } - print(")"); - } - - /** - * Returns the index name. This method takes care of length limitations imposed by some databases. - * - * @param index The index - * @return The index name - */ - public String getIndexName(Index index) - { - return shortenName(index.getName(), getMaxConstraintNameLength()); - } - - /** - * Writes the indexes of the given table. - * - * @param table The table - */ - protected void writeExternalIndicesCreateStmt(Table table) throws IOException - { - for (int idx = 0; idx < table.getIndexCount(); idx++) - { - Index index = table.getIndex(idx); - - if (!index.isUnique() && !getPlatformInfo().isIndicesSupported()) - { - throw new ModelException("Platform does not support non-unique indices"); - } - writeExternalIndexCreateStmt(table, index); - } - } - - /** - * Writes the indexes embedded within the create table statement. - * - * @param table The table - */ - protected void writeEmbeddedIndicesStmt(Table table) throws IOException - { - if (getPlatformInfo().isIndicesSupported()) - { - for (int idx = 0; idx < table.getIndexCount(); idx++) - { - printStartOfEmbeddedStatement(); - writeEmbeddedIndexCreateStmt(table, table.getIndex(idx)); - } - } - } - - /** - * Writes the given index of the table. - * - * @param table The table - * @param index The index - */ - protected void writeExternalIndexCreateStmt(Table table, Index index) throws IOException - { - if (getPlatformInfo().isIndicesSupported()) - { - if (index.getName() == null) - { - _log.warn("Cannot write unnamed index " + index); - } - else - { - print("CREATE"); - if (index.isUnique()) - { - print(" UNIQUE"); - } - print(" INDEX "); - printIdentifier(getIndexName(index)); - print(" ON "); - printIdentifier(getTableName(table)); - print(" ("); - - for (int idx = 0; idx < index.getColumnCount(); idx++) - { - IndexColumn idxColumn = index.getColumn(idx); - Column col = table.findColumn(idxColumn.getName()); - - if (col == null) - { - // would get null pointer on next line anyway, so throw exception - throw new ModelException("Invalid column '" + idxColumn.getName() + "' on index " + index.getName() + " for table " + table.getName()); - } - if (idx > 0) - { - print(", "); - } - printIdentifier(getColumnName(col)); - } - - print(")"); - printEndOfStatement(); - } - } - } - - /** - * Writes the given embedded index of the table. - * - * @param table The table - * @param index The index - */ - protected void writeEmbeddedIndexCreateStmt(Table table, Index index) throws IOException - { - if ((index.getName() != null) && (index.getName().length() > 0)) - { - print(" CONSTRAINT "); - printIdentifier(getIndexName(index)); - } - if (index.isUnique()) - { - print(" UNIQUE"); - } - else - { - print(" INDEX "); - } - print(" ("); - - for (int idx = 0; idx < index.getColumnCount(); idx++) - { - IndexColumn idxColumn = index.getColumn(idx); - Column col = table.findColumn(idxColumn.getName()); - - if (col == null) - { - // would get null pointer on next line anyway, so throw exception - throw new ModelException("Invalid column '" + idxColumn.getName() + "' on index " + index.getName() + " for table " + table.getName()); - } - if (idx > 0) - { - print(", "); - } - printIdentifier(getColumnName(col)); - } - - print(")"); - } - - /** - * Generates the statement to drop a non-embedded index from the database. - * - * @param table The table the index is on - * @param index The index to drop - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { - if (getPlatformInfo().isAlterTableForDropUsed()) - { - writeTableAlterStmt(table); - } - print("DROP INDEX "); - printIdentifier(getIndexName(index)); - if (!getPlatformInfo().isAlterTableForDropUsed()) - { - print(" ON "); - printIdentifier(getTableName(table)); - } - printEndOfStatement(); - } - - - /** - * Writes the foreign key constraints inside a create table () clause. - * - * @param database The database model - * @param table The table - */ - protected void writeEmbeddedForeignKeysStmt(Database database, Table table) throws IOException - { - for (int idx = 0; idx < table.getForeignKeyCount(); idx++) - { - ForeignKey key = table.getForeignKey(idx); - - if (key.getForeignTableName() == null) - { - _log.warn("Foreign key table is null for key " + key); - } - else - { - printStartOfEmbeddedStatement(); - if (getPlatformInfo().isEmbeddedForeignKeysNamed()) - { - print("CONSTRAINT "); - printIdentifier(getForeignKeyName(table, key)); - print(" "); - } - print("FOREIGN KEY ("); - writeLocalReferences(key); - print(") REFERENCES "); - printIdentifier(getTableName(database.findTable(key.getForeignTableName()))); - print(" ("); - writeForeignReferences(key); - print(")"); - } - } - } - - /** - * Writes a single foreign key constraint using a alter table statement. - * - * @param database The database model - * @param table The table - * @param key The foreign key - */ - protected void writeExternalForeignKeyCreateStmt(Database database, Table table, ForeignKey key) throws IOException - { - if (key.getForeignTableName() == null) - { - _log.warn("Foreign key table is null for key " + key); - } - else - { - writeTableAlterStmt(table); - - print("ADD CONSTRAINT "); - printIdentifier(getForeignKeyName(table, key)); - print(" FOREIGN KEY ("); - writeLocalReferences(key); - print(") REFERENCES "); - printIdentifier(getTableName(database.findTable(key.getForeignTableName()))); - print(" ("); - writeForeignReferences(key); - print(")"); - printEndOfStatement(); - } - } - - /** - * Writes a list of local references for the given foreign key. - * - * @param key The foreign key - */ - protected void writeLocalReferences(ForeignKey key) throws IOException - { - for (int idx = 0; idx < key.getReferenceCount(); idx++) - { - if (idx > 0) - { - print(", "); - } - printIdentifier(key.getReference(idx).getLocalColumnName()); - } - } - - /** - * Writes a list of foreign references for the given foreign key. - * - * @param key The foreign key - */ - protected void writeForeignReferences(ForeignKey key) throws IOException - { - for (int idx = 0; idx < key.getReferenceCount(); idx++) - { - if (idx > 0) - { - print(", "); - } - printIdentifier(key.getReference(idx).getForeignColumnName()); - } - } - - /** - * Generates the statement to drop a foreignkey constraint from the database using an - * alter table statement. - * - * @param table The table - * @param foreignKey The foreign key - */ - protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) throws IOException - { - writeTableAlterStmt(table); - print("DROP CONSTRAINT "); - printIdentifier(getForeignKeyName(table, foreignKey)); - printEndOfStatement(); - } - - // - // Helper methods - // - - /** - * Prints an SQL comment to the current stream. - * - * @param text The comment text - */ - protected void printComment(String text) throws IOException - { - if (getPlatform().isSqlCommentsOn()) - { - print(getPlatformInfo().getCommentPrefix()); - // Some databases insist on a space after the prefix - print(" "); - print(text); - print(" "); - print(getPlatformInfo().getCommentSuffix()); - println(); - } - } - - /** - * Prints the start of an embedded statement. - */ - protected void printStartOfEmbeddedStatement() throws IOException - { - println(","); - printIndent(); - } - - /** - * Prints the end of statement text, which is typically a semi colon followed by - * a carriage return. - */ - protected void printEndOfStatement() throws IOException - { - // TODO: It might make sense to use a special writer which stores the individual - // statements separately (the end of a statement is identified by this method) - println(getPlatformInfo().getSqlCommandDelimiter()); - println(); - } - - /** - * Prints a newline. - */ - protected void println() throws IOException - { - print(LINE_SEPARATOR); - } - - /** - * Prints some text. - * - * @param text The text to print - */ - protected void print(String text) throws IOException - { - _writer.write(text); - } - - /** - * Returns the delimited version of the identifier (if configured). - * - * @param identifier The identifier - * @return The delimited version of the identifier unless the platform is configured - * to use undelimited identifiers; in that case, the identifier is returned unchanged - */ - protected String getDelimitedIdentifier(String identifier) - { - if (getPlatform().isDelimitedIdentifierModeOn()) - { - return getPlatformInfo().getDelimiterToken() + identifier + getPlatformInfo().getDelimiterToken(); - } - else - { - return identifier; - } - } - - /** - * Prints the given identifier. For most databases, this will - * be a delimited identifier. - * - * @param identifier The identifier - */ - protected void printIdentifier(String identifier) throws IOException - { - print(getDelimitedIdentifier(identifier)); - } - - /** - * Prints the given identifier followed by a newline. For most databases, this will - * be a delimited identifier. - * - * @param identifier The identifier - */ - protected void printlnIdentifier(String identifier) throws IOException - { - println(getDelimitedIdentifier(identifier)); - } - - /** - * Prints some text followed by a newline. - * - * @param text The text to print - */ - protected void println(String text) throws IOException - { - print(text); - println(); - } - - /** - * Prints the characters used to indent SQL. - */ - protected void printIndent() throws IOException - { - print(getIndent()); - } - - /** - * Creates a reasonably unique identifier only consisting of hexadecimal characters and underscores. - * It looks like d578271282b42fce__2955b56e_107df3fbc96__8000 and is 48 characters long. - * - * @return The identifier - */ - protected String createUniqueIdentifier() - { - return new UID().toString().replace(':', '_').replace('-', '_'); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapeBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapeBuilder.java deleted file mode 100644 index 35dca7f8d3..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapeBuilder.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.cloudscape; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; - -/** - * The SQL Builder for Cloudscape. - * - * @version $Revision: 463757 $ - */ -public class CloudscapeBuilder extends SqlBuilder -{ - /** - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public CloudscapeBuilder(Platform platform) - { - super(platform); - addEscapedCharSequence("'", "''"); - } - - /** - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { - print("GENERATED ALWAYS AS IDENTITY"); - } - - /** - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { - return "VALUES IDENTITY_VAL_LOCAL()"; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapePlatform.java deleted file mode 100644 index 666390ca57..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/CloudscapePlatform.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.cloudscape; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/** - * The Cloudscape platform implementation. - * - * @version $Revision: 231306 $ - */ -public class CloudscapePlatform extends PlatformImplBase -{ - /** Database name of this platform. */ - public static final String DATABASENAME = "Cloudscape"; - /** A subprotocol used by the DB2 network driver. */ - public static final String JDBC_SUBPROTOCOL_1 = "db2j:net"; - /** A subprotocol used by the DB2 network driver. */ - public static final String JDBC_SUBPROTOCOL_2 = "cloudscape:net"; - - /** - * Creates a new platform instance. - */ - public CloudscapePlatform() - { - PlatformInfo info = getPlatformInfo(); - - info.setMaxIdentifierLength(128); - info.setSystemForeignKeyIndicesAlwaysNonUnique(true); - // BINARY and VARBINARY will also be handled by CloudscapeBuilder.getSqlType - info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.BINARY, "CHAR {0} FOR BIT DATA"); - info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.DISTINCT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE PRECISION", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.LONGVARBINARY, "LONG VARCHAR FOR BIT DATA"); - info.addNativeTypeMapping(Types.LONGVARCHAR, "LONG VARCHAR"); - info.addNativeTypeMapping(Types.NULL, "LONG VARCHAR FOR BIT DATA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.REF, "LONG VARCHAR FOR BIT DATA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.VARBINARY, "VARCHAR {0} FOR BIT DATA"); - info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); - info.addNativeTypeMapping("DATALINK", "LONG VARCHAR FOR BIT DATA", "LONGVARBINARY"); - - info.setDefaultSize(Types.BINARY, 254); - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARBINARY, 254); - info.setDefaultSize(Types.VARCHAR, 254); - - setSqlBuilder(new CloudscapeBuilder(this)); - } - - /** - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/package.html deleted file mode 100644 index 1eb7833509..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/cloudscape/package.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -

- This package contains the platform implementation for the - Cloudscape database. -

- - diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Builder.java deleted file mode 100644 index dbe5c4d018..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Builder.java +++ /dev/null @@ -1,273 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.db2; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.sql.Types; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; - -/* - * The SQL Builder for DB2. - * - * @version $Revision: 504811 $ - */ -public class Db2Builder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public Db2Builder(Platform platform) - { - super(platform); - addEscapedCharSequence("'", "''"); - } - - /* - * {@inheritDoc} - */ - protected String getNativeDefaultValue(Column column) - { - if ((column.getTypeCode() == Types.BIT) || - (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode()))) - { - return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString(); - } - else - { - return super.getNativeDefaultValue(column); - } - } - - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { - print("GENERATED BY DEFAULT AS IDENTITY"); - } - - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { - return "VALUES IDENTITY_VAL_LOCAL()"; - } - - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { - // Index names in DB2 are unique to a schema and hence Derby does not - // use the ON clause - print("DROP INDEX "); - printIdentifier(getIndexName(index)); - printEndOfStatement(); - } - - /* - * {@inheritDoc} - */ - protected void writeCastExpression(Column sourceColumn, Column targetColumn) throws IOException - { - String sourceNativeType = getBareNativeType(sourceColumn); - String targetNativeType = getBareNativeType(targetColumn); - - if (sourceNativeType.equals(targetNativeType)) - { - printIdentifier(getColumnName(sourceColumn)); - } - else - { - String type = getSqlType(targetColumn); - - // DB2 has the limitation that it cannot convert numeric values - // to VARCHAR, though it can convert them to CHAR - if (TypeMap.isNumericType(sourceColumn.getTypeCode()) && - "VARCHAR".equalsIgnoreCase(targetNativeType)) - { - Object sizeSpec = targetColumn.getSize(); - - if (sizeSpec == null) - { - sizeSpec = getPlatformInfo().getDefaultSize(targetColumn.getTypeCode()); - } - type = "CHAR(" +sizeSpec.toString() + ")"; - } - - print("CAST("); - printIdentifier(getColumnName(sourceColumn)); - print(" AS "); - print(type); - print(")"); - } - } - - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { - // DB2 provides only limited ways to alter a column, so we don't use them - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; - - // DB2 can only add not insert columns - // Also, DB2 does not allow the GENERATED BY DEFAULT AS IDENTITY clause in - // the ALTER TABLE ADD COLUMN statement, so we have to rebuild the table instead - if ((addColumnChange.getNextColumn() == null) && !addColumnChange.getNewColumn().isAutoIncrement()) - { - processChange(currentModel, desiredModel, addColumnChange); - changeIt.remove(); - } - } - } - - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddPrimaryKeyChange) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); - changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - processChange(currentModel, desiredModel, (PrimaryKeyChange)change); - changeIt.remove(); - } - else if (change instanceof RemovePrimaryKeyChange) - { - processChange(currentModel, desiredModel, (RemovePrimaryKeyChange)change); - changeIt.remove(); - } - } - } - - /* - * Processes the addition of a column to a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("ADD COLUMN "); - writeColumn(change.getChangedTable(), change.getNewColumn()); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a column from a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP COLUMN "); - printIdentifier(getColumnName(change.getColumn())); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a primary key from a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - RemovePrimaryKeyChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP PRIMARY KEY"); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the change of the primary key of a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - PrimaryKeyChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP PRIMARY KEY"); - printEndOfStatement(); - writeExternalPrimaryKeysCreateStmt(change.getChangedTable(), change.getNewPrimaryKeyColumns()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Platform.java deleted file mode 100644 index 4726854ade..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2Platform.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.db2; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The DB2 platform implementation. - * - * @version $Revision: 231306 $ - */ -public class Db2Platform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "DB2"; - /* The standard DB2 jdbc driver. */ - public static final String JDBC_DRIVER = "com.ibm.db2.jcc.DB2Driver"; - /* Older name for the jdbc driver. */ - public static final String JDBC_DRIVER_OLD1 = "COM.ibm.db2.jdbc.app.DB2Driver"; - /* Older name for the jdbc driver. */ - public static final String JDBC_DRIVER_OLD2 = "COM.ibm.db2os390.sqlj.jdbc.DB2SQLJDriver"; - /* The JTOpen JDBC Driver. */ - public static final String JDBC_DRIVER_JTOPEN = "com.ibm.as400.access.AS400JDBCDriver"; - /* The subprotocol used by the standard DB2 driver. */ - public static final String JDBC_SUBPROTOCOL = "db2"; - /* An alternative subprotocol used by the standard DB2 driver on OS/390. */ - public static final String JDBC_SUBPROTOCOL_OS390_1 = "db2os390"; - /* An alternative subprotocol used by the standard DB2 driver on OS/390. */ - public static final String JDBC_SUBPROTOCOL_OS390_2 = "db2os390sqlj"; - /* An alternative subprotocol used by the JTOpen driver on OS/400. */ - public static final String JDBC_SUBPROTOCOL_JTOPEN = "as400"; - - /* - * Creates a new platform instance. - */ - public Db2Platform() - { - PlatformInfo info = getPlatformInfo(); - - info.setMaxIdentifierLength(18); - - // the BINARY types are also handled by Db2Builder.getSqlType(Column) - info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.BINARY, "CHAR {0} FOR BIT DATA"); - info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.LONGVARBINARY, "LONG VARCHAR FOR BIT DATA"); - info.addNativeTypeMapping(Types.LONGVARCHAR, "LONG VARCHAR"); - info.addNativeTypeMapping(Types.NULL, "LONG VARCHAR FOR BIT DATA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.NUMERIC, "DECIMAL", Types.DECIMAL); - info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.VARBINARY, "VARCHAR {0} FOR BIT DATA"); - info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); - - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARCHAR, 254); - info.setDefaultSize(Types.BINARY, 254); - info.setDefaultSize(Types.VARBINARY, 254); - info.setStoresUpperCaseInCatalog(true); - - setSqlBuilder(new Db2Builder(this)); - setModelReader(new Db2ModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Builder.java deleted file mode 100644 index 7e27d93c65..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Builder.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.db2; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.Platform; - -/* - * The SQL Builder for DB2 v8 and above. - * - * @version $Revision: $ - */ -public class Db2v8Builder extends Db2Builder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public Db2v8Builder(Platform platform) - { - super(platform); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Platform.java deleted file mode 100644 index 2690a32b3b..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2v8Platform.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.db2; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * The DB2 platform implementation for DB2 v8 and above. - * - * @version $Revision: $ - */ -public class Db2v8Platform extends Db2Platform -{ - /* Database name of this platform. */ - public static final String[] DATABASENAMES = {"DB2v8","DB2/LINUX9","DB2"}; - - /* - * Creates a new platform instance. - */ - public Db2v8Platform() - { - super(); - // Note that we optimistically assume that number of characters = number of bytes - // If the name contains characters that are more than one byte in the database's - // encoding, then the db will report an error anyway, but we cannot really calculate - // the number of bytes - getPlatformInfo().setMaxIdentifierLength(128); - getPlatformInfo().setMaxColumnNameLength(128); - getPlatformInfo().setMaxConstraintNameLength(128); - getPlatformInfo().setMaxForeignKeyNameLength(128); - setSqlBuilder(new Db2v8Builder(this)); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyPlatform.java deleted file mode 100644 index 966a056220..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyPlatform.java +++ /dev/null @@ -1,135 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.derby; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Iterator; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.DatabaseOperationException; -import org.jumpmind.symmetric.db.ddl.platform.cloudscape.CloudscapePlatform; - -/* - * The platform implementation for Derby. - * - * @version $Revision: 231306 $ - */ -public class DerbyPlatform extends CloudscapePlatform -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "Derby"; - /* The derby jdbc driver for use as a client for a normal server. */ - public static final String JDBC_DRIVER = "org.apache.derby.jdbc.ClientDriver"; - /* The derby jdbc driver for use as an embedded database. */ - public static final String JDBC_DRIVER_EMBEDDED = "org.apache.derby.jdbc.EmbeddedDriver"; - /* The subprotocol used by the derby drivers. */ - public static final String JDBC_SUBPROTOCOL = "derby"; - - /* - * Creates a new Derby platform instance. - */ - public DerbyPlatform() - { - super(); - getPlatformInfo().addNativeTypeMapping(Types.DOUBLE, "DOUBLE"); - getPlatformInfo().addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); - getPlatformInfo().setStoresUpperCaseInCatalog(true); - setSqlBuilder(new DerbyBuilder(this)); - setModelReader(new DerbyModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } - - /* - * {@inheritDoc} - */ - public void createDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password, Map parameters) throws DatabaseOperationException, UnsupportedOperationException - { - // For Derby, you create databases by simply appending ";create=true" to the connection url - if (JDBC_DRIVER.equals(jdbcDriverClassName) || - JDBC_DRIVER_EMBEDDED.equals(jdbcDriverClassName)) - { - StringBuffer creationUrl = new StringBuffer(); - Connection connection = null; - - creationUrl.append(connectionUrl); - creationUrl.append(";create=true"); - if ((parameters != null) && !parameters.isEmpty()) - { - for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - - // no need to specify create twice (and create=false wouldn't help anyway) - if (!"create".equalsIgnoreCase(entry.getKey().toString())) - { - creationUrl.append(";"); - creationUrl.append(entry.getKey().toString()); - creationUrl.append("="); - if (entry.getValue() != null) - { - creationUrl.append(entry.getValue().toString()); - } - } - } - } - if (getLog().isDebugEnabled()) - { - getLog().debug("About to create database using this URL: "+creationUrl.toString()); - } - try - { - Class.forName(jdbcDriverClassName); - - connection = DriverManager.getConnection(creationUrl.toString(), username, password); - logWarnings(connection); - } - catch (Exception ex) - { - throw new DatabaseOperationException("Error while trying to create a database", ex); - } - finally - { - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException ex) - {} - } - } - } - else - { - throw new UnsupportedOperationException("Unable to create a Derby database via the driver "+jdbcDriverClassName); - } - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/h2/H2Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/h2/H2Builder.java deleted file mode 100644 index 9c87413146..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/h2/H2Builder.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -package org.jumpmind.symmetric.db.ddl.platform.h2; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.ListIterator; - -import org.apache.commons.lang.StringUtils; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnAutoIncrementChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDataTypeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnRequiredChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnSizeChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.ModelException; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.CreationParameters; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; - -/* - * The SQL Builder for the H2 database. From patch https://issues.apache.org/jira/browse/DDLUTILS-185 - */ -public class H2Builder extends SqlBuilder { - - public H2Builder(Platform platform) { - super(platform); - addEscapedCharSequence("'", "''"); - } - - /* - public void dropTable(Table table) throws IOException { - print("DROP TABLE "); - printIdentifier(getTableName(table)); - print(" IF EXISTS"); - printEndOfStatement(); - } - - /* - public String getSelectLastIdentityValues(Table table) { - return "CALL IDENTITY()"; - } - - /* - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException { - print("DROP INDEX IF EXISTS "); - printIdentifier(getIndexName(index)); - printEndOfStatement(); - } - - /* - protected void processTableStructureChanges(Database currentModel, Database desiredModel, - CreationParameters params, Collection changes) throws IOException { - - // Only drop columns that are not part of a primary key - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { - TableChange change = changeIt.next(); - if ((change instanceof RemoveColumnChange) && ((RemoveColumnChange) change).getColumn().isPrimaryKey()) { - changeIt.remove(); - } - } - - // in order to utilize the ALTER TABLE ADD COLUMN BEFORE statement - // we have to apply the add column changes in the correct order - // thus we first gather all add column changes and then execute them - // Since we get them in target table column order, we can simply - // iterate backwards - ArrayList addColumnChanges = new ArrayList(); - - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { - TableChange change = changeIt.next(); - if (change instanceof AddColumnChange) { - addColumnChanges.add((AddColumnChange)change); - changeIt.remove(); - } - } - - for (ListIterator changeIt = addColumnChanges.listIterator(addColumnChanges.size()); changeIt.hasPrevious();) { - AddColumnChange addColumnChange = (AddColumnChange) changeIt.previous(); - processChange(currentModel, desiredModel, addColumnChange); - changeIt.remove(); - } - - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { - TableChange change = changeIt.next(); - if (change instanceof RemoveColumnChange) { - RemoveColumnChange removeColumnChange = (RemoveColumnChange) change; - processChange(currentModel, desiredModel, removeColumnChange); - changeIt.remove(); - } - else if (change instanceof ColumnAutoIncrementChange) { - processAlterColumn(currentModel, change); - changeIt.remove(); - } else if (change instanceof ColumnChange) { - boolean needsAlter = true; - if (change instanceof ColumnDataTypeChange) { - ColumnDataTypeChange dataTypeChange = (ColumnDataTypeChange) change; - if (dataTypeChange.getChangedColumn().getTypeCode() == Types.DECIMAL - && dataTypeChange.getNewTypeCode() == Types.NUMERIC) { - needsAlter = false; - } - if (dataTypeChange.getChangedColumn().getTypeCode() == Types.SMALLINT - && dataTypeChange.getNewTypeCode() == Types.TINYINT) { - needsAlter = false; - } - if (dataTypeChange.getChangedColumn().getTypeCode() == Types.VARCHAR - && dataTypeChange.getNewTypeCode() == Types.LONGVARCHAR) { - needsAlter = false; - } - } - if (change instanceof ColumnSizeChange) { - ColumnSizeChange sizeChange = (ColumnSizeChange) change; - if (sizeChange.getNewScale() == 0 && sizeChange.getNewSize() == 0) { - needsAlter = false; - } else if (sizeChange.getNewSize() == sizeChange.getChangedColumn().getSizeAsInt() - && sizeChange.getNewScale() == sizeChange.getChangedColumn().getScale()) { - needsAlter = false; - } - } - if (needsAlter) { - processAlterColumn(currentModel, change); - } - changeIt.remove(); - } - } - - } - - /* - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException { - print("AUTO_INCREMENT"); - } - - protected void processAlterColumn(Database currentModel, TableChange change) throws IOException { - Column column = null; - if (change instanceof ColumnChange) { - column = ((ColumnChange) change).getChangedColumn(); - } else if (change instanceof ColumnAutoIncrementChange) { - column = ((ColumnAutoIncrementChange) change).getColumn(); - } - - if (column != null) { - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("ALTER COLUMN "); - if (change instanceof ColumnRequiredChange) { - ColumnRequiredChange columnRequiredChange = (ColumnRequiredChange) change; - printlnIdentifier(getColumnName(column)); - printIndent(); - if (columnRequiredChange.getChangedColumn().isRequired()) { - print(" SET NOT NULL "); - } else { - print(" SET NULL "); - } - } else { - writeColumn(change.getChangedTable(), column); - } - printEndOfStatement(); - } - } - - /* - * Processes the addition of a column to a table. - * - * @param currentModel - * The current database schema - * @param desiredModel - * The desired database schema - * @param change - * The change object - */ - protected void processChange(Database currentModel, Database desiredModel, AddColumnChange change) - throws IOException { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("ADD COLUMN "); - writeColumn(change.getChangedTable(), change.getNewColumn()); - if (change.getNextColumn() != null) { - print(" BEFORE "); - printIdentifier(getColumnName(change.getNextColumn())); - } - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a column from a table. - * - * @param currentModel - * The current database schema - * @param desiredModel - * The desired database schema - * @param change - * The change object - */ - protected void processChange(Database currentModel, Database desiredModel, RemoveColumnChange change) - throws IOException { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP COLUMN "); - printIdentifier(getColumnName(change.getColumn())); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - @Override - protected void writeColumnDefaultValueStmt(Table table, Column column) throws IOException { - Object parsedDefault = column.getParsedDefaultValue(); - - if (parsedDefault != null) { - if (!getPlatformInfo().isDefaultValuesForLongTypesSupported() - && ((column.getTypeCode() == Types.LONGVARBINARY) || (column.getTypeCode() == Types.LONGVARCHAR))) { - throw new ModelException( - "The platform does not support default values for LONGVARCHAR or LONGVARBINARY columns"); - } - // we write empty default value strings only if the type is not a - // numeric or date/time type - if (isValidDefaultValue(column.getDefaultValue(), column.getTypeCode())) { - print(" DEFAULT "); - writeColumnDefaultValue(table, column); - } - } else if (getPlatformInfo().isDefaultValueUsedForIdentitySpec() && column.isAutoIncrement()) { - print(" DEFAULT "); - writeColumnDefaultValue(table, column); - } else if (!StringUtils.isBlank(column.getDefaultValue())) { - print(" DEFAULT "); - writeColumnDefaultValue(table, column); - } - } - - @Override - protected void printDefaultValue(Object defaultValue, int typeCode) throws IOException { - if (defaultValue != null) { - String defaultValueStr = defaultValue.toString(); - boolean shouldUseQuotes = !TypeMap.isNumericType(typeCode) && !defaultValueStr.startsWith("TO_DATE(") - && !defaultValue.equals("CURRENT_TIMESTAMP") && !defaultValue.equals("CURRENT_TIME") - && !defaultValue.equals("CURRENT_DATE"); - ; - - if (shouldUseQuotes) { - // characters are only escaped when within a string literal - print(getPlatformInfo().getValueQuoteToken()); - print(escapeStringValue(defaultValueStr)); - print(getPlatformInfo().getValueQuoteToken()); - } else { - print(defaultValueStr); - } - } - } -} \ No newline at end of file diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbBuilder.java deleted file mode 100644 index c536a48f04..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbBuilder.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.hsqldb; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; - -/* - * The SQL Builder for the HsqlDb database. - * - * @version $Revision: 518485 $ - */ -public class HsqlDbBuilder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public HsqlDbBuilder(Platform platform) - { - super(platform); - addEscapedCharSequence("'", "''"); - } - - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { - print("DROP TABLE "); - printIdentifier(getTableName(table)); - print(" IF EXISTS"); - printEndOfStatement(); - } - - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { - return "CALL IDENTITY()"; - } - - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { - // HsqlDb can only drop columns that are not part of a primary key - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if ((change instanceof RemoveColumnChange) && - ((RemoveColumnChange)change).getColumn().isPrimaryKey()) - { - return; - } - } - - // in order to utilize the ALTER TABLE ADD COLUMN BEFORE statement - // we have to apply the add column changes in the correct order - // thus we first gather all add column changes and then execute them - // Since we get them in target table column order, we can simply - // iterate backwards - ArrayList addColumnChanges = new ArrayList(); - - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddColumnChange) - { - addColumnChanges.add(change); - changeIt.remove(); - } - } - for (ListIterator changeIt = addColumnChanges.listIterator(addColumnChanges.size()); changeIt.hasPrevious();) - { - AddColumnChange addColumnChange = (AddColumnChange)changeIt.previous(); - - processChange(currentModel, desiredModel, addColumnChange); - changeIt.remove(); - } - - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof RemoveColumnChange) - { - RemoveColumnChange removeColumnChange = (RemoveColumnChange)change; - - processChange(currentModel, desiredModel, removeColumnChange); - changeIt.remove(); - } - } - } - - /* - * Processes the addition of a column to a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("ADD COLUMN "); - writeColumn(change.getChangedTable(), change.getNewColumn()); - if (change.getNextColumn() != null) - { - print(" BEFORE "); - printIdentifier(getColumnName(change.getNextColumn())); - } - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a column from a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP COLUMN "); - printIdentifier(getColumnName(change.getColumn())); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbPlatform.java deleted file mode 100644 index 1a97d66806..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbPlatform.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.hsqldb; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform implementation for the HsqlDb database. - * - * @version $Revision: 231306 $ - */ -public class HsqlDbPlatform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "HsqlDb"; - /* The standard Hsqldb jdbc driver. */ - public static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; - /* The subprotocol used by the standard Hsqldb driver. */ - public static final String JDBC_SUBPROTOCOL = "hsqldb"; - - /* - * Creates a new instance of the Hsqldb platform. - */ - public HsqlDbPlatform() - { - PlatformInfo info = getPlatformInfo(); - - info.setNonPKIdentityColumnsSupported(false); - info.setIdentityOverrideAllowed(false); - info.setSystemForeignKeyIndicesAlwaysNonUnique(true); - - info.addNativeTypeMapping(Types.ARRAY, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.BLOB, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.CLOB, "LONGVARCHAR", Types.LONGVARCHAR); - info.addNativeTypeMapping(Types.DISTINCT, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "OBJECT"); - info.addNativeTypeMapping(Types.NULL, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.REF, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "LONGVARBINARY", Types.LONGVARBINARY); - // JDBC's TINYINT requires a value range of -255 to 255, but HsqlDb's is only -128 to 127 - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - - info.addNativeTypeMapping("BIT", "BOOLEAN", "BOOLEAN"); - info.addNativeTypeMapping("DATALINK", "LONGVARBINARY", "LONGVARBINARY"); - - info.setDefaultSize(Types.CHAR, Integer.MAX_VALUE); - info.setDefaultSize(Types.VARCHAR, Integer.MAX_VALUE); - info.setDefaultSize(Types.BINARY, Integer.MAX_VALUE); - info.setDefaultSize(Types.VARBINARY, Integer.MAX_VALUE); - - info.setStoresUpperCaseInCatalog(true); - - setSqlBuilder(new HsqlDbBuilder(this)); - setModelReader(new HsqlDbModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } - - /* - * {@inheritDoc} - */ - public void shutdownDatabase(Connection connection) - { - Statement stmt = null; - - try - { - stmt = connection.createStatement(); - stmt.executeUpdate("SHUTDOWN"); - } - catch (SQLException ex) - { - throw new DdlUtilsException(ex); - } - finally - { - closeStatement(stmt); - } - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2Platform.java deleted file mode 100644 index c5166e8b87..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2Platform.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.hsqldb2; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform implementation for the HsqlDb database. - */ -public class HsqlDb2Platform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "HSQL Database Engine2"; - - /* The standard Hsqldb jdbc driver. */ - public static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; - - /* The subprotocol used by the standard Hsqldb driver. */ - public static final String JDBC_SUBPROTOCOL = "hsqldb"; - - /* - * Creates a new instance of the Hsqldb platform. - */ - public HsqlDb2Platform() - { - PlatformInfo info = getPlatformInfo(); - - info.setNonPKIdentityColumnsSupported(false); - info.setIdentityOverrideAllowed(false); - info.setSystemForeignKeyIndicesAlwaysNonUnique(true); - - info.addNativeTypeMapping(Types.ARRAY, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.BLOB, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.CLOB, "LONGVARCHAR", Types.LONGVARCHAR); - info.addNativeTypeMapping(Types.DISTINCT, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "OBJECT"); - info.addNativeTypeMapping(Types.NULL, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.REF, "LONGVARBINARY", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "LONGVARBINARY", Types.LONGVARBINARY); - // JDBC's TINYINT requires a value range of -255 to 255, but HsqlDb's is only -128 to 127 - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - - info.addNativeTypeMapping("BIT", "BOOLEAN", "BOOLEAN"); - info.addNativeTypeMapping("DATALINK", "LONGVARBINARY", "LONGVARBINARY"); - - info.setDefaultSize(Types.CHAR, Integer.MAX_VALUE); - info.setDefaultSize(Types.VARCHAR, Integer.MAX_VALUE); - info.setDefaultSize(Types.BINARY, Integer.MAX_VALUE); - info.setDefaultSize(Types.VARBINARY, Integer.MAX_VALUE); - - info.setStoresUpperCaseInCatalog(true); - - setSqlBuilder(new HsqlDb2Builder(this)); - setModelReader(new HsqlDb2ModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } - - /* - * {@inheritDoc} - */ - public void shutdownDatabase(Connection connection) - { - Statement stmt = null; - - try - { - stmt = connection.createStatement(); - stmt.executeUpdate("SHUTDOWN"); - } - catch (SQLException ex) - { - throw new DdlUtilsException(ex); - } - finally - { - closeStatement(stmt); - } - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbasePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbasePlatform.java deleted file mode 100644 index b4fd58f2e0..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbasePlatform.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.interbase; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform implementation for the Interbase database. - * - * @version $Revision: 231306 $ - */ -public class InterbasePlatform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "Interbase"; - /* The interbase jdbc driver. */ - public static final String JDBC_DRIVER = "interbase.interclient.Driver"; - /* The subprotocol used by the interbase driver. */ - public static final String JDBC_SUBPROTOCOL = "interbase"; - - public static int SWITCH_TO_LONGVARCHAR_SIZE = 4096; - - /* - * Creates a new platform instance. - */ - public InterbasePlatform() - { - PlatformInfo info = getPlatformInfo(); - - info.setMaxIdentifierLength(31); - info.setCommentPrefix("/*"); - info.setCommentSuffix("*/"); - info.setSystemForeignKeyIndicesAlwaysNonUnique(true); - - // BINARY and VARBINARY are also handled by the InterbaseBuilder.getSqlType method - info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.BIGINT, "NUMERIC(18,0)"); - // Theoretically we could use (VAR)CHAR CHARACTER SET OCTETS but the JDBC driver is not - // able to handle that properly (the byte[]/BinaryStream accessors do not work) - info.addNativeTypeMapping(Types.BINARY, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.BLOB, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.CLOB, "BLOB SUB_TYPE TEXT"); - info.addNativeTypeMapping(Types.DISTINCT, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE PRECISION", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.LONGVARBINARY, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.LONGVARCHAR, "VARCHAR("+SWITCH_TO_LONGVARCHAR_SIZE+")", Types.VARCHAR); - info.addNativeTypeMapping(Types.NULL, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.REAL, "FLOAT"); - info.addNativeTypeMapping(Types.REF, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.VARBINARY, "BLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); - info.addNativeTypeMapping("DATALINK", "BLOB", "LONGVARBINARY"); - - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARCHAR, 254); - info.setHasSize(Types.BINARY, false); - info.setHasSize(Types.VARBINARY, false); - - info.setStoresUpperCaseInCatalog(true); - - setSqlBuilder(new InterbaseBuilder(this)); - setModelReader(new InterbaseModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } - - /* - * {@inheritDoc} - */ - protected void setStatementParameterValue(PreparedStatement statement, int sqlIndex, int typeCode, Object value) throws SQLException - { - if (value != null) - { - if ((value instanceof byte[]) && - ((typeCode == Types.BINARY) || (typeCode == Types.VARBINARY) || (typeCode == Types.BLOB))) - { - byte[] bytes = (byte[])value; - ByteArrayInputStream stream = new ByteArrayInputStream(bytes); - - statement.setBinaryStream(sqlIndex, stream, bytes.length); - return; - } - else if ((value instanceof String) && ((typeCode == Types.CLOB) || (typeCode == Types.LONGVARCHAR))) - { - // Clob is not supported directly - statement.setString(sqlIndex, (String)value); - return; - } - } - super.setStatementParameterValue(statement, sqlIndex, typeCode, value); - } - - /* - * {@inheritDoc} - */ - protected Object extractColumnValue(ResultSet resultSet, String columnName, int columnIdx, int jdbcType) throws SQLException - { - boolean useIdx = (columnName == null); - - switch (jdbcType) - { - case Types.BINARY: - case Types.VARBINARY: - case Types.BLOB: - try - { - BufferedInputStream input = new BufferedInputStream(useIdx ? resultSet.getBinaryStream(columnIdx) : resultSet.getBinaryStream(columnName)); - - if (resultSet.wasNull()) - { - return null; - } - - ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024); - byte[] data = new byte[1024]; - int numRead; - - while ((numRead = input.read(data, 0, data.length)) != -1) - { - buffer.write(data, 0, numRead); - } - input.close(); - return buffer.toByteArray(); - } - catch (IOException ex) - { - throw new DdlUtilsException(ex); - } - case Types.LONGVARCHAR: - case Types.CLOB: - String value = useIdx ? resultSet.getString(columnIdx) : resultSet.getString(columnName); - - return resultSet.wasNull() ? null : value; - default: - return super.extractColumnValue(resultSet, columnName, columnIdx, jdbcType); - } - } - -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlPlatform.java deleted file mode 100644 index 3240aa8166..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlPlatform.java +++ /dev/null @@ -1,156 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.mssql; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform implementation for the Microsoft SQL Server database. - * - * @version $Revision: 231306 $ - */ -public class MSSqlPlatform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "MsSql"; - /* The standard SQLServer jdbc driver. */ - public static final String JDBC_DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver"; - /* The new SQLServer 2005 jdbc driver which can also be used for SQL Server 2000. */ - public static final String JDBC_DRIVER_NEW = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; - /* The subprotocol used by the standard SQL Server driver. */ - public static final String JDBC_SUBPROTOCOL = "microsoft:sqlserver"; - /* The subprotocol recommended for the newer SQL Server 2005 driver. */ - public static final String JDBC_SUBPROTOCOL_NEW = "sqlserver"; - /* The subprotocol internally returned by the newer SQL Server 2005 driver. */ - public static final String JDBC_SUBPROTOCOL_INTERNAL = "sqljdbc"; - - /* - * Creates a new platform instance. - */ - public MSSqlPlatform() - { - PlatformInfo info = getPlatformInfo(); - - info.setMaxIdentifierLength(128); - - info.addNativeTypeMapping(Types.ARRAY, "IMAGE", Types.LONGVARBINARY); - // BIGINT will be mapped back to BIGINT by the model reader - info.addNativeTypeMapping(Types.BIGINT, "DECIMAL(19,0)"); - info.addNativeTypeMapping(Types.BLOB, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.CLOB, "TEXT", Types.LONGVARCHAR); - info.addNativeTypeMapping(Types.DATE, "DATETIME", Types.TIMESTAMP); - info.addNativeTypeMapping(Types.DISTINCT, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.DOUBLE, "FLOAT", Types.FLOAT); - info.addNativeTypeMapping(Types.INTEGER, "INT"); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.LONGVARBINARY, "IMAGE"); - info.addNativeTypeMapping(Types.LONGVARCHAR, "TEXT"); - info.addNativeTypeMapping(Types.NULL, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.OTHER, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.REF, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.TIME, "DATETIME", Types.TIMESTAMP); - info.addNativeTypeMapping(Types.TIMESTAMP, "DATETIME"); - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping("BOOLEAN", "BIT", "BIT"); - info.addNativeTypeMapping("DATALINK", "IMAGE", "LONGVARBINARY"); - - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARCHAR, 254); - info.setDefaultSize(Types.BINARY, 254); - info.setDefaultSize(Types.VARBINARY, 254); - - info.setStoresUpperCaseInCatalog(true); - - setSqlBuilder(new MSSqlBuilder(this)); - setModelReader(new MSSqlModelReader(this)); - - setDelimitedIdentifierModeOn(true); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } - - /* - * Determines whether we need to use identity override mode for the given table. - * - * @param table The table - * @return true if identity override mode is needed - */ - private boolean useIdentityOverrideFor(Table table) - { - return isIdentityOverrideOn() && - getPlatformInfo().isIdentityOverrideAllowed() && - (table.getAutoIncrementColumns().length > 0); - } - - /* - * {@inheritDoc} - */ - protected void beforeInsert(Connection connection, Table table) throws SQLException - { - if (useIdentityOverrideFor(table)) - { - MSSqlBuilder builder = (MSSqlBuilder)getSqlBuilder(); - - connection.createStatement().execute(builder.getEnableIdentityOverrideSql(table)); - } - } - - /* - * {@inheritDoc} - */ - protected void afterInsert(Connection connection, Table table) throws SQLException - { - if (useIdentityOverrideFor(table)) - { - MSSqlBuilder builder = (MSSqlBuilder)getSqlBuilder(); - - connection.createStatement().execute(builder.getDisableIdentityOverrideSql(table)); - } - } - - /* - * {@inheritDoc} - */ - protected void beforeUpdate(Connection connection, Table table) throws SQLException - { - beforeInsert(connection, table); - } - - /* - * {@inheritDoc} - */ - protected void afterUpdate(Connection connection, Table table) throws SQLException - { - afterInsert(connection, table); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50ModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50ModelReader.java deleted file mode 100644 index 9f875e9114..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50ModelReader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.mysql; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.SQLException; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; - -/* - * Reads a database model from a MySql 5 database. - */ -public class MySql50ModelReader extends MySqlModelReader -{ - /* - * Creates a new model reader for MySql 5 databases. - * - * @param platform The platform that this model reader belongs to - */ - public MySql50ModelReader(Platform platform) - { - super(platform); - } - - @Override - protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { - Column column = super.readColumn(metaData, values); - - // make sure the defaultvalue is null when an empty is returned. - if ("".equals(column.getDefaultValue())) - { - column.setDefaultValue(null); - } - return column; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50Platform.java deleted file mode 100644 index 29692578e3..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySql50Platform.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.mysql; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.PlatformInfo; - -/* - * The platform implementation for MySQL 5 and above. - * - * @version $Revision: 231306 $ - */ -public class MySql50Platform extends MySqlPlatform -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "MySQL5"; - - /* - * Creates a new platform instance. - */ - public MySql50Platform() - { - super(); - - PlatformInfo info = getPlatformInfo(); - - // MySql 5.0 returns an empty string for default values for pk columns - // which is different from the MySql 4 behaviour - info.setSyntheticDefaultValueForRequiredReturned(false); - - setModelReader(new MySql50ModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlBuilder.java deleted file mode 100644 index 2d6ff93d7f..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlBuilder.java +++ /dev/null @@ -1,351 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.mysql; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.collections.set.ListOrderedSet; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; - -/* - * The SQL Builder for MySQL. - * - * @version $Revision: 518498 $ - */ -public class MySqlBuilder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public MySqlBuilder(Platform platform) - { - super(platform); - // we need to handle the backslash first otherwise the other - // already escaped sequences would be affected - addEscapedCharSequence("\\", "\\\\"); - addEscapedCharSequence("\0", "\\0"); - addEscapedCharSequence("'", "\\'"); - addEscapedCharSequence("\"", "\\\""); - addEscapedCharSequence("\b", "\\b"); - addEscapedCharSequence("\n", "\\n"); - addEscapedCharSequence("\r", "\\r"); - addEscapedCharSequence("\t", "\\t"); - addEscapedCharSequence("\u001A", "\\Z"); - addEscapedCharSequence("%", "\\%"); - addEscapedCharSequence("_", "\\_"); - } - - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { - print("DROP TABLE IF EXISTS "); - printIdentifier(getTableName(table)); - printEndOfStatement(); - } - - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { - print("AUTO_INCREMENT"); - } - - /* - * {@inheritDoc} - */ - protected boolean shouldGeneratePrimaryKeys(Column[] primaryKeyColumns) - { - // mySQL requires primary key indication for autoincrement key columns - // I'm not sure why the default skips the pk statement if all are identity - return true; - } - - /* - * {@inheritDoc} - * Normally mysql will return the LAST_INSERT_ID as the column name for the inserted id. - * Since ddlutils expects the real column name of the field that is autoincrementing, the - * column has an alias of that column name. - */ - public String getSelectLastIdentityValues(Table table) - { - String autoIncrementKeyName = ""; - if (table.getAutoIncrementColumns().length > 0) - { - autoIncrementKeyName = table.getAutoIncrementColumns()[0].getName(); - } - return "SELECT LAST_INSERT_ID() " + autoIncrementKeyName; - } - - /* - * {@inheritDoc} - */ - protected void writeTableCreationStmtEnding(Table table, Map parameters) throws IOException - { - if (parameters != null) - { - print(" "); - // MySql supports additional table creation options which are appended - // at the end of the CREATE TABLE statement - for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - - print(entry.getKey().toString()); - if (entry.getValue() != null) - { - print("="); - print(entry.getValue().toString()); - } - if (it.hasNext()) - { - print(" "); - } - } - } - super.writeTableCreationStmtEnding(table, parameters); - } - - /* - * {@inheritDoc} - */ - protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) throws IOException - { - writeTableAlterStmt(table); - print("DROP FOREIGN KEY "); - printIdentifier(getForeignKeyName(table, foreignKey)); - printEndOfStatement(); - - if (foreignKey.isAutoIndexPresent()) - { - writeTableAlterStmt(table); - print("DROP INDEX "); - printIdentifier(getForeignKeyName(table, foreignKey)); - printEndOfStatement(); - } - } - - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { - // in order to utilize the ALTER TABLE ADD COLUMN AFTER statement - // we have to apply the add column changes in the correct order - // thus we first gather all add column changes and then execute them - ArrayList addColumnChanges = new ArrayList(); - - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddColumnChange) - { - addColumnChanges.add((AddColumnChange)change); - changeIt.remove(); - } - } - for (Iterator changeIt = addColumnChanges.iterator(); changeIt.hasNext();) - { - AddColumnChange addColumnChange = (AddColumnChange)changeIt.next(); - - processChange(currentModel, desiredModel, addColumnChange); - changeIt.remove(); - } - - ListOrderedSet changedColumns = new ListOrderedSet(); - - // we don't have to care about the order because the comparator will have ensured - // that a add primary key change comes after all necessary columns are present - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof RemoveColumnChange) - { - processChange(currentModel, desiredModel, (RemoveColumnChange)change); - changeIt.remove(); - } - else if (change instanceof AddPrimaryKeyChange) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); - changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - processChange(currentModel, desiredModel, (PrimaryKeyChange)change); - changeIt.remove(); - } - else if (change instanceof RemovePrimaryKeyChange) - { - processChange(currentModel, desiredModel, (RemovePrimaryKeyChange)change); - changeIt.remove(); - } - else if (change instanceof ColumnChange) - { - // we gather all changed columns because we can use the ALTER TABLE MODIFY COLUMN - // statement for them - changedColumns.add(((ColumnChange)change).getChangedColumn()); - changeIt.remove(); - } - } - for (Iterator columnIt = changedColumns.iterator(); columnIt.hasNext();) - { - Column sourceColumn = (Column)columnIt.next(); - Column targetColumn = targetTable.findColumn(sourceColumn.getName(), getPlatform().isDelimitedIdentifierModeOn()); - - processColumnChange(sourceTable, targetTable, sourceColumn, targetColumn); - } - } - - /* - * Processes the addition of a column to a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("ADD COLUMN "); - writeColumn(change.getChangedTable(), change.getNewColumn()); - if (change.getPreviousColumn() != null) - { - print(" AFTER "); - printIdentifier(getColumnName(change.getPreviousColumn())); - } - else - { - print(" FIRST"); - } - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a column from a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP COLUMN "); - printIdentifier(getColumnName(change.getColumn())); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a primary key from a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - RemovePrimaryKeyChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP PRIMARY KEY"); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the change of the primary key of a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - PrimaryKeyChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP PRIMARY KEY"); - printEndOfStatement(); - writeExternalPrimaryKeysCreateStmt(change.getChangedTable(), change.getNewPrimaryKeyColumns()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes a change to a column. - * - * @param sourceTable The current table - * @param targetTable The desired table - * @param sourceColumn The current column - * @param targetColumn The desired column - */ - protected void processColumnChange(Table sourceTable, - Table targetTable, - Column sourceColumn, - Column targetColumn) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(sourceTable)); - printIndent(); - print("MODIFY COLUMN "); - writeColumn(targetTable, targetColumn); - printEndOfStatement(); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlPlatform.java deleted file mode 100644 index f516c69b7f..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlPlatform.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.mysql; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform implementation for MySQL. - * - * @version $Revision: 231306 $ - */ -public class MySqlPlatform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "MySQL"; - /* The standard MySQL jdbc driver. */ - public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; - /* The old MySQL jdbc driver. */ - public static final String JDBC_DRIVER_OLD = "org.gjt.mm.mysql.Driver"; - /* The subprotocol used by the standard MySQL driver. */ - public static final String JDBC_SUBPROTOCOL = "mysql"; - - /* - * Creates a new platform instance. - */ - public MySqlPlatform() - { - PlatformInfo info = getPlatformInfo(); - - info.setMaxIdentifierLength(64); - info.setNullAsDefaultValueRequired(true); - info.setDefaultValuesForLongTypesSupported(false); - // see http://dev.mysql.com/doc/refman/4.1/en/example-auto-increment.html - info.setNonPKIdentityColumnsSupported(false); - // MySql returns synthetic default values for pk columns - info.setSyntheticDefaultValueForRequiredReturned(true); - info.setCommentPrefix("#"); - // Double quotes are only allowed for delimiting identifiers if the server SQL mode includes ANSI_QUOTES - info.setDelimiterToken("`"); - - info.addNativeTypeMapping(Types.ARRAY, "LONGBLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.BIT, "TINYINT(1)"); - info.addNativeTypeMapping(Types.BLOB, "LONGBLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.CLOB, "LONGTEXT", Types.LONGVARCHAR); - info.addNativeTypeMapping(Types.DISTINCT, "LONGBLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "LONGBLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.LONGVARBINARY, "MEDIUMBLOB"); - info.addNativeTypeMapping(Types.LONGVARCHAR, "MEDIUMTEXT"); - info.addNativeTypeMapping(Types.NULL, "MEDIUMBLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.NUMERIC, "DECIMAL", Types.DECIMAL); - info.addNativeTypeMapping(Types.OTHER, "LONGBLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.REAL, "FLOAT"); - info.addNativeTypeMapping(Types.REF, "MEDIUMBLOB", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "LONGBLOB", Types.LONGVARBINARY); - // Since TIMESTAMP is not a stable datatype yet, and does not support a higher precision - // than DATETIME (year to seconds) as of MySQL 5, we map the JDBC type here to DATETIME - // TODO: Make this configurable - info.addNativeTypeMapping(Types.TIMESTAMP, "DATETIME"); - // In MySql, TINYINT has only a range of -128 to 127 - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping("BOOLEAN", "TINYINT(1)", "BIT"); - info.addNativeTypeMapping("DATALINK", "MEDIUMBLOB", "LONGVARBINARY"); - - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARCHAR, 254); - info.setDefaultSize(Types.BINARY, 254); - info.setDefaultSize(Types.VARBINARY, 254); - - setDelimitedIdentifierModeOn(true); - setSqlBuilder(new MySqlBuilder(this)); - setModelReader(new MySqlModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Builder.java deleted file mode 100644 index 9ab5712311..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Builder.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.oracle; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; - -/* - * The SQL builder for Oracle 10. - * - * @version $Revision: $ - */ -public class Oracle10Builder extends Oracle8Builder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public Oracle10Builder(Platform platform) - { - super(platform); - } - - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { - // The only difference to the Oracle 8/9 variant is the purge which prevents the - // table from being moved to the recycle bin (which is new in Oracle 10) - Column[] columns = table.getAutoIncrementColumns(); - - for (int idx = 0; idx < columns.length; idx++) - { - dropAutoIncrementTrigger(table, columns[idx]); - dropAutoIncrementSequence(table, columns[idx]); - } - - print("DROP TABLE "); - printIdentifier(getTableName(table)); - print(" CASCADE CONSTRAINTS PURGE"); - printEndOfStatement(); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Platform.java deleted file mode 100644 index b46cd856de..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle10Platform.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.oracle; - - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * The platform for Oracle 10. - */ -public class Oracle10Platform extends Oracle9Platform -{ - /* Database name of this platform. */ - public static final String DATABASENAME10 = "Oracle10"; - public static final String DATABASENAME11 = "Oracle11"; - - /* - * Creates a new platform instance. - */ - public Oracle10Platform() - { - super(); - setSqlBuilder(new Oracle10Builder(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Builder.java deleted file mode 100644 index c56eaa64fe..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Builder.java +++ /dev/null @@ -1,524 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.oracle; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.sql.Types; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.oro.text.regex.MalformedPatternException; -import org.apache.oro.text.regex.Pattern; -import org.apache.oro.text.regex.PatternCompiler; -import org.apache.oro.text.regex.Perl5Compiler; -import org.apache.oro.text.regex.Perl5Matcher; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; - -/* - * The SQL Builder for Oracle. - * - * @version $Revision: 517050 $ - */ -public class Oracle8Builder extends SqlBuilder -{ - /* The regular expression pattern for ISO dates, i.e. 'YYYY-MM-DD'. */ - private Pattern _isoDatePattern; - /* The regular expression pattern for ISO times, i.e. 'HH:MI:SS'. */ - private Pattern _isoTimePattern; - /* The regular expression pattern for ISO timestamps, i.e. 'YYYY-MM-DD HH:MI:SS.fffffffff'. */ - private Pattern _isoTimestampPattern; - - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public Oracle8Builder(Platform platform) - { - super(platform); - addEscapedCharSequence("'", "''"); - - PatternCompiler compiler = new Perl5Compiler(); - - try - { - _isoDatePattern = compiler.compile("\\d{4}\\-\\d{2}\\-\\d{2}"); - _isoTimePattern = compiler.compile("\\d{2}:\\d{2}:\\d{2}"); - _isoTimestampPattern = compiler.compile("\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2}[\\.\\d{1,8}]?"); - } - catch (MalformedPatternException ex) - { - throw new DdlUtilsException(ex); - } - } - - /* - * {@inheritDoc} - */ - public void createTable(Database database, Table table, Map parameters) throws IOException - { - // lets create any sequences - Column[] columns = table.getAutoIncrementColumns(); - - for (int idx = 0; idx < columns.length; idx++) - { - createAutoIncrementSequence(table, columns[idx]); - } - - super.createTable(database, table, parameters); - - for (int idx = 0; idx < columns.length; idx++) - { - createAutoIncrementTrigger(table, columns[idx]); - } - } - - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { - Column[] columns = table.getAutoIncrementColumns(); - - for (int idx = 0; idx < columns.length; idx++) - { - dropAutoIncrementTrigger(table, columns[idx]); - dropAutoIncrementSequence(table, columns[idx]); - } - - print("DROP TABLE "); - printIdentifier(getTableName(table)); - print(" CASCADE CONSTRAINTS"); - printEndOfStatement(); - } - - /* - * Creates the sequence necessary for the auto-increment of the given column. - * - * @param table The table - * @param column The column - */ - protected void createAutoIncrementSequence(Table table, - Column column) throws IOException - { - print("CREATE SEQUENCE "); - printIdentifier(getConstraintName("seq", table, column.getName(), null)); - printEndOfStatement(); - } - - /* - * Creates the trigger necessary for the auto-increment of the given column. - * - * @param table The table - * @param column The column - */ - protected void createAutoIncrementTrigger(Table table, - Column column) throws IOException - { - String columnName = getColumnName(column); - String triggerName = getConstraintName("trg", table, column.getName(), null); - - if (getPlatform().isScriptModeOn()) - { - // For the script, we output a more nicely formatted version - print("CREATE OR REPLACE TRIGGER "); - printlnIdentifier(triggerName); - print("BEFORE INSERT ON "); - printlnIdentifier(getTableName(table)); - print("FOR EACH ROW WHEN (new."); - printIdentifier(columnName); - println(" IS NULL)"); - println("BEGIN"); - print(" SELECT "); - printIdentifier(getConstraintName("seq", table, column.getName(), null)); - print(".nextval INTO :new."); - printIdentifier(columnName); - print(" FROM dual"); - println(getPlatformInfo().getSqlCommandDelimiter()); - print("END"); - println(getPlatformInfo().getSqlCommandDelimiter()); - println("/"); - println(); - } - else - { - // note that the BEGIN ... SELECT ... END; is all in one line and does - // not contain a semicolon except for the END-one - // this way, the tokenizer will not split the statement before the END - print("CREATE OR REPLACE TRIGGER "); - printIdentifier(triggerName); - print(" BEFORE INSERT ON "); - printIdentifier(getTableName(table)); - print(" FOR EACH ROW WHEN (new."); - printIdentifier(columnName); - println(" IS NULL)"); - print("BEGIN SELECT "); - printIdentifier(getConstraintName("seq", table, column.getName(), null)); - print(".nextval INTO :new."); - printIdentifier(columnName); - print(" FROM dual"); - print(getPlatformInfo().getSqlCommandDelimiter()); - print(" END"); - // It is important that there is a semicolon at the end of the statement (or more - // precisely, at the end of the PL/SQL block), and thus we put two semicolons here - // because the tokenizer will remove the one at the end - print(getPlatformInfo().getSqlCommandDelimiter()); - printEndOfStatement(); - } - } - - /* - * Drops the sequence used for the auto-increment of the given column. - * - * @param table The table - * @param column The column - */ - protected void dropAutoIncrementSequence(Table table, - Column column) throws IOException - { - print("DROP SEQUENCE "); - printIdentifier(getConstraintName("seq", table, column.getName(), null)); - printEndOfStatement(); - } - - /* - * Drops the trigger used for the auto-increment of the given column. - * - * @param table The table - * @param column The column - */ - protected void dropAutoIncrementTrigger(Table table, - Column column) throws IOException - { - print("DROP TRIGGER "); - printIdentifier(getConstraintName("trg", table, column.getName(), null)); - printEndOfStatement(); - } - - /* - * {@inheritDoc} - */ - protected void createTemporaryTable(Database database, Table table, Map parameters) throws IOException - { - createTable(database, table, parameters); - } - - /* - * {@inheritDoc} - */ - protected void dropTemporaryTable(Database database, Table table) throws IOException - { - dropTable(table); - } - - /* - * {@inheritDoc} - */ - public void dropExternalForeignKeys(Table table) throws IOException - { - // no need to as we drop the table with CASCASE CONSTRAINTS - } - - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { - // Index names in Oracle are unique to a schema and hence Oracle does not - // use the ON clause - print("DROP INDEX "); - printIdentifier(getIndexName(index)); - printEndOfStatement(); - } - - /* - * {@inheritDoc} - */ - protected void printDefaultValue(Object defaultValue, int typeCode) throws IOException - { - if (defaultValue != null) - { - String defaultValueStr = defaultValue.toString(); - boolean shouldUseQuotes = !TypeMap.isNumericType(typeCode) && !defaultValueStr.startsWith("TO_DATE("); - - if (shouldUseQuotes) - { - // characters are only escaped when within a string literal - print(getPlatformInfo().getValueQuoteToken()); - print(escapeStringValue(defaultValueStr)); - print(getPlatformInfo().getValueQuoteToken()); - } - else - { - print(defaultValueStr); - } - } - } - - /* - * {@inheritDoc} - */ - protected String getNativeDefaultValue(Column column) - { - if ((column.getTypeCode() == Types.BIT) || - (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode()))) - { - return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString(); - } - // Oracle does not accept ISO formats, so we have to convert an ISO spec if we find one - // But these are the only formats that we make sure work, every other format has to be database-dependent - // and thus the user has to ensure that it is correct - else if (column.getTypeCode() == Types.DATE) - { - if (new Perl5Matcher().matches(column.getDefaultValue(), _isoDatePattern)) - { - return "TO_DATE('"+column.getDefaultValue()+"', 'YYYY-MM-DD')"; - } - } - else if (column.getTypeCode() == Types.TIME) - { - if (new Perl5Matcher().matches(column.getDefaultValue(), _isoTimePattern)) - { - return "TO_DATE('"+column.getDefaultValue()+"', 'HH24:MI:SS')"; - } - } - else if (column.getTypeCode() == Types.TIMESTAMP) - { - if (new Perl5Matcher().matches(column.getDefaultValue(), _isoTimestampPattern)) - { - return "TO_DATE('"+column.getDefaultValue()+"', 'YYYY-MM-DD HH24:MI:SS')"; - } - } - return super.getNativeDefaultValue(column); - } - - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { - // we're using sequences instead - } - - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { - Column[] columns = table.getAutoIncrementColumns(); - - if (columns.length > 0) - { - StringBuffer result = new StringBuffer(); - - result.append("SELECT "); - for (int idx = 0; idx < columns.length; idx++) - { - if (idx > 0) - { - result.append(","); - } - result.append(getDelimitedIdentifier(getConstraintName("seq", table, columns[idx].getName(), null))); - result.append(".currval"); - } - result.append(" FROM dual"); - return result.toString(); - } - else - { - return null; - } - } - - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { - // While Oracle has an ALTER TABLE MODIFY statement, it is somewhat limited - // esp. if there is data in the table, so we don't use it - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; - - // Oracle can only add not insert columns - // Also, we cannot add NOT NULL columns unless they have a default value - if (!addColumnChange.isAtEnd() || - (addColumnChange.getNewColumn().isRequired() && (addColumnChange.getNewColumn().getDefaultValue() == null))) - { - // we need to rebuild the full table - return; - } - } - } - - // First we drop primary keys as necessary - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof RemovePrimaryKeyChange) - { - processChange(currentModel, desiredModel, (RemovePrimaryKeyChange)change); - changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - PrimaryKeyChange pkChange = (PrimaryKeyChange)change; - RemovePrimaryKeyChange removePkChange = new RemovePrimaryKeyChange(pkChange.getChangedTable(), - pkChange.getOldPrimaryKeyColumns()); - - processChange(currentModel, desiredModel, removePkChange); - } - } - - // Next we add/remove columns - // While Oracle has an ALTER TABLE MODIFY statement, it is somewhat limited - // esp. if there is data in the table, so we don't use it - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddColumnChange) - { - processChange(currentModel, desiredModel, (AddColumnChange)change); - changeIt.remove(); - } - else if (change instanceof RemoveColumnChange) - { - processChange(currentModel, desiredModel, (RemoveColumnChange)change); - changeIt.remove(); - } - } - // Finally we add primary keys - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - - if (change instanceof AddPrimaryKeyChange) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); - changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - PrimaryKeyChange pkChange = (PrimaryKeyChange)change; - AddPrimaryKeyChange addPkChange = new AddPrimaryKeyChange(pkChange.getChangedTable(), - pkChange.getNewPrimaryKeyColumns()); - - processChange(currentModel, desiredModel, addPkChange); - changeIt.remove(); - } - } - } - - /* - * Processes the addition of a column to a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("ADD "); - writeColumn(change.getChangedTable(), change.getNewColumn()); - printEndOfStatement(); - if (change.getNewColumn().isAutoIncrement()) - { - createAutoIncrementSequence(change.getChangedTable(), change.getNewColumn()); - createAutoIncrementTrigger(change.getChangedTable(), change.getNewColumn()); - } - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a column from a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { - if (change.getColumn().isAutoIncrement()) - { - dropAutoIncrementTrigger(change.getChangedTable(), change.getColumn()); - dropAutoIncrementSequence(change.getChangedTable(), change.getColumn()); - } - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP COLUMN "); - printIdentifier(getColumnName(change.getColumn())); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } - - /* - * Processes the removal of a primary key from a table. - * - * @param currentModel The current database schema - * @param desiredModel The desired database schema - * @param change The change object - */ - protected void processChange(Database currentModel, - Database desiredModel, - RemovePrimaryKeyChange change) throws IOException - { - print("ALTER TABLE "); - printlnIdentifier(getTableName(change.getChangedTable())); - printIndent(); - print("DROP PRIMARY KEY"); - printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Platform.java deleted file mode 100644 index cb6e5ccc46..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle8Platform.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.oracle; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform for Oracle 8. - * - * TODO: We might support the {@link org.jumpmind.symmetric.ddl.Platform#createDatabase(String, String, String, String, Map)} - * functionality via "CREATE SCHEMA"/"CREATE USER" or "CREATE TABLESPACE" ? - * - * @version $Revision: 231306 $ - */ -public class Oracle8Platform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "Oracle"; - /* The standard Oracle jdbc driver. */ - public static final String JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver"; - /* The old Oracle jdbc driver. */ - public static final String JDBC_DRIVER_OLD = "oracle.jdbc.dnlddriver.OracleDriver"; - /* The thin subprotocol used by the standard Oracle driver. */ - public static final String JDBC_SUBPROTOCOL_THIN = "oracle:thin"; - /* The thin subprotocol used by the standard Oracle driver. */ - public static final String JDBC_SUBPROTOCOL_OCI8 = "oracle:oci8"; - /* The old thin subprotocol used by the standard Oracle driver. */ - public static final String JDBC_SUBPROTOCOL_THIN_OLD = "oracle:dnldthin"; - - /* - * Creates a new platform instance. - */ - public Oracle8Platform() - { - PlatformInfo info = getPlatformInfo(); - - info.setMaxIdentifierLength(30); - info.setIdentityStatusReadingSupported(false); - - // Note that the back-mappings are partially done by the model reader, not the driver - info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.BIGINT, "NUMBER(38)"); - info.addNativeTypeMapping(Types.BINARY, "RAW", Types.VARBINARY); - info.addNativeTypeMapping(Types.BIT, "NUMBER(1)"); - info.addNativeTypeMapping(Types.DATE, "DATE", Types.TIMESTAMP); - info.addNativeTypeMapping(Types.DECIMAL, "NUMBER"); - info.addNativeTypeMapping(Types.DISTINCT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); - info.addNativeTypeMapping(Types.FLOAT, "FLOAT", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.LONGVARBINARY, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.LONGVARCHAR, "CLOB", Types.CLOB); - info.addNativeTypeMapping(Types.NULL, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.NUMERIC, "NUMBER", Types.DECIMAL); - info.addNativeTypeMapping(Types.INTEGER, "NUMBER(22)", Types.DECIMAL); - info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.REF, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.SMALLINT, "NUMBER(5)"); - info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.BLOB); - info.addNativeTypeMapping(Types.TIME, "DATE", Types.DATE); - info.addNativeTypeMapping(Types.TIMESTAMP, "DATE"); - info.addNativeTypeMapping(Types.TINYINT, "NUMBER(3)"); - info.addNativeTypeMapping(Types.VARBINARY, "RAW"); - info.addNativeTypeMapping(Types.VARCHAR, "VARCHAR2"); - - info.addNativeTypeMapping("BOOLEAN", "NUMBER(1)", "BIT"); - info.addNativeTypeMapping("DATALINK", "BLOB", "BLOB"); - - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARCHAR, 254); - info.setDefaultSize(Types.BINARY, 254); - info.setDefaultSize(Types.VARBINARY, 254); - - info.setStoresUpperCaseInCatalog(true); - - setSqlBuilder(new Oracle8Builder(this)); - setModelReader(new OracleModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle9Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle9Platform.java deleted file mode 100644 index 08d9b8df91..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/Oracle9Platform.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.oracle; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Types; - -/* - * The platform for Oracle 9. - * - * @version $Revision: 231306 $ - */ -public class Oracle9Platform extends Oracle8Platform -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "Oracle9"; - - /* - * Creates a new platform instance. - */ - public Oracle9Platform() - { - super(); - getPlatformInfo().addNativeTypeMapping(Types.TIMESTAMP, "TIMESTAMP"); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/OracleModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/OracleModelReader.java deleted file mode 100644 index da77d8de46..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/OracleModelReader.java +++ /dev/null @@ -1,401 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.oracle; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.collections.map.ListOrderedMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.oro.text.regex.MalformedPatternException; -import org.apache.oro.text.regex.Pattern; -import org.apache.oro.text.regex.PatternCompiler; -import org.apache.oro.text.regex.PatternMatcher; -import org.apache.oro.text.regex.Perl5Compiler; -import org.apache.oro.text.regex.Perl5Matcher; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; - -/* - * Reads a database model from an Oracle 8 database. - */ -public class OracleModelReader extends JdbcModelReader -{ - private final Log _log = LogFactory.getLog(OracleModelReader.class); - - /* The regular expression pattern for the Oracle conversion of ISO dates. */ - private Pattern _oracleIsoDatePattern; - /* The regular expression pattern for the Oracle conversion of ISO times. */ - private Pattern _oracleIsoTimePattern; - /* The regular expression pattern for the Oracle conversion of ISO timestamps. */ - private Pattern _oracleIsoTimestampPattern; - - /* - * Creates a new model reader for Oracle 8 databases. - * - * @param platform The platform that this model reader belongs to - */ - public OracleModelReader(Platform platform) - { - super(platform); - setDefaultCatalogPattern(null); - setDefaultSchemaPattern(null); - setDefaultTablePattern("%"); - - PatternCompiler compiler = new Perl5Compiler(); - - try - { - _oracleIsoDatePattern = compiler.compile("TO_DATE\\('([^']*)'\\, 'YYYY\\-MM\\-DD'\\)"); - _oracleIsoTimePattern = compiler.compile("TO_DATE\\('([^']*)'\\, 'HH24:MI:SS'\\)"); - _oracleIsoTimestampPattern = compiler.compile("TO_DATE\\('([^']*)'\\, 'YYYY\\-MM\\-DD HH24:MI:SS'\\)"); - } - catch (MalformedPatternException ex) - { - throw new DdlUtilsException(ex); - } - } - - @Override - protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, Map values) - throws SQLException { - // Oracle 10 added the recycle bin which contains dropped database - // objects not yet purged - // Since we don't want entries from the recycle bin, we filter them out - boolean tableHasBeenDeleted = isTableInRecycleBin(connection, values); - - if (!tableHasBeenDeleted) { - String tableName = (String) values.get("TABLE_NAME"); - - // system table ? - if (tableName.indexOf('$') > 0) { - return null; - } - - Table table = super.readTable(connection, metaData, values); - if (table != null) { - determineAutoIncrementColumns(connection, table); - } - - return table; - } else { - return null; - } - } - - protected boolean isTableInRecycleBin(Connection connection, Map values) throws SQLException { - ResultSet rs = null; - PreparedStatement stmt = null; - try { - stmt = connection.prepareStatement("SELECT * FROM RECYCLEBIN WHERE OBJECT_NAME=?"); - stmt.setString(1, (String) values.get("TABLE_NAME")); - - rs = stmt.executeQuery(); - return rs.next(); - } finally { - close(rs); - close(stmt); - } - } - - @Override - protected Integer overrideJdbcTypeForColumn(Map values) { - String typeName = (String) values.get("TYPE_NAME"); - if (typeName != null && typeName.startsWith("DATE")) { - return Types.DATE; - } else if (typeName != null && typeName.startsWith("TIMESTAMP")) { - // This is for Oracle's TIMESTAMP(9) - return Types.TIMESTAMP; - } else if (typeName != null && typeName.startsWith("NVARCHAR")) { - // This is for Oracle's NVARCHAR type - return Types.VARCHAR; - } else if (typeName != null && typeName.startsWith("LONGNVARCHAR")) { - return Types.LONGVARCHAR; - } else if (typeName != null && typeName.startsWith("NCHAR")) { - return Types.CHAR; - } else if (typeName != null && typeName.startsWith("NCLOB")) { - return Types.CLOB; - } else if (typeName != null && typeName.startsWith("BINARY_FLOAT")) { - return Types.FLOAT; - } else if (typeName != null && typeName.startsWith("BINARY_DOUBLE")) { - return Types.DOUBLE; - } else { - return super.overrideJdbcTypeForColumn(values); - } - } - - @Override - protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { - Column column = super.readColumn(metaData, values); - if (column.getTypeCode() == Types.DECIMAL) - { - // We're back-mapping the NUMBER columns returned by Oracle - // Note that the JDBC driver returns DECIMAL for these NUMBER columns - switch (column.getSizeAsInt()) - { - case 1: - if (column.getScale() == 0) - { - column.setTypeCode(Types.BIT); - } - break; - case 3: - if (column.getScale() == 0) - { - column.setTypeCode(Types.TINYINT); - } - break; - case 5: - if (column.getScale() == 0) - { - column.setTypeCode(Types.SMALLINT); - } - break; - case 18: - column.setTypeCode(Types.REAL); - break; - case 22: - if (column.getScale() == 0) - { - column.setTypeCode(Types.INTEGER); - } - break; - case 38: - if (column.getScale() == 0) - { - column.setTypeCode(Types.BIGINT); - } - else - { - column.setTypeCode(Types.DOUBLE); - } - break; - } - } - else if (column.getTypeCode() == Types.FLOAT) - { - // Same for REAL, FLOAT, DOUBLE PRECISION, which all back-map to FLOAT but with - // different sizes (63 for REAL, 126 for FLOAT/DOUBLE PRECISION) - switch (column.getSizeAsInt()) - { - case 63: - column.setTypeCode(Types.REAL); - break; - case 126: - column.setTypeCode(Types.DOUBLE); - break; - } - } - else if ((column.getTypeCode() == Types.DATE) || (column.getTypeCode() == Types.TIMESTAMP)) - { - // we also reverse the ISO-format adaptation, and adjust the default value to timestamp - if (column.getDefaultValue() != null) - { - PatternMatcher matcher = new Perl5Matcher(); - Timestamp timestamp = null; - - if (matcher.matches(column.getDefaultValue(), _oracleIsoTimestampPattern)) - { - String timestampVal = matcher.getMatch().group(1); - - timestamp = Timestamp.valueOf(timestampVal); - } - else if (matcher.matches(column.getDefaultValue(), _oracleIsoDatePattern)) - { - String dateVal = matcher.getMatch().group(1); - - timestamp = new Timestamp(Date.valueOf(dateVal).getTime()); - } - else if (matcher.matches(column.getDefaultValue(), _oracleIsoTimePattern)) - { - String timeVal = matcher.getMatch().group(1); - - timestamp = new Timestamp(Time.valueOf(timeVal).getTime()); - } - if (timestamp != null) - { - column.setDefaultValue(timestamp.toString()); - } - } - } - else if (TypeMap.isTextType(column.getTypeCode())) - { - column.setDefaultValue(unescape(column.getDefaultValue(), "'", "''")); - } - return column; - } - - /* - * Helper method that determines the auto increment status using Firebird's system tables. - * - * @param table The table - */ - protected void determineAutoIncrementColumns(Connection connection, Table table) throws SQLException - { - Column[] columns = table.getColumns(); - - for (int idx = 0; idx < columns.length; idx++) - { - columns[idx].setAutoIncrement(isAutoIncrement(connection, table, columns[idx])); - } - } - - /* - * Tries to determine whether the given column is an identity column. - * - * @param table The table - * @param column The column - * @return true if the column is an identity column - */ - protected boolean isAutoIncrement(Connection connection, Table table, Column column) throws SQLException - { - // TODO: For now, we only check whether there is a sequence & trigger as generated by DdlUtils - // But once sequence/trigger support is in place, it might be possible to 'parse' the - // trigger body (via SELECT trigger_name, trigger_body FROM user_triggers) in order to - // determine whether it fits our auto-increment definition - PreparedStatement prepStmt = null; - String triggerName = getPlatform().getSqlBuilder().getConstraintName("trg", table, column.getName(), null); - String seqName = getPlatform().getSqlBuilder().getConstraintName("seq", table, column.getName(), null); - - if (!getPlatform().isDelimitedIdentifierModeOn()) - { - triggerName = triggerName.toUpperCase(); - seqName = seqName.toUpperCase(); - } - try - { - prepStmt = connection.prepareStatement("SELECT * FROM user_triggers WHERE trigger_name = ?"); - prepStmt.setString(1, triggerName); - - ResultSet resultSet = prepStmt.executeQuery(); - - if (!resultSet.next()) - { - return false; - } - // we have a trigger, so lets check the sequence - prepStmt.close(); - - prepStmt = connection.prepareStatement("SELECT * FROM user_sequences WHERE sequence_name = ?"); - prepStmt.setString(1, seqName); - - resultSet = prepStmt.executeQuery(); - return resultSet.next(); - } - finally - { - if (prepStmt != null) - { - prepStmt.close(); - } - } - } - - @Override - protected Collection readIndices(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException - { - // Oracle bug 4999817 causes a table analyze to execute in response to a call to - // DatabaseMetaData#getIndexInfo. - // The bug is fixed in driver version 10.2.0.4. The bug is present in at least - // driver versions 10.2.0.1.0, 10.1.0.2.0, and 9.2.0.5. - // To avoid this bug, we will access user_indexes view. - // This also allows us to filter system-generated indices which are identified by either - // having GENERATED='Y' in the query result, or by their index names being equal to the - // name of the primary key of the table - - StringBuffer query = new StringBuffer(); - - query.append("SELECT a.INDEX_NAME, a.INDEX_TYPE, a.UNIQUENESS, b.COLUMN_NAME, b.COLUMN_POSITION FROM USER_INDEXES a, USER_IND_COLUMNS b WHERE "); - query.append("a.TABLE_NAME=? AND a.GENERATED=? AND a.TABLE_TYPE=? AND a.TABLE_NAME=b.TABLE_NAME AND a.INDEX_NAME=b.INDEX_NAME AND "); - query.append("a.INDEX_NAME NOT IN (SELECT DISTINCT c.CONSTRAINT_NAME FROM USER_CONSTRAINTS c WHERE c.CONSTRAINT_TYPE=? AND c.TABLE_NAME=a.TABLE_NAME"); - if (metaData.getSchemaPattern() != null) - { - query.append(" AND c.OWNER LIKE ?) AND a.TABLE_OWNER LIKE ?"); - } - else - { - query.append(")"); - } - - Map indices = new ListOrderedMap(); - PreparedStatement stmt = null; - - try - { - stmt = connection.prepareStatement(query.toString()); - stmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName.toUpperCase()); - stmt.setString(2, "N"); - stmt.setString(3, "TABLE"); - stmt.setString(4, "P"); - if (metaData.getSchemaPattern() != null) - { - stmt.setString(5, metaData.getSchemaPattern().toUpperCase()); - stmt.setString(6, metaData.getSchemaPattern().toUpperCase()); - } - - ResultSet rs = stmt.executeQuery(); - Map values = new HashMap(); - - while (rs.next()) - { - String name =rs.getString(1); - String type = rs.getString(2); - // Only read in normal oracle indexes - if (type.startsWith("NORMAL")) - { - values.put("INDEX_TYPE", new Short(DatabaseMetaData.tableIndexOther)); - values.put("INDEX_NAME", name); - values.put("NON_UNIQUE", "UNIQUE".equalsIgnoreCase(rs.getString(3)) ? Boolean.FALSE : Boolean.TRUE); - values.put("COLUMN_NAME", rs.getString(4)); - values.put("ORDINAL_POSITION", new Short(rs.getShort(5))); - - readIndex(metaData, values, indices); - } else { - _log.warn("Skipping index " + name + " of type " + type); - } - } - } - finally - { - if (stmt != null) - { - stmt.close(); - } - } - return indices.values(); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlPlatform.java deleted file mode 100644 index ac4c133db3..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlPlatform.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.postgresql; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; -import java.util.Iterator; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.DatabaseOperationException; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform implementation for PostgresSql. - * - * @version $Revision: 231306 $ - */ -public class PostgreSqlPlatform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "PostgreSql"; - /* The standard PostgreSQL jdbc driver. */ - public static final String JDBC_DRIVER = "org.postgresql.Driver"; - /* The subprotocol used by the standard PostgreSQL driver. */ - public static final String JDBC_SUBPROTOCOL = "postgresql"; - - /* - * Creates a new platform instance. - */ - public PostgreSqlPlatform() - { - PlatformInfo info = getPlatformInfo(); - - // this is the default length though it might be changed when building PostgreSQL - // in file src/include/postgres_ext.h - info.setMaxIdentifierLength(31); - - info.addNativeTypeMapping(Types.ARRAY, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.BINARY, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.BIT, "BOOLEAN"); - info.addNativeTypeMapping(Types.BLOB, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.CLOB, "TEXT", Types.LONGVARCHAR); - info.addNativeTypeMapping(Types.DECIMAL, "NUMERIC", Types.NUMERIC); - info.addNativeTypeMapping(Types.DISTINCT, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE PRECISION", Types.DOUBLE); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.LONGVARBINARY, "BYTEA"); - info.addNativeTypeMapping(Types.LONGVARCHAR, "TEXT", Types.LONGVARCHAR); - info.addNativeTypeMapping(Types.NULL, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.OTHER, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.REF, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.VARBINARY, "BYTEA", Types.LONGVARBINARY); - info.addNativeTypeMapping("BOOLEAN", "BOOLEAN", "BIT"); - info.addNativeTypeMapping("DATALINK", "BYTEA", "LONGVARBINARY"); - - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARCHAR, 254); - - // no support for specifying the size for these types (because they are mapped - // to BYTEA which back-maps to BLOB) - info.setHasSize(Types.BINARY, false); - info.setHasSize(Types.VARBINARY, false); - - setDelimitedIdentifierModeOn(true); - - setSqlBuilder(new PostgreSqlBuilder(this)); - setModelReader(new PostgreSqlModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } - - /* - * Creates or drops the database referenced by the given connection url. - * - * @param jdbcDriverClassName The jdbc driver class name - * @param connectionUrl The url to connect to the database if it were already created - * @param username The username for creating the database - * @param password The password for creating the database - * @param parameters Additional parameters for the operation - * @param createDb Whether to create or drop the database - */ - private void createOrDropDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password, Map parameters, boolean createDb) throws DatabaseOperationException, UnsupportedOperationException - { - if (JDBC_DRIVER.equals(jdbcDriverClassName)) - { - int slashPos = connectionUrl.lastIndexOf('/'); - - if (slashPos < 0) - { - throw new DatabaseOperationException("Cannot parse the given connection url "+connectionUrl); - } - - int paramPos = connectionUrl.lastIndexOf('?'); - String baseDb = connectionUrl.substring(0, slashPos + 1) + "template1"; - String dbName = (paramPos > slashPos ? connectionUrl.substring(slashPos + 1, paramPos) : connectionUrl.substring(slashPos + 1)); - Connection connection = null; - Statement stmt = null; - StringBuffer sql = new StringBuffer(); - - sql.append(createDb ? "CREATE" : "DROP"); - sql.append(" DATABASE "); - sql.append(dbName); - if ((parameters != null) && !parameters.isEmpty()) - { - for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - - sql.append(" "); - sql.append(entry.getKey().toString()); - if (entry.getValue() != null) - { - sql.append(" "); - sql.append(entry.getValue().toString()); - } - } - } - if (getLog().isDebugEnabled()) - { - getLog().debug("About to create database via "+baseDb+" using this SQL: "+sql.toString()); - } - try - { - Class.forName(jdbcDriverClassName); - - connection = DriverManager.getConnection(baseDb, username, password); - stmt = connection.createStatement(); - stmt.execute(sql.toString()); - logWarnings(connection); - } - catch (Exception ex) - { - throw new DatabaseOperationException("Error while trying to " + (createDb ? "create" : "drop") + " a database: "+ex.getLocalizedMessage(), ex); - } - finally - { - if (stmt != null) - { - try - { - stmt.close(); - } - catch (SQLException ex) - {} - } - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException ex) - {} - } - } - } - else - { - throw new UnsupportedOperationException("Unable to " + (createDb ? "create" : "drop") + " a PostgreSQL database via the driver "+jdbcDriverClassName); - } - } - - /* - * {@inheritDoc} - */ - public void createDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password, Map parameters) throws DatabaseOperationException, UnsupportedOperationException - { - // With PostgreSQL, you create a database by executing "CREATE DATABASE" in an existing database (usually - // the template1 database because it usually exists) - createOrDropDatabase(jdbcDriverClassName, connectionUrl, username, password, parameters, true); - } - - /* - * {@inheritDoc} - */ - public void dropDatabase(String jdbcDriverClassName, String connectionUrl, String username, String password) throws DatabaseOperationException, UnsupportedOperationException - { - // With PostgreSQL, you create a database by executing "DROP DATABASE" in an existing database (usually - // the template1 database because it usually exists) - createOrDropDatabase(jdbcDriverClassName, connectionUrl, username, password, null, false); - } - -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseASE15Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseASE15Platform.java deleted file mode 100644 index 94aa205d16..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseASE15Platform.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.sybase; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * The platform implementation for Sybase ASE 15 and above. - * - * @version $Revision: $ - */ -public class SybaseASE15Platform extends SybasePlatform -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "SybaseASE15"; - - /* - * Creates a new platform instance. - */ - public SybaseASE15Platform() - { - super(); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybasePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybasePlatform.java deleted file mode 100644 index 992de34826..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybasePlatform.java +++ /dev/null @@ -1,296 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.platform.sybase; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.jumpmind.symmetric.db.ddl.DatabaseOperationException; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; - -/* - * The platform implementation for Sybase. - * - * @version $Revision: 231306 $ - */ -public class SybasePlatform extends PlatformImplBase -{ - /* Database name of this platform. */ - public static final String DATABASENAME = "Sybase"; - /* The standard Sybase jdbc driver. */ - public static final String JDBC_DRIVER = "com.sybase.jdbc2.jdbc.SybDriver"; - /* The old Sybase jdbc driver. */ - public static final String JDBC_DRIVER_OLD = "com.sybase.jdbc.SybDriver"; - /* The subprotocol used by the standard Sybase driver. */ - public static final String JDBC_SUBPROTOCOL = "sybase:Tds"; - - /* The maximum size that text and binary columns can have. */ - public static final long MAX_TEXT_SIZE = 2147483647; - - /* - * Creates a new platform instance. - */ - public SybasePlatform() - { - PlatformInfo info = getPlatformInfo(); - - info.setMaxIdentifierLength(128); - info.setNullAsDefaultValueRequired(true); - info.setCommentPrefix("/*"); - info.setCommentSuffix("*/"); - info.setDelimiterToken("\""); - setDelimitedIdentifierModeOn(true); - - info.addNativeTypeMapping(Types.ARRAY, "IMAGE"); - // BIGINT is mapped back in the model reader - info.addNativeTypeMapping(Types.BIGINT, "DECIMAL(19,0)"); - // we're not using the native BIT type because it is rather limited (cannot be NULL, cannot be indexed) - info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping(Types.BLOB, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.CLOB, "TEXT", Types.LONGVARCHAR); - info.addNativeTypeMapping(Types.DATE, "DATETIME", Types.TIMESTAMP); - info.addNativeTypeMapping(Types.DISTINCT, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); - info.addNativeTypeMapping(Types.FLOAT, "DOUBLE PRECISION", Types.DOUBLE); - info.addNativeTypeMapping(Types.INTEGER, "INT"); - info.addNativeTypeMapping(Types.JAVA_OBJECT, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.LONGVARBINARY, "IMAGE"); - info.addNativeTypeMapping(Types.LONGVARCHAR, "TEXT"); - info.addNativeTypeMapping(Types.NULL, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.OTHER, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.REF, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.STRUCT, "IMAGE", Types.LONGVARBINARY); - info.addNativeTypeMapping(Types.TIME, "DATETIME", Types.TIMESTAMP); - info.addNativeTypeMapping(Types.TIMESTAMP, "DATETIME", Types.TIMESTAMP); - info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); - info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); - info.addNativeTypeMapping("DATALINK", "IMAGE", "LONGVARBINARY"); - - info.setDefaultSize(Types.BINARY, 254); - info.setDefaultSize(Types.VARBINARY, 254); - info.setDefaultSize(Types.CHAR, 254); - info.setDefaultSize(Types.VARCHAR, 254); - - setSqlBuilder(new SybaseBuilder(this)); - setModelReader(new SybaseModelReader(this)); - } - - /* - * {@inheritDoc} - */ - public String getName() - { - return DATABASENAME; - } - - /* - * Sets the text size which is the maximum amount of bytes that Sybase returns in a SELECT statement - * for binary/text columns (e.g. blob, longvarchar etc.). - * - * @param size The size to set - */ - private void setTextSize(long size) - { - Connection connection = borrowConnection(); - Statement stmt = null; - - try - { - stmt = connection.createStatement(); - - stmt.execute("SET textsize "+size); - } - catch (SQLException ex) - { - throw new DatabaseOperationException(ex); - } - finally - { - closeStatement(stmt); - returnConnection(connection); - } - } - - /* - * {@inheritDoc} - */ - protected Object extractColumnValue(ResultSet resultSet, String columnName, int columnIdx, int jdbcType) throws DatabaseOperationException, SQLException - { - boolean useIdx = (columnName == null); - - if ((jdbcType == Types.LONGVARBINARY) || (jdbcType == Types.BLOB)) - { - InputStream stream = useIdx ? resultSet.getBinaryStream(columnIdx) : resultSet.getBinaryStream(columnName); - - if (stream == null) - { - return null; - } - else - { - byte[] buf = new byte[65536]; - byte[] result = new byte[0]; - int len; - - try - { - do - { - len = stream.read(buf); - if (len > 0) - { - byte[] newResult = new byte[result.length + len]; - - System.arraycopy(result, 0, newResult, 0, result.length); - System.arraycopy(buf, 0, newResult, result.length, len); - result = newResult; - } - } - while (len > 0); - stream.close(); - return result; - } - catch (IOException ex) - { - throw new DatabaseOperationException("Error while extracting the value of column " + columnName + " of type " + - TypeMap.getJdbcTypeName(jdbcType) + " from a result set", ex); - } - } - } - else - { - return super.extractColumnValue(resultSet, columnName, columnIdx, jdbcType); - } - } - - /* - * {@inheritDoc} - */ - protected void setStatementParameterValue(PreparedStatement statement, int sqlIndex, int typeCode, Object value) throws SQLException - { - if ((typeCode == Types.BLOB) || (typeCode == Types.LONGVARBINARY)) - { - // jConnect doesn't like the BLOB type, but works without problems with LONGVARBINARY - // even when using the Blob class - if (value instanceof byte[]) - { - byte[] data = (byte[])value; - - statement.setBinaryStream(sqlIndex, new ByteArrayInputStream(data), data.length); - } - else - { - // Sybase doesn't like the BLOB type, but works without problems with LONGVARBINARY - // even when using the Blob class - super.setStatementParameterValue(statement, sqlIndex, Types.LONGVARBINARY, value); - } - } - else if (typeCode == Types.CLOB) - { - // Same for CLOB and LONGVARCHAR - super.setStatementParameterValue(statement, sqlIndex, Types.LONGVARCHAR, value); - } - else - { - super.setStatementParameterValue(statement, sqlIndex, typeCode, value); - } - } - - /* - * Determines whether we need to use identity override mode for the given table. - * - * @param table The table - * @return true if identity override mode is needed - */ - private boolean useIdentityOverrideFor(Table table) - { - return isIdentityOverrideOn() && - getPlatformInfo().isIdentityOverrideAllowed() && - (table.getAutoIncrementColumns().length > 0); - } - - /* - * {@inheritDoc} - */ - protected void beforeInsert(Connection connection, Table table) throws SQLException - { - if (useIdentityOverrideFor(table)) - { - SybaseBuilder builder = (SybaseBuilder)getSqlBuilder(); - String quotationOn = builder.getQuotationOnStatement(); - String identityInsertOn = builder.getEnableIdentityOverrideSql(table); - Statement stmt = connection.createStatement(); - - if (quotationOn.length() > 0) - { - stmt.execute(quotationOn); - } - stmt.execute(identityInsertOn); - stmt.close(); - } - } - - /* - * {@inheritDoc} - */ - protected void afterInsert(Connection connection, Table table) throws SQLException - { - if (useIdentityOverrideFor(table)) - { - SybaseBuilder builder = (SybaseBuilder)getSqlBuilder(); - String quotationOn = builder.getQuotationOnStatement(); - String identityInsertOff = builder.getDisableIdentityOverrideSql(table); - Statement stmt = connection.createStatement(); - - if (quotationOn.length() > 0) - { - stmt.execute(quotationOn); - } - stmt.execute(identityInsertOff); - stmt.close(); - } - } - - /* - * {@inheritDoc} - */ - protected void beforeUpdate(Connection connection, Table table) throws SQLException - { - beforeInsert(connection, table); - } - - /* - * {@inheritDoc} - */ - protected void afterUpdate(Connection connection, Table table) throws SQLException - { - afterInsert(connection, table); - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/JdbcSupport.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/JdbcSupport.java deleted file mode 100644 index 75b9b751e5..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/JdbcSupport.java +++ /dev/null @@ -1,220 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.util; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashSet; -import java.util.Iterator; - -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.DatabaseOperationException; - -/** - * JdbcSupport is an abstract base class for objects which need to - * perform JDBC operations. It contains a number of useful methods - * for implementation inheritence.. - * - * @version $Revision: 463757 $ - */ -public abstract class JdbcSupport -{ - /** The Log to which logging calls will be made. */ - private final Log _log = LogFactory.getLog(JdbcSupport.class); - /** The data source. */ - private DataSource _dataSource; - /** The username for accessing the database. */ - private String _username; - /** The password for accessing the database. */ - private String _password; - /** The names of the currently borrowed connections (for debugging). */ - private HashSet _openConnectionNames = new HashSet(); - - // Properties - //------------------------------------------------------------------------- - - /** - * Returns the data source used for communicating with the database. - * - * @return The data source - */ - public DataSource getDataSource() - { - return _dataSource; - } - - /** - * Sets the DataSource used for communicating with the database. - * - * @param dataSource The data source - */ - public void setDataSource(DataSource dataSource) - { - _dataSource = dataSource; - } - - - /** - * Returns the username used to access the database. - * - * @return The username - */ - public String getUsername() - { - return _username; - } - - /** - * Sets the username to be used to access the database. - * - * @param username The username - */ - public void setUsername(String username) - { - _username = username; - } - - /** - * Returns the password used to access the database. - * - * @return The password - */ - public String getPassword() - { - return _password; - } - - /** - * Sets the password to be used to access the database. - * - * @param password The password - */ - public void setPassword(String password) - { - _password = password; - } - - // Implementation methods - //------------------------------------------------------------------------- - - /** - * Returns a (new) JDBC connection from the data source. - * - * @return The connection - */ - public Connection borrowConnection() throws DatabaseOperationException - { - try - { - Connection connection = null; - - if (_username == null) - { - connection = getDataSource().getConnection(); - } - else - { - connection = getDataSource().getConnection(_username, _password); - } - if (_log.isDebugEnabled()) - { - String connName = connection.toString(); - - _log.debug("Borrowed connection "+connName+" from data source"); - _openConnectionNames.add(connName); - } - return connection; - } - catch (SQLException ex) - { - throw new DatabaseOperationException("Could not get a connection from the datasource", ex); - } - } - - /** - * Closes the given JDBC connection (returns it back to the pool if the datasource is poolable). - * - * @param connection The connection - */ - public void returnConnection(Connection connection) - { - try - { - if ((connection != null) && !connection.isClosed()) - { - if (_log.isDebugEnabled()) - { - String connName = connection.toString(); - - _openConnectionNames.remove(connName); - - StringBuffer logMsg = new StringBuffer(); - - logMsg.append("Returning connection "); - logMsg.append(connName); - logMsg.append(" to data source.\nRemaining connections:"); - if (_openConnectionNames.isEmpty()) - { - logMsg.append(" None"); - } - else - { - for (Iterator it = _openConnectionNames.iterator(); it.hasNext();) - { - logMsg.append("\n "); - logMsg.append(it.next().toString()); - } - } - _log.debug(logMsg.toString()); - } - connection.close(); - } - } - catch (Exception e) - { - _log.warn("Caught exception while returning connection to pool", e); - } - } - - /** - * Closes the given statement (which also closes all result sets for this statement) and the - * connection it belongs to. - * - * @param statement The statement - */ - public void closeStatement(Statement statement) - { - if (statement != null) - { - try - { - statement.close(); - } - catch (Exception e) - { - _log.debug("Ignoring exception that occurred while closing statement", e); - } - } - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/SqlTokenizer.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/SqlTokenizer.java deleted file mode 100644 index d6dd6541e4..0000000000 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/SqlTokenizer.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.jumpmind.symmetric.db.ddl.util; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/** - * A statement tokenizer for SQL strings that splits only at delimiters that - * are at the end of a line or the end of the SQL (row mode). - * - * TODO: Add awareness of strings, so that semicolons within strings are not parsed - * - * @version $Revision: $ - */ -public class SqlTokenizer -{ - /** The SQL to tokenize. */ - private String _sql; - /** The index of the last character in the string. */ - private int _lastCharIdx; - /** The last delimiter position in the string. */ - private int _lastDelimiterPos = -1; - /** The next delimiter position in the string. */ - private int _nextDelimiterPos = -1; - /** Whether there are no more tokens. */ - private boolean _finished; - - /** - * Creates a new sql tokenizer. - * - * @param sql The sql text - */ - public SqlTokenizer(String sql) - { - _sql = sql; - _lastCharIdx = sql.length() - 1; - } - - /** - * Determines whether there are more statements. - * - * @return true if there are more statements - */ - public boolean hasMoreStatements() - { - if (_finished) - { - return false; - } - else - { - if (_nextDelimiterPos <= _lastDelimiterPos) - { - _nextDelimiterPos = _sql.indexOf(';', _lastDelimiterPos + 1); - while ((_nextDelimiterPos >= 0) && (_nextDelimiterPos < _lastCharIdx)) - { - char nextChar = _sql.charAt(_nextDelimiterPos + 1); - - if ((nextChar == '\r') || (nextChar == '\n')) - { - break; - } - _nextDelimiterPos = _sql.indexOf(';', _nextDelimiterPos + 1); - } - } - return (_nextDelimiterPos >= 0) || (_lastDelimiterPos < _lastCharIdx); - } - } - - /** - * Returns the next statement. - * - * @return The statement - */ - public String getNextStatement() - { - String result = null; - - if (hasMoreStatements()) - { - if (_nextDelimiterPos >= 0) - { - result = _sql.substring(_lastDelimiterPos + 1, _nextDelimiterPos); - _lastDelimiterPos = _nextDelimiterPos; - } - else - { - result = _sql.substring(_lastDelimiterPos + 1); - _finished = true; - } - } - return result; - } -} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/DatabaseIO.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/DatabaseIO.java similarity index 98% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/DatabaseIO.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/DatabaseIO.java index c0d7874d35..cb2b529e25 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/DatabaseIO.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/DatabaseIO.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.io; +package org.jumpmind.symmetric.db.io; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -32,8 +32,8 @@ import org.apache.commons.betwixt.io.BeanReader; import org.apache.commons.betwixt.io.BeanWriter; import org.apache.commons.betwixt.strategy.HyphenatedNameMapper; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.model.Database; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.model.Database; import org.xml.sax.InputSource; import org.xml.sax.SAXException; diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/DigesterRules.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/DigesterRules.java similarity index 94% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/DigesterRules.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/DigesterRules.java index 29c1b6d931..58b44602b5 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/DigesterRules.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/DigesterRules.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.io; +package org.jumpmind.symmetric.db.io; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/LocalEntityResolver.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/LocalEntityResolver.java similarity index 98% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/LocalEntityResolver.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/LocalEntityResolver.java index 4df69b9971..fd59e983a1 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/LocalEntityResolver.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/LocalEntityResolver.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.io; +package org.jumpmind.symmetric.db.io; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/io/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/io/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Column.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Column.java similarity index 99% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Column.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Column.java index 200cecd456..28ffb27f31 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Column.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Column.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -29,7 +29,7 @@ import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; /** * Represents a column in the database model. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Database.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Database.java similarity index 99% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Database.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Database.java index 1207ca4ed9..05e2537cb3 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Database.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Database.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/ForeignKey.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/ForeignKey.java similarity index 99% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/ForeignKey.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/ForeignKey.java index 9d4e52f4da..909ac8dcd7 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/ForeignKey.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/ForeignKey.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Index.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Index.java similarity index 98% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Index.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Index.java index 8b8670ff06..129b984822 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Index.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Index.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/IndexColumn.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/IndexColumn.java similarity index 99% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/IndexColumn.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/IndexColumn.java index 7a8084b0b3..5ec55f6e94 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/IndexColumn.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/IndexColumn.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/IndexImpBase.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/IndexImpBase.java similarity index 94% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/IndexImpBase.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/IndexImpBase.java index 3e92b76d77..c470f9bc95 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/IndexImpBase.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/IndexImpBase.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/JdbcTypeCategoryEnum.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/JdbcTypeCategoryEnum.java similarity index 96% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/JdbcTypeCategoryEnum.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/JdbcTypeCategoryEnum.java index d4437ad958..b9dfe1e96a 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/JdbcTypeCategoryEnum.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/JdbcTypeCategoryEnum.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/ModelException.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/ModelException.java similarity index 91% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/ModelException.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/ModelException.java index 90ace5deb5..ed6c1f458b 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/ModelException.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/ModelException.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,7 @@ * under the License. */ -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; +import org.jumpmind.symmetric.db.DdlUtilsException; /** * Indicates a model error. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/NonUniqueIndex.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/NonUniqueIndex.java similarity index 95% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/NonUniqueIndex.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/NonUniqueIndex.java index af41696f79..74bc86b8c8 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/NonUniqueIndex.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/NonUniqueIndex.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Reference.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Reference.java similarity index 99% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Reference.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Reference.java index 370aabf79a..9a44c7f578 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Reference.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Reference.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Table.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Table.java similarity index 99% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Table.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Table.java index 8a5d099dfa..f5d9265629 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/Table.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/Table.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/TypeMap.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/TypeMap.java similarity index 99% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/TypeMap.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/TypeMap.java index 03b831bc33..143498322d 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/TypeMap.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/TypeMap.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -24,7 +24,7 @@ import java.util.HashSet; import java.util.Set; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; /** * A class that maps SQL type names to their JDBC type ID found in diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/UniqueIndex.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/UniqueIndex.java similarity index 98% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/UniqueIndex.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/UniqueIndex.java index dea6a1077f..21947e9bd5 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/UniqueIndex.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/UniqueIndex.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.model; +package org.jumpmind.symmetric.db.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/model/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/model/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/package.html similarity index 89% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/package.html index 02f4dd6666..29b1df3584 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/package.html +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/package.html @@ -23,9 +23,9 @@

- This package mainly contains the database platform abstraction, {@link org.apache.ddlutils.Platform} + This package mainly contains the database platform abstraction, {@link org.jumpmind.symmetric.db.IDatabasePlatform} and the factory to create instances for individual platforms, - {@link org.apache.ddlutils.PlatformFactory}. + {@link org.jumpmind.symmetric.db.DatabasePlatformFactory}.

diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/DatabaseMetaDataWrapper.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/DatabaseMetaDataWrapper.java similarity index 96% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/DatabaseMetaDataWrapper.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/DatabaseMetaDataWrapper.java index 3419823952..23cab7b0e0 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/DatabaseMetaDataWrapper.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/DatabaseMetaDataWrapper.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform; +package org.jumpmind.symmetric.db.platform; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/DefaultValueHelper.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/DefaultValueHelper.java similarity index 93% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/DefaultValueHelper.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/DefaultValueHelper.java index e76fafd847..482a4f3969 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/DefaultValueHelper.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/DefaultValueHelper.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform; +package org.jumpmind.symmetric.db.platform; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -26,8 +26,8 @@ import org.apache.commons.beanutils.ConversionException; import org.apache.commons.beanutils.ConvertUtils; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; /** * Helper class for dealing with default values, e.g. converting them to other types. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/JdbcModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/JdbcModelReader.java similarity index 97% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/JdbcModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/JdbcModelReader.java index ddde91f81e..f98bd0278b 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/JdbcModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/JdbcModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform; +package org.jumpmind.symmetric.db.platform; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -40,17 +40,17 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.IndexColumn; -import org.jumpmind.symmetric.db.ddl.model.NonUniqueIndex; -import org.jumpmind.symmetric.db.ddl.model.Reference; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.UniqueIndex; +import org.jumpmind.symmetric.db.DatabasePlatformInfo; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.IndexColumn; +import org.jumpmind.symmetric.db.model.NonUniqueIndex; +import org.jumpmind.symmetric.db.model.Reference; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.UniqueIndex; /* * An utility class to create a Database model from a live database. @@ -58,7 +58,7 @@ public class JdbcModelReader { /* The Log to which logging calls will be made. */ - private final Log _log = LogFactory.getLog(JdbcModelReader.class); + protected final Log log = LogFactory.getLog(JdbcModelReader.class); /* The descriptors for the relevant columns in the table meta data. */ private final List _columnsForTable; @@ -72,7 +72,7 @@ public class JdbcModelReader private final List _columnsForIndex; /* The platform that this model reader belongs to. */ - private Platform _platform; + private IDatabasePlatform _platform; /* Contains default column sizes (minimum sizes that a JDBC-compliant db must support). */ private HashMap _defaultSizes = new HashMap(); /* The default database catalog to read. */ @@ -91,7 +91,7 @@ public class JdbcModelReader * * @param platform The plaftform this builder belongs to */ - public JdbcModelReader(Platform platform) + public JdbcModelReader(IDatabasePlatform platform) { _platform = platform; @@ -121,7 +121,7 @@ public JdbcModelReader(Platform platform) * * @return The platform */ - public Platform getPlatform() + public IDatabasePlatform getPlatform() { return _platform; } @@ -131,7 +131,7 @@ public Platform getPlatform() * * @return The platform settings */ - public PlatformInfo getPlatformInfo() + public DatabasePlatformInfo getPlatformInfo() { return _platform.getPlatformInfo(); } @@ -445,7 +445,7 @@ public Database getDatabase(Connection connection, String name, String catalog, } catch (Exception ex) { - _log.info("Cannot determine the catalog name from connection.", ex); + log.info("Cannot determine the catalog name from connection.", ex); } } else @@ -1102,7 +1102,7 @@ public void determineAutoIncrementFromResultSetMetaData(Connection conn, Table t msg.append(col.toString()); } } - _log.warn(msg); + log.warn(msg); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/MetaDataColumnDescriptor.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/MetaDataColumnDescriptor.java similarity index 95% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/MetaDataColumnDescriptor.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/MetaDataColumnDescriptor.java index cb579a0559..5dbaffc5a5 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/MetaDataColumnDescriptor.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/MetaDataColumnDescriptor.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform; +package org.jumpmind.symmetric.db.platform; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/SqlBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/SqlBuilder.java new file mode 100644 index 0000000000..b9e0cea9d6 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/SqlBuilder.java @@ -0,0 +1,2512 @@ +package org.jumpmind.symmetric.db.platform; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.IOException; +import java.io.Writer; +import java.rmi.server.UID; +import java.sql.Types; +import java.text.DateFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.collections.Closure; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.Predicate; +import org.apache.commons.lang.StringUtils; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddForeignKeyChange; +import org.jumpmind.symmetric.db.alter.AddIndexChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.AddTableChange; +import org.jumpmind.symmetric.db.alter.ColumnAutoIncrementChange; +import org.jumpmind.symmetric.db.alter.ColumnDataTypeChange; +import org.jumpmind.symmetric.db.alter.ColumnDefaultValueChange; +import org.jumpmind.symmetric.db.alter.ColumnRequiredChange; +import org.jumpmind.symmetric.db.alter.ColumnSizeChange; +import org.jumpmind.symmetric.db.alter.IModelChange; +import org.jumpmind.symmetric.db.alter.ModelComparator; +import org.jumpmind.symmetric.db.alter.PrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.RemoveForeignKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveIndexChange; +import org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveTableChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.IndexColumn; +import org.jumpmind.symmetric.db.model.ModelException; +import org.jumpmind.symmetric.db.model.Reference; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.util.CallbackClosure; +import org.jumpmind.symmetric.db.util.MultiInstanceofPredicate; +import org.jumpmind.symmetric.util.Log; + +/** + * This class is a collection of Strategy methods for creating the DDL required + * to create and drop databases and tables. + * + * It is hoped that just a single implementation of this class, for each + * database should make creating DDL for each physical database fairly + * straightforward. + * + * An implementation of this class can always delegate down to some templating + * technology such as Velocity if it requires. Though often that can be quite + * complex when attempting to reuse code across many databases. Hopefully only a + * small amount code needs to be changed on a per database basis. + */ +public abstract class SqlBuilder { + + /** The line separator for in between sql commands. */ + private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n"); + + /** The placeholder for the size value in the native type spec. */ + protected static final String SIZE_PLACEHOLDER = "{0}"; + + /** The Log to which logging calls will be made. */ + protected Log log; + + /** The platform that this builder belongs to. */ + protected IDatabasePlatform platform; + + /** The indentation used to indent commands. */ + private String indent = " "; + + /** An optional locale specification for number and date formatting. */ + private String valueLocale; + + /** The date formatter. */ + private DateFormat valueDateFormat; + + /** The date time formatter. */ + private DateFormat valueTimeFormat; + + /** The number formatter. */ + private NumberFormat valueNumberFormat; + + /** Helper object for dealing with default values. */ + private DefaultValueHelper defaultValueHelper = new DefaultValueHelper(); + + /** The character sequences that need escaping. */ + private Map charSequencesToEscape = new LinkedHashMap(); + + protected Writer writer; + + /** + * Creates a new sql builder. + * + * @param platform + * The platform this builder belongs to + */ + public SqlBuilder(Log log, IDatabasePlatform platform, Writer writer) { + this.log = log; + this.platform = platform; + this.writer = writer; + } + + /** + * Returns the default value helper. + * + * @return The default value helper + */ + public DefaultValueHelper getDefaultValueHelper() { + return defaultValueHelper; + } + + /** + * Returns the string used to indent the SQL. + * + * @return The indentation string + */ + public String getIndent() { + return indent; + } + + /** + * Sets the string used to indent the SQL. + * + * @param indent + * The indentation string + */ + public void setIndent(String indent) { + this.indent = indent; + } + + /** + * Returns the locale that is used for number and date formatting (when + * printing default values and in generates insert/update/delete + * statements). + * + * @return The locale or null if default formatting is used + */ + public String getValueLocale() { + return valueLocale; + } + + /** + * Sets the locale that is used for number and date formatting (when + * printing default values and in generates insert/update/delete + * statements). + * + * @param localeStr + * The new locale or null if default formatting + * should be used; Format is "language[_country[_variant]]" + */ + public void setValueLocale(String localeStr) { + if (localeStr != null) { + int sepPos = localeStr.indexOf('_'); + String language = null; + String country = null; + String variant = null; + + if (sepPos > 0) { + language = localeStr.substring(0, sepPos); + country = localeStr.substring(sepPos + 1); + sepPos = country.indexOf('_'); + if (sepPos > 0) { + variant = country.substring(sepPos + 1); + country = country.substring(0, sepPos); + } + } else { + language = localeStr; + } + if (language != null) { + Locale locale = null; + + if (variant != null) { + locale = new Locale(language, country, variant); + } else if (country != null) { + locale = new Locale(language, country); + } else { + locale = new Locale(language); + } + + valueLocale = localeStr; + setValueDateFormat(DateFormat.getDateInstance(DateFormat.SHORT, locale)); + setValueTimeFormat(DateFormat.getTimeInstance(DateFormat.SHORT, locale)); + setValueNumberFormat(NumberFormat.getNumberInstance(locale)); + return; + } + } + valueLocale = null; + setValueDateFormat(null); + setValueTimeFormat(null); + setValueNumberFormat(null); + } + + /** + * Returns the format object for formatting dates in the specified locale. + * + * @return The date format object or null if no locale is set + */ + protected DateFormat getValueDateFormat() { + return valueDateFormat; + } + + /** + * Sets the format object for formatting dates in the specified locale. + * + * @param format + * The date format object + */ + protected void setValueDateFormat(DateFormat format) { + this.valueDateFormat = format; + } + + /** + * Returns the format object for formatting times in the specified locale. + * + * @return The time format object or null if no locale is set + */ + protected DateFormat getValueTimeFormat() { + return valueTimeFormat; + } + + /** + * Sets the date format object for formatting times in the specified locale. + * + * @param format + * The time format object + */ + protected void setValueTimeFormat(DateFormat format) { + this.valueTimeFormat = format; + } + + /** + * Returns the format object for formatting numbers in the specified locale. + * + * @return The number format object or null if no locale is set + */ + protected NumberFormat getValueNumberFormat() { + return valueNumberFormat; + } + + /** + * Returns a new date format object for formatting numbers in the specified + * locale. Platforms can override this if necessary. + * + * @param format + * The number format object + */ + protected void setValueNumberFormat(NumberFormat format) { + this.valueNumberFormat = format; + } + + /** + * Adds a char sequence that needs escaping, and its escaped version. + * + * @param charSequence + * The char sequence + * @param escapedVersion + * The escaped version + */ + protected void addEscapedCharSequence(String charSequence, String escapedVersion) { + charSequencesToEscape.put(charSequence, escapedVersion); + } + + /** + * Outputs the DDL required to drop (if requested) and (re)create all tables + * in the database model. + * + * @param database + * The database + * @param dropTables + * Whether to drop tables before creating them + */ + public void createTables(Database database, boolean dropTables) { + if (dropTables) { + dropTables(database); + } + + for (int idx = 0; idx < database.getTableCount(); idx++) { + Table table = database.getTable(idx); + + writeTableComment(table); + createTable(database, table); + } + + // we're writing the external foreignkeys last to ensure that all + // referenced tables are already defined + createExternalForeignKeys(database); + } + + /** + * Generates the DDL to modify an existing database so the schema matches + * the specified database schema by using drops, modifications and + * additions. Database-specific implementations can change aspect of this + * algorithm by redefining the individual methods that compromise it. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param params + * The parameters used in the creation of new tables. Note that + * for existing tables, the parameters won't be applied + */ + public void alterDatabase(Database currentModel, Database desiredModel) { + ModelComparator comparator = new ModelComparator(platform.getPlatformInfo(), + platform.isDelimitedIdentifierModeOn()); + List changes = comparator.compare(currentModel, desiredModel); + processChanges(currentModel, desiredModel, changes); + } + + public boolean isAlterDatabase(Database currentModel, Database desiredModel) { + ModelComparator comparator = new ModelComparator(platform.getPlatformInfo(), + platform.isDelimitedIdentifierModeOn()); + List changes = comparator.compare(currentModel, desiredModel); + return changes.size() > 0; + } + + /** + * Calls the given closure for all changes that are of one of the given + * types, and then removes them from the changes collection. + * + * @param changes + * The changes + * @param changeTypes + * The types to search for + * @param closure + * The closure to invoke + */ + protected void applyForSelectedChanges(Collection changes, + Class[] changeTypes, final Closure closure) { + final Predicate predicate = new MultiInstanceofPredicate(changeTypes); + + // basically we filter the changes for all objects where the above + // predicate returns true, and for these filtered objects we invoke the + // given closure + CollectionUtils.filter(changes, new Predicate() { + public boolean evaluate(Object obj) { + if (predicate.evaluate(obj)) { + closure.execute(obj); + return false; + } else { + return true; + } + } + }); + } + + /** + * Processes the changes. The default argument performs several passes: + *
    + *
  1. + * {@link org.jumpmind.symmetric.db.alter.RemoveForeignKeyChange} and + * {@link org.jumpmind.symmetric.db.alter.RemoveIndexChange} come first to + * allow for e.g. subsequent primary key changes or column removal.
  2. + *
  3. {@link org.jumpmind.symmetric.db.alter.RemoveTableChange} comes after + * the removal of foreign keys and indices.
  4. + *
  5. These are all handled together:
    + * {@link org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange}
    + * {@link org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange}
    + * {@link org.jumpmind.symmetric.db.alter.PrimaryKeyChange}
    + * {@link org.jumpmind.symmetric.db.alter.RemoveColumnChange}
    + * {@link org.jumpmind.symmetric.db.alter.AddColumnChange}
    + * {@link org.jumpmind.symmetric.db.alter.ColumnAutoIncrementChange}
    + * {@link org.jumpmind.symmetric.db.alter.ColumnDefaultValueChange}
    + * {@link org.jumpmind.symmetric.db.alter.ColumnRequiredChange}
    + * {@link org.jumpmind.symmetric.db.alter.ColumnDataTypeChange}
    + * {@link org.jumpmind.symmetric.db.alter.ColumnSizeChange}
    + * The reason for this is that the default algorithm rebuilds the table for + * these changes and thus their order is irrelevant.
  6. + *
  7. {@link org.jumpmind.symmetric.db.alter.AddTableChange}
    + * needs to come after the table removal (so that tables of the same name + * are removed) and before the addition of foreign keys etc.
  8. + *
  9. {@link org.jumpmind.symmetric.db.alter.AddForeignKeyChange} and + * {@link org.jumpmind.symmetric.db.alter.AddIndexChange} come last after + * table/column/primary key additions or changes.
  10. + *
+ * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param changes + * The changes + */ + @SuppressWarnings("unchecked") + protected void processChanges(Database currentModel, Database desiredModel, + List changes) { + CallbackClosure callbackClosure = new CallbackClosure(this, "processChange", new Class[] { + Database.class, Database.class, null }, new Object[] { currentModel, desiredModel, + null }); + + // 1st pass: removing external constraints and indices + applyForSelectedChanges(changes, new Class[] { RemoveForeignKeyChange.class, + RemoveIndexChange.class }, callbackClosure); + + // 2nd pass: removing tables + applyForSelectedChanges(changes, new Class[] { RemoveTableChange.class }, callbackClosure); + + // 3rd pass: changing the structure of tables + Predicate predicate = new MultiInstanceofPredicate(new Class[] { + RemovePrimaryKeyChange.class, AddPrimaryKeyChange.class, PrimaryKeyChange.class, + RemoveColumnChange.class, AddColumnChange.class, ColumnAutoIncrementChange.class, + ColumnDefaultValueChange.class, ColumnRequiredChange.class, + ColumnDataTypeChange.class, ColumnSizeChange.class }); + + processTableStructureChanges(currentModel, desiredModel, + CollectionUtils.select(changes, predicate)); + + // 4th pass: adding tables + applyForSelectedChanges(changes, new Class[] { AddTableChange.class }, callbackClosure); + // 5th pass: adding external constraints and indices + applyForSelectedChanges(changes, new Class[] { AddForeignKeyChange.class, + AddIndexChange.class }, callbackClosure); + } + + /** + * This is a fall-through callback which generates a warning because a + * specific change type wasn't handled. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, IModelChange change) { + log.warn("Change of type " + change.getClass() + " was not handled"); + } + + /** + * Processes the change representing the removal of a foreign key. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveForeignKeyChange change) { + writeExternalForeignKeyDropStmt(change.getChangedTable(), change.getForeignKey()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /** + * Processes the change representing the removal of an index. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveIndexChange change) { + writeExternalIndexDropStmt(change.getChangedTable(), change.getIndex()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /** + * Processes the change representing the removal of a table. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveTableChange change) { + dropTable(change.getChangedTable()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /** + * Processes the change representing the addition of a table. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, AddTableChange change) { + createTable(desiredModel, change.getNewTable()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /** + * Processes the change representing the addition of a foreign key. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + AddForeignKeyChange change) { + writeExternalForeignKeyCreateStmt(desiredModel, change.getChangedTable(), + change.getNewForeignKey()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /** + * Processes the change representing the addition of an index. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, AddIndexChange change) { + writeExternalIndexCreateStmt(change.getChangedTable(), change.getNewIndex()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /** + * Processes the changes to the structure of tables. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param changes + * The change objects + */ + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Collection changes) { + LinkedHashMap> changesPerTable = new LinkedHashMap>(); + LinkedHashMap> unchangedFKs = new LinkedHashMap>(); + boolean caseSensitive = platform.isDelimitedIdentifierModeOn(); + + // we first sort the changes for the tables + // however since the changes might contain source or target tables + // we use the names rather than the table objects + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + String name = change.getChangedTable().getName(); + + if (!caseSensitive) { + name = name.toUpperCase(); + } + + List changesForTable = (List) changesPerTable.get(name); + + if (changesForTable == null) { + changesForTable = new ArrayList(); + changesPerTable.put(name, changesForTable); + unchangedFKs.put(name, getUnchangedForeignKeys(currentModel, desiredModel, name)); + } + changesForTable.add(change); + } + // we also need to drop the foreign keys of the unchanged tables + // referencing the changed tables + addRelevantFKsFromUnchangedTables(currentModel, desiredModel, changesPerTable.keySet(), + unchangedFKs); + + // we're dropping the unchanged foreign keys + for (Iterator>> tableFKIt = unchangedFKs.entrySet() + .iterator(); tableFKIt.hasNext();) { + Map.Entry> entry = tableFKIt.next(); + Table targetTable = desiredModel.findTable((String) entry.getKey(), caseSensitive); + + for (Iterator fkIt = entry.getValue().iterator(); fkIt.hasNext();) { + writeExternalForeignKeyDropStmt(targetTable, fkIt.next()); + } + } + + // We're using a copy of the current model so that the table structure + // changes can modify it + Database copyOfCurrentModel = null; + + try { + copyOfCurrentModel = (Database) currentModel.clone(); + } catch (CloneNotSupportedException ex) { + throw new DdlUtilsException(ex); + } + + for (Iterator>> tableChangeIt = changesPerTable + .entrySet().iterator(); tableChangeIt.hasNext();) { + Map.Entry> entry = tableChangeIt.next(); + processTableStructureChanges(copyOfCurrentModel, desiredModel, entry.getKey(), + entry.getValue()); + } + // and finally we're re-creating the unchanged foreign keys + for (Iterator>> tableFKIt = unchangedFKs.entrySet() + .iterator(); tableFKIt.hasNext();) { + Map.Entry> entry = tableFKIt.next(); + Table targetTable = desiredModel.findTable((String) entry.getKey(), caseSensitive); + + for (Iterator fkIt = entry.getValue().iterator(); fkIt.hasNext();) { + writeExternalForeignKeyCreateStmt(desiredModel, targetTable, fkIt.next()); + } + } + } + + /** + * Determines the unchanged foreign keys of the indicated table. + * + * @param currentModel + * The current model + * @param desiredModel + * The desired model + * @param tableName + * The name of the table + * @return The list of unchanged foreign keys + */ + private List getUnchangedForeignKeys(Database currentModel, Database desiredModel, + String tableName) { + ArrayList unchangedFKs = new ArrayList(); + boolean caseSensitive = platform.isDelimitedIdentifierModeOn(); + Table sourceTable = currentModel.findTable(tableName, caseSensitive); + Table targetTable = desiredModel.findTable(tableName, caseSensitive); + + for (int idx = 0; idx < targetTable.getForeignKeyCount(); idx++) { + ForeignKey targetFK = targetTable.getForeignKey(idx); + ForeignKey sourceFK = sourceTable.findForeignKey(targetFK, caseSensitive); + + if (sourceFK != null) { + unchangedFKs.add(targetFK); + } + } + return unchangedFKs; + } + + /** + * Adds the foreign keys of the unchanged tables that reference changed + * tables to the given map. + * + * @param currentModel + * The current model + * @param desiredModel + * The desired model + * @param namesOfKnownChangedTables + * The known names of changed tables + * @param fksPerTable + * The map table name -> foreign keys to which found foreign keys + * will be added to + */ + private void addRelevantFKsFromUnchangedTables(Database currentModel, Database desiredModel, + Set namesOfKnownChangedTables, Map fksPerTable) { + boolean caseSensitive = platform.isDelimitedIdentifierModeOn(); + + for (int tableIdx = 0; tableIdx < desiredModel.getTableCount(); tableIdx++) { + Table targetTable = desiredModel.getTable(tableIdx); + String name = targetTable.getName(); + Table sourceTable = currentModel.findTable(name, caseSensitive); + List relevantFks = null; + + if (!caseSensitive) { + name = name.toUpperCase(); + } + if ((sourceTable != null) && !namesOfKnownChangedTables.contains(name)) { + for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++) { + ForeignKey targetFk = targetTable.getForeignKey(fkIdx); + ForeignKey sourceFk = sourceTable.findForeignKey(targetFk, caseSensitive); + String refName = targetFk.getForeignTableName(); + + if (!caseSensitive) { + refName = refName.toUpperCase(); + } + if ((sourceFk != null) && namesOfKnownChangedTables.contains(refName)) { + if (relevantFks == null) { + relevantFks = new ArrayList(); + fksPerTable.put(name, relevantFks); + } + relevantFks.add(targetFk); + } + } + } + } + } + + /** + * Processes the changes to the structure of a single table. + * Database-specific implementations might redefine this method, but it is + * usually sufficient to redefine the + * {@link #processTableStructureChanges(Database, Database, Table, Table, Map, List)} + * method instead. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param tableName + * The name of the changed table + * @param changes + * The change objects for this table + */ + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + String tableName, List changes) { + Table sourceTable = currentModel.findTable(tableName, + platform.isDelimitedIdentifierModeOn()); + Table targetTable = desiredModel.findTable(tableName, + platform.isDelimitedIdentifierModeOn()); + + // we're enforcing a full rebuild in case of the addition of a required + // column without a default value that is not autoincrement + boolean requiresFullRebuild = false; + + for (Iterator changeIt = changes.iterator(); !requiresFullRebuild + && changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; + + if (addColumnChange.getNewColumn().isRequired() + && (addColumnChange.getNewColumn().getDefaultValue() == null) + && !addColumnChange.getNewColumn().isAutoIncrement()) { + requiresFullRebuild = true; + } + } + } + if (!requiresFullRebuild) { + processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, + changes); + } + + if (!changes.isEmpty()) { + // we can only copy the data if no required columns without default + // value and + // non-autoincrement have been added + boolean canMigrateData = true; + + for (Iterator it = changes.iterator(); canMigrateData && it.hasNext();) { + TableChange change = (TableChange) it.next(); + + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; + + if (addColumnChange.getNewColumn().isRequired() + && !addColumnChange.getNewColumn().isAutoIncrement() + && (addColumnChange.getNewColumn().getDefaultValue() == null)) { + log.warn("Data cannot be retained in table " + + change.getChangedTable().getName() + + " because of the addition of the required column " + + addColumnChange.getNewColumn().getName()); + canMigrateData = false; + } + } + } + + Table realTargetTable = getRealTargetTableFor(desiredModel, sourceTable, targetTable); + + if (canMigrateData) { + Table tempTable = getTemporaryTableFor(desiredModel, targetTable); + + createTemporaryTable(desiredModel, tempTable); + writeCopyDataStatement(sourceTable, tempTable); + // Note that we don't drop the indices here because the DROP + // TABLE will take care of that + // Likewise, foreign keys have already been dropped as necessary + dropTable(sourceTable); + createTable(desiredModel, realTargetTable); + writeCopyDataStatement(tempTable, targetTable); + dropTemporaryTable(desiredModel, tempTable); + writeFixLastIdentityValues(targetTable); + } else { + dropTable(sourceTable); + createTable(desiredModel, realTargetTable); + } + } + } + + /** + * Allows database-specific implementations to handle changes in a database + * specific manner. Any handled change should be applied to the given + * current model (which is a copy of the real original model) and be removed + * from the list of changes.
+ * In the default implementation, all {@link AddPrimaryKeyChange} changes + * are applied via an ALTER TABLE ADD CONSTRAINT statement. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param sourceTable + * The original table + * @param targetTable + * The desired table + * @param changes + * The change objects for the target table + */ + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + if (changes.size() == 1) { + TableChange change = changes.get(0); + + if (change instanceof AddPrimaryKeyChange) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); + changes.clear(); + } + } + } + + /** + * Creates a temporary table object that corresponds to the given table. + * Database-specific implementations may redefine this method if e.g. the + * database directly supports temporary tables. The default implementation + * simply appends an underscore to the table name and uses that as the table + * name. + * + * @param targetModel + * The target database + * @param targetTable + * The target table + * @return The temporary table + */ + protected Table getTemporaryTableFor(Database targetModel, Table targetTable) { + return getTemporaryTableFor(targetModel, targetTable, "_"); + } + + public Table getBackupTableFor(Database model, Table sourceTable) { + return getTemporaryTableFor(model, sourceTable, "x"); + } + + public Table createBackupTableFor(Database model, Table sourceTable) { + Table backupTable = getBackupTableFor(model, sourceTable); + writeTableCreationStmt(model, backupTable); + printEndOfStatement(); + writeCopyDataStatement(sourceTable, backupTable); + return backupTable; + } + + public void restoreTableFromBackup(Table backupTable, Table targetTable, LinkedHashMap columnMap) { + print("DELETE FROM "); + printIdentifier(getTableName(targetTable)); + printEndOfStatement(); + writeCopyDataStatement(backupTable, targetTable, columnMap); + } + + protected Table getTemporaryTableFor(Database targetModel, Table targetTable, String suffix) { + Table table = new Table(); + + table.setCatalog(targetTable.getCatalog()); + table.setSchema(targetTable.getSchema()); + table.setName(targetTable.getName() + suffix); + table.setType(targetTable.getType()); + for (int idx = 0; idx < targetTable.getColumnCount(); idx++) { + try { + table.addColumn((Column) targetTable.getColumn(idx).clone()); + } catch (CloneNotSupportedException ex) { + throw new DdlUtilsException(ex); + } + } + + return table; + } + + /** + * Outputs the DDL to create the given temporary table. Per default this is + * simply a call to {@link #createTable(Database, Table, Map)}. + * + * @param database + * The database model + * @param table + * The table + */ + protected void createTemporaryTable(Database database, Table table) { + createTable(database, table); + } + + /** + * Outputs the DDL to drop the given temporary table. Per default this is + * simply a call to {@link #dropTable(Table)}. + * + * @param database + * The database model + * @param table + * The table + */ + protected void dropTemporaryTable(Database database, Table table) { + dropTable(table); + } + + /** + * Creates the target table object that differs from the given target table + * only in the indices. More specifically, only those indices are used that + * have not changed. + * + * @param targetModel + * The target database + * @param sourceTable + * The source table + * @param targetTable + * The target table + * @return The table + */ + protected Table getRealTargetTableFor(Database targetModel, Table sourceTable, Table targetTable) { + Table table = new Table(); + + table.setCatalog(targetTable.getCatalog()); + table.setSchema(targetTable.getSchema()); + table.setName(targetTable.getName()); + table.setType(targetTable.getType()); + for (int idx = 0; idx < targetTable.getColumnCount(); idx++) { + try { + table.addColumn((Column) targetTable.getColumn(idx).clone()); + } catch (CloneNotSupportedException ex) { + throw new DdlUtilsException(ex); + } + } + + boolean caseSensitive = platform.isDelimitedIdentifierModeOn(); + + for (int idx = 0; idx < targetTable.getIndexCount(); idx++) { + Index targetIndex = targetTable.getIndex(idx); + Index sourceIndex = sourceTable.findIndex(targetIndex.getName(), caseSensitive); + + if (sourceIndex != null) { + if ((caseSensitive && sourceIndex.equals(targetIndex)) + || (!caseSensitive && sourceIndex.equalsIgnoreCase(targetIndex))) { + table.addIndex(targetIndex); + } + } + } + + return table; + } + + /** + * Writes a statement that copies the data from the source to the target + * table. Note that this copies only those columns that are in both tables. + * Database-specific implementations might redefine this method though they + * usually it suffices to redefine the + * {@link #writeCastExpression(Column, Column)} method. + * + * @param sourceTable + * The source table + * @param targetTable + * The target table + */ + public void writeCopyDataStatement(Table sourceTable, Table targetTable) { + LinkedHashMap columnMap = getCopyDataColumnMapping(sourceTable, targetTable); + writeCopyDataStatement(sourceTable, targetTable, columnMap); + } + + public void writeCopyDataStatement(Table sourceTable, Table targetTable, LinkedHashMap columnMap) { + print("INSERT INTO "); + printIdentifier(getTableName(targetTable)); + print(" ("); + for (Iterator columnIt = columnMap.values().iterator(); columnIt.hasNext();) { + printIdentifier(getColumnName((Column) columnIt.next())); + if (columnIt.hasNext()) { + print(","); + } + } + print(") SELECT "); + for (Iterator columnsIt = columnMap.entrySet().iterator(); columnsIt.hasNext();) { + Map.Entry entry = (Map.Entry) columnsIt.next(); + + writeCastExpression((Column) entry.getKey(), (Column) entry.getValue()); + if (columnsIt.hasNext()) { + print(","); + } + } + print(" FROM "); + printIdentifier(getTableName(sourceTable)); + printEndOfStatement(); + } + + public LinkedHashMap getCopyDataColumnMapping(Table sourceTable, Table targetTable) { + LinkedHashMap columns = new LinkedHashMap(); + + for (int idx = 0; idx < sourceTable.getColumnCount(); idx++) { + Column sourceColumn = sourceTable.getColumn(idx); + Column targetColumn = targetTable.findColumn(sourceColumn.getName(), + platform.isDelimitedIdentifierModeOn()); + + if (targetColumn != null) { + columns.put(sourceColumn, targetColumn); + } + } + return columns; + } + + public LinkedHashMap getCopyDataColumnOrderedMapping(Table sourceTable, Table targetTable) { + LinkedHashMap columns = new LinkedHashMap(); + + for (int idx = 0; idx < sourceTable.getColumnCount(); idx++) { + columns.put(sourceTable.getColumn(idx), targetTable.getColumn(idx)); + } + return columns; + } + + /** + * Writes a cast expression that converts the value of the source column to + * the data type of the target column. Per default, simply the name of the + * source column is written thereby assuming that any casts happen + * implicitly. + * + * @param sourceColumn + * The source column + * @param targetColumn + * The target column + */ + protected void writeCastExpression(Column sourceColumn, Column targetColumn) { + printIdentifier(getColumnName(sourceColumn)); + } + + /** + * Processes the addition of a primary key to a table. + * + * @param currentModel + * The current database schema + * @param desiredModel + * The desired database schema + * @param change + * The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + AddPrimaryKeyChange change) { + writeExternalPrimaryKeysCreateStmt(change.getChangedTable(), change.getPrimaryKeyColumns()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /** + * Searches in the given table for a corresponding foreign key. If the given + * key has no name, then a foreign key to the same table with the same + * columns in the same order is searched. If the given key has a name, then + * the a corresponding key also needs to have the same name, or no name at + * all, but not a different one. + * + * @param table + * The table to search in + * @param fk + * The original foreign key + * @return The corresponding foreign key if found + */ + protected ForeignKey findCorrespondingForeignKey(Table table, ForeignKey fk) { + boolean caseMatters = platform.isDelimitedIdentifierModeOn(); + boolean checkFkName = (fk.getName() != null) && (fk.getName().length() > 0); + Reference[] refs = fk.getReferences(); + ArrayList curRefs = new ArrayList(); + + for (int fkIdx = 0; fkIdx < table.getForeignKeyCount(); fkIdx++) { + ForeignKey curFk = table.getForeignKey(fkIdx); + boolean checkCurFkName = checkFkName && (curFk.getName() != null) + && (curFk.getName().length() > 0); + + if ((!checkCurFkName || areEqual(fk.getName(), curFk.getName(), caseMatters)) + && areEqual(fk.getForeignTableName(), curFk.getForeignTableName(), caseMatters)) { + curRefs.clear(); + CollectionUtils.addAll(curRefs, curFk.getReferences()); + + // the order is not fixed, so we have to take this long way + if (curRefs.size() == refs.length) { + for (int refIdx = 0; refIdx < refs.length; refIdx++) { + boolean found = false; + + for (int curRefIdx = 0; !found && (curRefIdx < curRefs.size()); curRefIdx++) { + Reference curRef = (Reference) curRefs.get(curRefIdx); + + if ((caseMatters && refs[refIdx].equals(curRef)) + || (!caseMatters && refs[refIdx].equalsIgnoreCase(curRef))) { + curRefs.remove(curRefIdx); + found = true; + } + } + } + if (curRefs.isEmpty()) { + return curFk; + } + } + } + } + return null; + } + + /** + * Compares the two strings. + * + * @param string1 + * The first string + * @param string2 + * The second string + * @param caseMatters + * Whether case matters in the comparison + * @return true if the string are equal + */ + protected boolean areEqual(String string1, String string2, boolean caseMatters) { + return (caseMatters && string1.equals(string2)) + || (!caseMatters && string1.equalsIgnoreCase(string2)); + } + + /** + * Outputs the DDL to create the table along with any non-external + * constraints as well as with external primary keys and indices (but not + * foreign keys). + * + * @param database + * The database model + * @param table + * The table + */ + public void createTable(Database database, Table table) { + writeTableCreationStmt(database, table); + writeTableCreationStmtEnding(table); + + if (!platform.getPlatformInfo().isPrimaryKeyEmbedded()) { + writeExternalPrimaryKeysCreateStmt(table, table.getPrimaryKeyColumns()); + } + if (!platform.getPlatformInfo().isIndicesEmbedded()) { + writeExternalIndicesCreateStmt(table); + } + } + + /** + * Creates the external foreignkey creation statements for all tables in the + * database. + * + * @param database + * The database + */ + public void createExternalForeignKeys(Database database) { + for (int idx = 0; idx < database.getTableCount(); idx++) { + createExternalForeignKeys(database, database.getTable(idx)); + } + } + + /** + * Creates external foreignkey creation statements if necessary. + * + * @param database + * The database model + * @param table + * The table + */ + public void createExternalForeignKeys(Database database, Table table) { + if (!platform.getPlatformInfo().isForeignKeysEmbedded()) { + for (int idx = 0; idx < table.getForeignKeyCount(); idx++) { + writeExternalForeignKeyCreateStmt(database, table, table.getForeignKey(idx)); + } + } + } + + /** + * Outputs the DDL required to drop the database. + * + * @param database + * The database + */ + public void dropTables(Database database) { + // we're dropping the external foreignkeys first + for (int idx = database.getTableCount() - 1; idx >= 0; idx--) { + Table table = database.getTable(idx); + + if ((table.getName() != null) && (table.getName().length() > 0)) { + dropExternalForeignKeys(table); + } + } + + // Next we drop the tables in reverse order to avoid referencial + // problems + // TODO: It might be more useful to either (or both) + // * determine an order in which the tables can be dropped safely (via + // the foreignkeys) + // * alter the tables first to drop the internal foreignkeys + for (int idx = database.getTableCount() - 1; idx >= 0; idx--) { + Table table = database.getTable(idx); + + if ((table.getName() != null) && (table.getName().length() > 0)) { + writeTableComment(table); + dropTable(table); + } + } + } + + /** + * Outputs the DDL required to drop the given table. This method also drops + * foreign keys to the table. + * + * @param database + * The database + * @param table + * The table + */ + public void dropTable(Database database, Table table) { + // we're dropping the foreignkeys to the table first + for (int idx = database.getTableCount() - 1; idx >= 0; idx--) { + Table otherTable = database.getTable(idx); + ForeignKey[] fks = otherTable.getForeignKeys(); + + for (int fkIdx = 0; (fks != null) && (fkIdx < fks.length); fkIdx++) { + if (fks[fkIdx].getForeignTable().equals(table)) { + writeExternalForeignKeyDropStmt(otherTable, fks[fkIdx]); + } + } + } + // and the foreign keys from the table + dropExternalForeignKeys(table); + + writeTableComment(table); + dropTable(table); + } + + /** + * Outputs the DDL to drop the table. Note that this method does not drop + * foreign keys to this table. Use {@link #dropTable(Database, Table)} if + * you want that. + * + * @param table + * The table to drop + */ + public void dropTable(Table table) { + print("DROP TABLE "); + printIdentifier(getTableName(table)); + printEndOfStatement(); + } + + /** + * Creates external foreignkey drop statements. + * + * @param table + * The table + */ + public void dropExternalForeignKeys(Table table) { + if (!platform.getPlatformInfo().isForeignKeysEmbedded()) { + for (int idx = 0; idx < table.getForeignKeyCount(); idx++) { + writeExternalForeignKeyDropStmt(table, table.getForeignKey(idx)); + } + } + } + + /** + * Creates the SQL for inserting an object into the specified table. If + * values are given then a concrete insert statement is created, otherwise + * an insert statement usable in a prepared statement is build. + * + * @param table + * The table + * @param columnValues + * The columns values indexed by the column names + * @param genPlaceholders + * Whether to generate value placeholders for a prepared + * statement + * @return The insertion sql + */ + public String getInsertSql(Table table, Map columnValues, boolean genPlaceholders) { + StringBuffer buffer = new StringBuffer("INSERT INTO "); + boolean addComma = false; + + buffer.append(getDelimitedIdentifier(getTableName(table))); + buffer.append(" ("); + + for (int idx = 0; idx < table.getColumnCount(); idx++) { + Column column = table.getColumn(idx); + + if (columnValues.containsKey(column.getName())) { + if (addComma) { + buffer.append(", "); + } + buffer.append(getDelimitedIdentifier(column.getName())); + addComma = true; + } + } + buffer.append(") VALUES ("); + if (genPlaceholders) { + addComma = false; + for (int idx = 0; idx < columnValues.size(); idx++) { + if (addComma) { + buffer.append(", "); + } + buffer.append("?"); + addComma = true; + } + } else { + addComma = false; + for (int idx = 0; idx < table.getColumnCount(); idx++) { + Column column = table.getColumn(idx); + + if (columnValues.containsKey(column.getName())) { + if (addComma) { + buffer.append(", "); + } + buffer.append(getValueAsString(column, columnValues.get(column.getName()))); + addComma = true; + } + } + } + buffer.append(")"); + return buffer.toString(); + } + + /** + * Creates the SQL for updating an object in the specified table. If values + * are given then a concrete update statement is created, otherwise an + * update statement usable in a prepared statement is build. + * + * @param table + * The table + * @param columnValues + * Contains the values for the columns to update, and should also + * contain the primary key values to identify the object to + * update in case genPlaceholders is + * false + * @param genPlaceholders + * Whether to generate value placeholders for a prepared + * statement (both for the pk values and the object values) + * @return The update sql + */ + public String getUpdateSql(Table table, Map columnValues, boolean genPlaceholders) { + StringBuffer buffer = new StringBuffer("UPDATE "); + boolean addSep = false; + + buffer.append(getDelimitedIdentifier(getTableName(table))); + buffer.append(" SET "); + + for (int idx = 0; idx < table.getColumnCount(); idx++) { + Column column = table.getColumn(idx); + + if (!column.isPrimaryKey() && columnValues.containsKey(column.getName())) { + if (addSep) { + buffer.append(", "); + } + buffer.append(getDelimitedIdentifier(column.getName())); + buffer.append(" = "); + if (genPlaceholders) { + buffer.append("?"); + } else { + buffer.append(getValueAsString(column, columnValues.get(column.getName()))); + } + addSep = true; + } + } + buffer.append(" WHERE "); + addSep = false; + for (int idx = 0; idx < table.getColumnCount(); idx++) { + Column column = table.getColumn(idx); + + if (column.isPrimaryKey() && columnValues.containsKey(column.getName())) { + if (addSep) { + buffer.append(" AND "); + } + buffer.append(getDelimitedIdentifier(column.getName())); + buffer.append(" = "); + if (genPlaceholders) { + buffer.append("?"); + } else { + buffer.append(getValueAsString(column, columnValues.get(column.getName()))); + } + addSep = true; + } + } + return buffer.toString(); + } + + /** + * Creates the SQL for deleting an object from the specified table. If + * values are given then a concrete delete statement is created, otherwise + * an delete statement usable in a prepared statement is build. + * + * @param table + * The table + * @param pkValues + * The primary key values indexed by the column names, can be + * empty + * @param genPlaceholders + * Whether to generate value placeholders for a prepared + * statement + * @return The delete sql + */ + public String getDeleteSql(Table table, Map pkValues, boolean genPlaceholders) { + StringBuffer buffer = new StringBuffer("DELETE FROM "); + boolean addSep = false; + + buffer.append(getDelimitedIdentifier(getTableName(table))); + if ((pkValues != null) && !pkValues.isEmpty()) { + buffer.append(" WHERE "); + for (Iterator it = pkValues.entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + Column column = table.findColumn((String) entry.getKey()); + + if (addSep) { + buffer.append(" AND "); + } + buffer.append(getDelimitedIdentifier(entry.getKey().toString())); + buffer.append(" = "); + if (genPlaceholders) { + buffer.append("?"); + } else { + buffer.append(column == null ? entry.getValue() : getValueAsString(column, + entry.getValue())); + } + addSep = true; + } + } + return buffer.toString(); + } + + /** + * Generates the string representation of the given value. + * + * @param column + * The column + * @param value + * The value + * @return The string representation + */ + protected String getValueAsString(Column column, Object value) { + if (value == null) { + return "NULL"; + } + + StringBuffer result = new StringBuffer(); + + // TODO: Handle binary types (BINARY, VARBINARY, LONGVARBINARY, BLOB) + switch (column.getTypeCode()) { + case Types.DATE: + result.append(platform.getPlatformInfo().getValueQuoteToken()); + if (!(value instanceof String) && (getValueDateFormat() != null)) { + // TODO: Can the format method handle java.sql.Date properly ? + result.append(getValueDateFormat().format(value)); + } else { + result.append(value.toString()); + } + result.append(platform.getPlatformInfo().getValueQuoteToken()); + break; + case Types.TIME: + result.append(platform.getPlatformInfo().getValueQuoteToken()); + if (!(value instanceof String) && (getValueTimeFormat() != null)) { + // TODO: Can the format method handle java.sql.Date properly ? + result.append(getValueTimeFormat().format(value)); + } else { + result.append(value.toString()); + } + result.append(platform.getPlatformInfo().getValueQuoteToken()); + break; + case Types.TIMESTAMP: + result.append(platform.getPlatformInfo().getValueQuoteToken()); + // TODO: SimpleDateFormat does not support nano seconds so we would + // need a custom date formatter for timestamps + result.append(value.toString()); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + break; + case Types.REAL: + case Types.NUMERIC: + case Types.FLOAT: + case Types.DOUBLE: + case Types.DECIMAL: + result.append(platform.getPlatformInfo().getValueQuoteToken()); + if (!(value instanceof String) && (getValueNumberFormat() != null)) { + result.append(getValueNumberFormat().format(value)); + } else { + result.append(value.toString()); + } + result.append(platform.getPlatformInfo().getValueQuoteToken()); + break; + default: + result.append(platform.getPlatformInfo().getValueQuoteToken()); + result.append(escapeStringValue(value.toString())); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + break; + } + return result.toString(); + } + + /** + * Generates the SQL for querying the id that was created in the last + * insertion operation. This is obviously only useful for pk fields that are + * auto-incrementing. A database that does not support this, will return + * null. + * + * @param table + * The table + * @return The sql, or null if the database does not support + * this + */ + public String getSelectLastIdentityValues(Table table) { + // No default possible as the databases are quite different in this + // respect + return null; + } + + /** + * Generates the SQL to execute that sets the current sequence number. + * + * @param table + * @param id + * @return + */ + public String fixLastIdentityValues(Table table) { + return null; + } + + public void writeFixLastIdentityValues(Table table) { + String sql = fixLastIdentityValues(table); + if (sql != null) { + print(sql); + printEndOfStatement(); + } + } + + // + // implementation methods that may be overridden by specific database + // builders + // + + /** + * Generates a version of the name that has at most the specified length. + * + * @param name + * The original name + * @param desiredLength + * The desired maximum length + * @return The shortened version + */ + public String shortenName(String name, int desiredLength) { + // TODO: Find an algorithm that generates unique names + int originalLength = name.length(); + + if ((desiredLength <= 0) || (originalLength <= desiredLength)) { + return name; + } + + int delta = originalLength - desiredLength; + int startCut = desiredLength / 2; + + StringBuffer result = new StringBuffer(); + + result.append(name.substring(0, startCut)); + if (((startCut == 0) || (name.charAt(startCut - 1) != '_')) + && ((startCut + delta + 1 == originalLength) || (name.charAt(startCut + delta + 1) != '_'))) { + // just to make sure that there isn't already a '_' right before or + // right + // after the cutting place (which would look odd with an aditional + // one) + result.append("_"); + } + result.append(name.substring(startCut + delta + 1, originalLength)); + return result.toString(); + } + + /** + * Returns the table name. This method takes care of length limitations + * imposed by some databases. + * + * @param table + * The table + * @return The table name + */ + public String getTableName(Table table) { + return shortenName(table.getName(), platform.getPlatformInfo().getMaxTableNameLength()); + } + + /** + * Outputs a comment for the table. + * + * @param table + * The table + */ + protected void writeTableComment(Table table) { + printComment("-----------------------------------------------------------------------"); + printComment(getTableName(table)); + printComment("-----------------------------------------------------------------------"); + println(); + } + + /** + * Generates the first part of the ALTER TABLE statement including the table + * name. + * + * @param table + * The table being altered + */ + protected void writeTableAlterStmt(Table table) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(table)); + printIndent(); + } + + /** + * Writes the table creation statement without the statement end. + * + * @param database + * The model + * @param table + * The table + * @param parameters + * Additional platform-specific parameters for the table creation + */ + protected void writeTableCreationStmt(Database database, Table table) { + print("CREATE TABLE "); + printlnIdentifier(getTableName(table)); + println("("); + + writeColumns(table); + + if (platform.getPlatformInfo().isPrimaryKeyEmbedded()) { + writeEmbeddedPrimaryKeysStmt(table); + } + if (platform.getPlatformInfo().isForeignKeysEmbedded()) { + writeEmbeddedForeignKeysStmt(database, table); + } + if (platform.getPlatformInfo().isIndicesEmbedded()) { + writeEmbeddedIndicesStmt(table); + } + println(); + print(")"); + } + + /** + * Writes the end of the table creation statement. Per default, only the end + * of the statement is written, but this can be changed in subclasses. + * + * @param table + * The table + */ + protected void writeTableCreationStmtEnding(Table table) { + printEndOfStatement(); + } + + /** + * Writes the columns of the given table. + * + * @param table + * The table + */ + protected void writeColumns(Table table) { + for (int idx = 0; idx < table.getColumnCount(); idx++) { + printIndent(); + writeColumn(table, table.getColumn(idx)); + if (idx < table.getColumnCount() - 1) { + println(","); + } + } + } + + /** + * Returns the column name. This method takes care of length limitations + * imposed by some databases. + * + * @param column + * The column + * @return The column name + */ + protected String getColumnName(Column column) { + return shortenName(column.getName(), platform.getPlatformInfo().getMaxColumnNameLength()); + } + + /** + * Outputs the DDL for the specified column. + * + * @param table + * The table containing the column + * @param column + * The column + */ + protected void writeColumn(Table table, Column column) { + // see comments in columnsDiffer about null/"" defaults + printIdentifier(getColumnName(column)); + print(" "); + print(getSqlType(column)); + writeColumnDefaultValueStmt(table, column); + if (column.isRequired()) { + print(" "); + writeColumnNotNullableStmt(); + } else if (platform.getPlatformInfo().isNullAsDefaultValueRequired() + && platform.getPlatformInfo().hasNullDefault(column.getTypeCode())) { + print(" "); + writeColumnNullableStmt(); + } + if (column.isAutoIncrement() + && !platform.getPlatformInfo().isDefaultValueUsedForIdentitySpec()) { + if (!platform.getPlatformInfo().isNonPKIdentityColumnsSupported() + && !column.isPrimaryKey()) { + throw new ModelException( + "Column " + + column.getName() + + " in table " + + table.getName() + + " is auto-incrementing but not a primary key column, which is not supported by the platform"); + } + print(" "); + writeColumnAutoIncrementStmt(table, column); + } + } + + /** + * Returns the full SQL type specification (including size and + * precision/scale) for the given column. + * + * @param column + * The column + * @return The full SQL type string including the size + */ + protected String getSqlType(Column column) { + String nativeType = getNativeType(column); + int sizePos = nativeType.indexOf(SIZE_PLACEHOLDER); + StringBuffer sqlType = new StringBuffer(); + + sqlType.append(sizePos >= 0 ? nativeType.substring(0, sizePos) : nativeType); + + Object sizeSpec = column.getSize(); + + if (sizeSpec == null) { + sizeSpec = platform.getPlatformInfo().getDefaultSize(column.getTypeCode()); + } + if (sizeSpec != null) { + if (platform.getPlatformInfo().hasSize(column.getTypeCode())) { + sqlType.append("("); + sqlType.append(sizeSpec.toString()); + sqlType.append(")"); + } else if (platform.getPlatformInfo().hasPrecisionAndScale(column.getTypeCode())) { + sqlType.append("("); + sqlType.append(column.getSizeAsInt()); + sqlType.append(","); + sqlType.append(column.getScale()); + sqlType.append(")"); + } + } + sqlType.append(sizePos >= 0 ? nativeType.substring(sizePos + SIZE_PLACEHOLDER.length()) + : ""); + + return sqlType.toString(); + } + + /** + * Returns the database-native type for the given column. + * + * @param column + * The column + * @return The native type + */ + protected String getNativeType(Column column) { + String nativeType = (String) platform.getPlatformInfo().getNativeType(column.getTypeCode()); + + return nativeType == null ? column.getType() : nativeType; + } + + /** + * Returns the bare database-native type for the given column without any + * size specifies. + * + * @param column + * The column + * @return The native type + */ + protected String getBareNativeType(Column column) { + String nativeType = getNativeType(column); + int sizePos = nativeType.indexOf(SIZE_PLACEHOLDER); + + return sizePos >= 0 ? nativeType.substring(0, sizePos) : nativeType; + } + + /** + * Returns the native default value for the column. + * + * @param column + * The column + * @return The native default value + */ + protected String getNativeDefaultValue(Column column) { + return column.getDefaultValue(); + } + + /** + * Escapes the necessary characters in given string value. + * + * @param value + * The value + * @return The corresponding string with the special characters properly + * escaped + */ + protected String escapeStringValue(String value) { + String result = value; + + for (Iterator it = charSequencesToEscape.entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + + result = StringUtils + .replace(result, (String) entry.getKey(), (String) entry.getValue()); + } + return result; + } + + /** + * Determines whether the given default spec is a non-empty spec that shall + * be used in a DEFAULT expression. E.g. if the spec is an empty string and + * the type is a numeric type, then it is no valid default value whereas if + * it is a string type, then it is valid. + * + * @param defaultSpec + * The default value spec + * @param typeCode + * The JDBC type code + * @return true if the default value spec is valid + */ + protected boolean isValidDefaultValue(String defaultSpec, int typeCode) { + return (defaultSpec != null) + && ((defaultSpec.length() > 0) || (!TypeMap.isNumericType(typeCode) && !TypeMap + .isDateTimeType(typeCode))); + } + + /** + * Prints the default value stmt part for the column. + * + * @param table + * The table + * @param column + * The column + */ + protected void writeColumnDefaultValueStmt(Table table, Column column) { + Object parsedDefault = column.getParsedDefaultValue(); + + if (parsedDefault != null) { + if (!platform.getPlatformInfo().isDefaultValuesForLongTypesSupported() + && ((column.getTypeCode() == Types.LONGVARBINARY) || (column.getTypeCode() == Types.LONGVARCHAR))) { + throw new ModelException( + "The platform does not support default values for LONGVARCHAR or LONGVARBINARY columns"); + } + // we write empty default value strings only if the type is not a + // numeric or date/time type + if (isValidDefaultValue(column.getDefaultValue(), column.getTypeCode())) { + print(" DEFAULT "); + writeColumnDefaultValue(table, column); + } + } else if (platform.getPlatformInfo().isDefaultValueUsedForIdentitySpec() + && column.isAutoIncrement()) { + print(" DEFAULT "); + writeColumnDefaultValue(table, column); + } + } + + /** + * Prints the default value of the column. + * + * @param table + * The table + * @param column + * The column + */ + protected void writeColumnDefaultValue(Table table, Column column) { + printDefaultValue(getNativeDefaultValue(column), column.getTypeCode()); + } + + /** + * Prints the default value of the column. + * + * @param defaultValue + * The default value + * @param typeCode + * The type code to write the default value for + */ + protected void printDefaultValue(Object defaultValue, int typeCode) { + if (defaultValue != null) { + boolean shouldUseQuotes = !TypeMap.isNumericType(typeCode); + + if (shouldUseQuotes) { + // characters are only escaped when within a string literal + print(platform.getPlatformInfo().getValueQuoteToken()); + print(escapeStringValue(defaultValue.toString())); + print(platform.getPlatformInfo().getValueQuoteToken()); + } else { + print(defaultValue.toString()); + } + } + } + + /** + * Prints that the column is an auto increment column. + * + * @param table + * The table + * @param column + * The column + */ + protected void writeColumnAutoIncrementStmt(Table table, Column column) { + print("IDENTITY"); + } + + /** + * Prints that a column is nullable. + */ + protected void writeColumnNullableStmt() { + print("NULL"); + } + + /** + * Prints that a column is not nullable. + */ + protected void writeColumnNotNullableStmt() { + print("NOT NULL"); + } + + /** + * Compares the current column in the database with the desired one. Type, + * nullability, size, scale, default value, and precision radix are the + * attributes checked. Currently default values are compared, and null and + * empty string are considered equal. + * + * @param currentColumn + * The current column as it is in the database + * @param desiredColumn + * The desired column + * @return true if the column specifications differ + */ + protected boolean columnsDiffer(Column currentColumn, Column desiredColumn) { + // The createColumn method leaves off the default clause if + // column.getDefaultValue() + // is null. mySQL interprets this as a default of "" or 0, and thus the + // columns + // are always different according to this method. alterDatabase will + // generate + // an alter statement for the column, but it will be the exact same + // definition + // as before. In order to avoid this situation I am ignoring the + // comparison + // if the desired default is null. In order to "un-default" a column + // you'll + // have to have a default="" or default="0" in the schema xml. + // If this is bad for other databases, it is recommended that the + // createColumn + // method use a "DEFAULT NULL" statement if that is what is needed. + // A good way to get this would be to require a defaultValue="" in + // the + // schema xml if you really want null and not just unspecified. + + String desiredDefault = desiredColumn.getDefaultValue(); + String currentDefault = currentColumn.getDefaultValue(); + boolean defaultsEqual = (desiredDefault == null) || desiredDefault.equals(currentDefault); + boolean sizeMatters = platform.getPlatformInfo().hasSize(currentColumn.getTypeCode()) + && (desiredColumn.getSize() != null); + + // We're comparing the jdbc type that corresponds to the native type for + // the + // desired type, in order to avoid repeated altering of a perfectly + // valid column + if ((platform.getPlatformInfo().getTargetJdbcType(desiredColumn.getTypeCode()) != currentColumn + .getTypeCode()) + || (desiredColumn.isRequired() != currentColumn.isRequired()) + || (sizeMatters && !StringUtils.equals(desiredColumn.getSize(), + currentColumn.getSize())) || !defaultsEqual) { + return true; + } else { + return false; + } + } + + /** + * Returns the name to be used for the given foreign key. If the foreign key + * has no specified name, this method determines a unique name for it. The + * name will also be shortened to honor the maximum identifier length + * imposed by the platform. + * + * @param table + * The table for whith the foreign key is defined + * @param fk + * The foreign key + * @return The name + */ + public String getForeignKeyName(Table table, ForeignKey fk) { + String fkName = fk.getName(); + boolean needsName = (fkName == null) || (fkName.length() == 0); + + if (needsName) { + StringBuffer name = new StringBuffer(); + + for (int idx = 0; idx < fk.getReferenceCount(); idx++) { + name.append(fk.getReference(idx).getLocalColumnName()); + name.append("_"); + } + name.append(fk.getForeignTableName()); + fkName = getConstraintName(null, table, "FK", name.toString()); + } + fkName = shortenName(fkName, platform.getPlatformInfo().getMaxForeignKeyNameLength()); + + if (needsName) { + log.warn("Encountered a foreign key in table " + table.getName() + + " that has no name. " + + "DdlUtils will use the auto-generated and shortened name " + fkName + + " instead."); + } + + return fkName; + } + + /** + * Returns the constraint name. This method takes care of length limitations + * imposed by some databases. + * + * @param prefix + * The constraint prefix, can be null + * @param table + * The table that the constraint belongs to + * @param secondPart + * The second name part, e.g. the name of the constraint column + * @param suffix + * The constraint suffix, e.g. a counter (can be + * null) + * @return The constraint name + */ + public String getConstraintName(String prefix, Table table, String secondPart, String suffix) { + StringBuffer result = new StringBuffer(); + + if (prefix != null) { + result.append(prefix); + result.append("_"); + } + result.append(table.getName()); + result.append("_"); + result.append(secondPart); + if (suffix != null) { + result.append("_"); + result.append(suffix); + } + return shortenName(result.toString(), platform.getPlatformInfo() + .getMaxConstraintNameLength()); + } + + /** + * Writes the primary key constraints of the table inside its definition. + * + * @param table + * The table + */ + protected void writeEmbeddedPrimaryKeysStmt(Table table) { + Column[] primaryKeyColumns = table.getPrimaryKeyColumns(); + + if ((primaryKeyColumns.length > 0) && shouldGeneratePrimaryKeys(primaryKeyColumns)) { + printStartOfEmbeddedStatement(); + writePrimaryKeyStmt(table, primaryKeyColumns); + } + } + + /** + * Writes the primary key constraints of the table as alter table + * statements. + * + * @param table + * The table + * @param primaryKeyColumns + * The primary key columns + */ + protected void writeExternalPrimaryKeysCreateStmt(Table table, Column[] primaryKeyColumns) { + if ((primaryKeyColumns.length > 0) && shouldGeneratePrimaryKeys(primaryKeyColumns)) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(table)); + printIndent(); + print("ADD CONSTRAINT "); + printIdentifier(getConstraintName(null, table, "PK", null)); + print(" "); + writePrimaryKeyStmt(table, primaryKeyColumns); + printEndOfStatement(); + } + } + + /** + * Determines whether we should generate a primary key constraint for the + * given primary key columns. + * + * @param primaryKeyColumns + * The pk columns + * @return true if a pk statement should be generated for the + * columns + */ + protected boolean shouldGeneratePrimaryKeys(Column[] primaryKeyColumns) { + return true; + } + + /** + * Writes a primary key statement for the given columns. + * + * @param table + * The table + * @param primaryKeyColumns + * The primary columns + */ + protected void writePrimaryKeyStmt(Table table, Column[] primaryKeyColumns) { + print("PRIMARY KEY ("); + for (int idx = 0; idx < primaryKeyColumns.length; idx++) { + printIdentifier(getColumnName(primaryKeyColumns[idx])); + if (idx < primaryKeyColumns.length - 1) { + print(", "); + } + } + print(")"); + } + + /** + * Returns the index name. This method takes care of length limitations + * imposed by some databases. + * + * @param index + * The index + * @return The index name + */ + public String getIndexName(Index index) { + return shortenName(index.getName(), platform.getPlatformInfo().getMaxConstraintNameLength()); + } + + /** + * Writes the indexes of the given table. + * + * @param table + * The table + */ + protected void writeExternalIndicesCreateStmt(Table table) { + for (int idx = 0; idx < table.getIndexCount(); idx++) { + Index index = table.getIndex(idx); + + if (!index.isUnique() && !platform.getPlatformInfo().isIndicesSupported()) { + throw new ModelException("Platform does not support non-unique indices"); + } + writeExternalIndexCreateStmt(table, index); + } + } + + /** + * Writes the indexes embedded within the create table statement. + * + * @param table + * The table + */ + protected void writeEmbeddedIndicesStmt(Table table) { + if (platform.getPlatformInfo().isIndicesSupported()) { + for (int idx = 0; idx < table.getIndexCount(); idx++) { + printStartOfEmbeddedStatement(); + writeEmbeddedIndexCreateStmt(table, table.getIndex(idx)); + } + } + } + + /** + * Writes the given index of the table. + * + * @param table + * The table + * @param index + * The index + */ + protected void writeExternalIndexCreateStmt(Table table, Index index) { + if (platform.getPlatformInfo().isIndicesSupported()) { + if (index.getName() == null) { + log.warn("Cannot write unnamed index " + index); + } else { + print("CREATE"); + if (index.isUnique()) { + print(" UNIQUE"); + } + print(" INDEX "); + printIdentifier(getIndexName(index)); + print(" ON "); + printIdentifier(getTableName(table)); + print(" ("); + + for (int idx = 0; idx < index.getColumnCount(); idx++) { + IndexColumn idxColumn = index.getColumn(idx); + Column col = table.findColumn(idxColumn.getName()); + + if (col == null) { + // would get null pointer on next line anyway, so throw + // exception + throw new ModelException("Invalid column '" + idxColumn.getName() + + "' on index " + index.getName() + " for table " + table.getName()); + } + if (idx > 0) { + print(", "); + } + printIdentifier(getColumnName(col)); + } + + print(")"); + printEndOfStatement(); + } + } + } + + /** + * Writes the given embedded index of the table. + * + * @param table + * The table + * @param index + * The index + */ + protected void writeEmbeddedIndexCreateStmt(Table table, Index index) { + if ((index.getName() != null) && (index.getName().length() > 0)) { + print(" CONSTRAINT "); + printIdentifier(getIndexName(index)); + } + if (index.isUnique()) { + print(" UNIQUE"); + } else { + print(" INDEX "); + } + print(" ("); + + for (int idx = 0; idx < index.getColumnCount(); idx++) { + IndexColumn idxColumn = index.getColumn(idx); + Column col = table.findColumn(idxColumn.getName()); + + if (col == null) { + // would get null pointer on next line anyway, so throw + // exception + throw new ModelException("Invalid column '" + idxColumn.getName() + "' on index " + + index.getName() + " for table " + table.getName()); + } + if (idx > 0) { + print(", "); + } + printIdentifier(getColumnName(col)); + } + + print(")"); + } + + /** + * Generates the statement to drop a non-embedded index from the database. + * + * @param table + * The table the index is on + * @param index + * The index to drop + */ + public void writeExternalIndexDropStmt(Table table, Index index) { + if (platform.getPlatformInfo().isAlterTableForDropUsed()) { + writeTableAlterStmt(table); + } + print("DROP INDEX "); + printIdentifier(getIndexName(index)); + if (!platform.getPlatformInfo().isAlterTableForDropUsed()) { + print(" ON "); + printIdentifier(getTableName(table)); + } + printEndOfStatement(); + } + + /** + * Writes the foreign key constraints inside a create table () clause. + * + * @param database + * The database model + * @param table + * The table + */ + protected void writeEmbeddedForeignKeysStmt(Database database, Table table) { + for (int idx = 0; idx < table.getForeignKeyCount(); idx++) { + ForeignKey key = table.getForeignKey(idx); + + if (key.getForeignTableName() == null) { + log.warn("Foreign key table is null for key " + key); + } else { + printStartOfEmbeddedStatement(); + if (platform.getPlatformInfo().isEmbeddedForeignKeysNamed()) { + print("CONSTRAINT "); + printIdentifier(getForeignKeyName(table, key)); + print(" "); + } + print("FOREIGN KEY ("); + writeLocalReferences(key); + print(") REFERENCES "); + printIdentifier(getTableName(database.findTable(key.getForeignTableName()))); + print(" ("); + writeForeignReferences(key); + print(")"); + } + } + } + + /** + * Writes a single foreign key constraint using a alter table statement. + * + * @param database + * The database model + * @param table + * The table + * @param key + * The foreign key + */ + protected void writeExternalForeignKeyCreateStmt(Database database, Table table, ForeignKey key) { + if (key.getForeignTableName() == null) { + log.warn("Foreign key table is null for key " + key); + } else { + writeTableAlterStmt(table); + + print("ADD CONSTRAINT "); + printIdentifier(getForeignKeyName(table, key)); + print(" FOREIGN KEY ("); + writeLocalReferences(key); + print(") REFERENCES "); + printIdentifier(getTableName(database.findTable(key.getForeignTableName()))); + print(" ("); + writeForeignReferences(key); + print(")"); + printEndOfStatement(); + } + } + + /** + * Writes a list of local references for the given foreign key. + * + * @param key + * The foreign key + */ + protected void writeLocalReferences(ForeignKey key) { + for (int idx = 0; idx < key.getReferenceCount(); idx++) { + if (idx > 0) { + print(", "); + } + printIdentifier(key.getReference(idx).getLocalColumnName()); + } + } + + /** + * Writes a list of foreign references for the given foreign key. + * + * @param key + * The foreign key + */ + protected void writeForeignReferences(ForeignKey key) { + for (int idx = 0; idx < key.getReferenceCount(); idx++) { + if (idx > 0) { + print(", "); + } + printIdentifier(key.getReference(idx).getForeignColumnName()); + } + } + + /** + * Generates the statement to drop a foreignkey constraint from the database + * using an alter table statement. + * + * @param table + * The table + * @param foreignKey + * The foreign key + */ + protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) { + writeTableAlterStmt(table); + print("DROP CONSTRAINT "); + printIdentifier(getForeignKeyName(table, foreignKey)); + printEndOfStatement(); + } + + // + // Helper methods + // + + /** + * Prints an SQL comment to the current stream. + * + * @param text + * The comment text + */ + protected void printComment(String text) { + if (platform.isSqlCommentsOn()) { + print(platform.getPlatformInfo().getCommentPrefix()); + // Some databases insist on a space after the prefix + print(" "); + print(text); + print(" "); + print(platform.getPlatformInfo().getCommentSuffix()); + println(); + } + } + + /** + * Prints the start of an embedded statement. + */ + protected void printStartOfEmbeddedStatement() { + println(","); + printIndent(); + } + + /** + * Prints the end of statement text, which is typically a semi colon + * followed by a carriage return. + */ + protected void printEndOfStatement() { + // TODO: It might make sense to use a special writer which stores the + // individual + // statements separately (the end of a statement is identified by this + // method) + println(platform.getPlatformInfo().getSqlCommandDelimiter()); + println(); + } + + /** + * Prints a newline. + */ + protected void println() { + print(LINE_SEPARATOR); + } + + /** + * Prints some text. + * + * @param text + * The text to print + */ + protected void print(String text) { + try { + writer.write(text); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + /** + * Returns the delimited version of the identifier (if configured). + * + * @param identifier + * The identifier + * @return The delimited version of the identifier unless the platform is + * configured to use undelimited identifiers; in that case, the + * identifier is returned unchanged + */ + protected String getDelimitedIdentifier(String identifier) { + if (platform.isDelimitedIdentifierModeOn()) { + return platform.getPlatformInfo().getDelimiterToken() + identifier + + platform.getPlatformInfo().getDelimiterToken(); + } else { + return identifier; + } + } + + /** + * Prints the given identifier. For most databases, this will be a delimited + * identifier. + * + * @param identifier + * The identifier + */ + protected void printIdentifier(String identifier) { + print(getDelimitedIdentifier(identifier)); + } + + /** + * Prints the given identifier followed by a newline. For most databases, + * this will be a delimited identifier. + * + * @param identifier + * The identifier + */ + protected void printlnIdentifier(String identifier) { + println(getDelimitedIdentifier(identifier)); + } + + /** + * Prints some text followed by a newline. + * + * @param text + * The text to print + */ + protected void println(String text) { + print(text); + println(); + } + + /** + * Prints the characters used to indent SQL. + */ + protected void printIndent() { + print(getIndent()); + } + + /** + * Creates a reasonably unique identifier only consisting of hexadecimal + * characters and underscores. It looks like + * d578271282b42fce__2955b56e_107df3fbc96__8000 and is 48 + * characters long. + * + * @return The identifier + */ + protected String createUniqueIdentifier() { + return new UID().toString().replace(':', '_').replace('-', '_'); + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Builder.java new file mode 100644 index 0000000000..579d98de9b --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Builder.java @@ -0,0 +1,234 @@ +package org.jumpmind.symmetric.db.platform.db2; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; +import java.util.Iterator; +import java.util.List; + +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.PrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; +import org.jumpmind.symmetric.util.Log; + +/* + * The SQL Builder for DB2. + */ +public class Db2Builder extends SqlBuilder { + + public Db2Builder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + addEscapedCharSequence("'", "''"); + } + + @Override + protected String getNativeDefaultValue(Column column) { + if ((column.getTypeCode() == Types.BIT) + || (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils + .determineBooleanTypeCode()))) { + return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), + Types.SMALLINT).toString(); + } else { + return super.getNativeDefaultValue(column); + } + } + + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { + print("GENERATED BY DEFAULT AS IDENTITY"); + } + + @Override + public String getSelectLastIdentityValues(Table table) { + return "VALUES IDENTITY_VAL_LOCAL()"; + } + + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { + // Index names in DB2 are unique to a schema and hence Derby does not + // use the ON clause + print("DROP INDEX "); + printIdentifier(getIndexName(index)); + printEndOfStatement(); + } + + @Override + protected void writeCastExpression(Column sourceColumn, Column targetColumn) { + String sourceNativeType = getBareNativeType(sourceColumn); + String targetNativeType = getBareNativeType(targetColumn); + + if (sourceNativeType.equals(targetNativeType)) { + printIdentifier(getColumnName(sourceColumn)); + } else { + String type = getSqlType(targetColumn); + + // DB2 has the limitation that it cannot convert numeric values + // to VARCHAR, though it can convert them to CHAR + if (TypeMap.isNumericType(sourceColumn.getTypeCode()) + && "VARCHAR".equalsIgnoreCase(targetNativeType)) { + Object sizeSpec = targetColumn.getSize(); + + if (sizeSpec == null) { + sizeSpec = platform.getPlatformInfo() + .getDefaultSize(targetColumn.getTypeCode()); + } + type = "CHAR(" + sizeSpec.toString() + ")"; + } + + print("CAST("); + printIdentifier(getColumnName(sourceColumn)); + print(" AS "); + print(type); + print(")"); + } + } + + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + // DB2 provides only limited ways to alter a column, so we don't use + // them + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; + + // DB2 can only add not insert columns + // Also, DB2 does not allow the GENERATED BY DEFAULT AS IDENTITY + // clause in + // the ALTER TABLE ADD COLUMN statement, so we have to rebuild + // the table instead + if ((addColumnChange.getNextColumn() == null) + && !addColumnChange.getNewColumn().isAutoIncrement()) { + processChange(currentModel, desiredModel, addColumnChange); + changeIt.remove(); + } + } + } + + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddPrimaryKeyChange) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); + changeIt.remove(); + } else if (change instanceof PrimaryKeyChange) { + processChange(currentModel, desiredModel, (PrimaryKeyChange) change); + changeIt.remove(); + } else if (change instanceof RemovePrimaryKeyChange) { + processChange(currentModel, desiredModel, (RemovePrimaryKeyChange) change); + changeIt.remove(); + } + } + } + + /* + * Processes the addition of a column to a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("ADD COLUMN "); + writeColumn(change.getChangedTable(), change.getNewColumn()); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a column from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP COLUMN "); + printIdentifier(getColumnName(change.getColumn())); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a primary key from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemovePrimaryKeyChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP PRIMARY KEY"); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the change of the primary key of a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + PrimaryKeyChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP PRIMARY KEY"); + printEndOfStatement(); + writeExternalPrimaryKeysCreateStmt(change.getChangedTable(), + change.getNewPrimaryKeyColumns()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2ModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2ModelReader.java similarity index 89% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2ModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2ModelReader.java index 61055d93ad..6504b00cbb 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/Db2ModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2ModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.db2; +package org.jumpmind.symmetric.db.platform.db2; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -32,19 +32,17 @@ import org.apache.oro.text.regex.PatternMatcher; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a Db2 UDB database. - * - * @version $Revision: $ */ public class Db2ModelReader extends JdbcModelReader { @@ -60,7 +58,7 @@ public class Db2ModelReader extends JdbcModelReader * * @param platform The platform that this model reader belongs to */ - public Db2ModelReader(Platform platform) + public Db2ModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Platform.java new file mode 100644 index 0000000000..b75809fb68 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/Db2Platform.java @@ -0,0 +1,102 @@ +package org.jumpmind.symmetric.db.platform.db2; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The DB2 platform implementation. + */ +public class Db2Platform extends AbstractDatabasePlatform { + + /* Database name of this platform. */ + public static final String DATABASENAME = "DB2"; + + /* The standard DB2 jdbc driver. */ + public static final String JDBC_DRIVER = "com.ibm.db2.jcc.DB2Driver"; + + /* Older name for the jdbc driver. */ + public static final String JDBC_DRIVER_OLD1 = "COM.ibm.db2.jdbc.app.DB2Driver"; + + /* Older name for the jdbc driver. */ + public static final String JDBC_DRIVER_OLD2 = "COM.ibm.db2os390.sqlj.jdbc.DB2SQLJDriver"; + + /* The JTOpen JDBC Driver. */ + public static final String JDBC_DRIVER_JTOPEN = "com.ibm.as400.access.AS400JDBCDriver"; + + /* The subprotocol used by the standard DB2 driver. */ + public static final String JDBC_SUBPROTOCOL = "db2"; + + /* An alternative subprotocol used by the standard DB2 driver on OS/390. */ + public static final String JDBC_SUBPROTOCOL_OS390_1 = "db2os390"; + + /* An alternative subprotocol used by the standard DB2 driver on OS/390. */ + public static final String JDBC_SUBPROTOCOL_OS390_2 = "db2os390sqlj"; + + /* An alternative subprotocol used by the JTOpen driver on OS/400. */ + public static final String JDBC_SUBPROTOCOL_JTOPEN = "as400"; + + /* + * Creates a new platform instance. + */ + public Db2Platform() { + + // the BINARY types are also handled by Db2Builder.getSqlType(Column) + info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.BINARY, "CHAR {0} FOR BIT DATA"); + info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.LONGVARBINARY, "LONG VARCHAR FOR BIT DATA"); + info.addNativeTypeMapping(Types.LONGVARCHAR, "LONG VARCHAR"); + info.addNativeTypeMapping(Types.NULL, "LONG VARCHAR FOR BIT DATA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.NUMERIC, "DECIMAL", Types.DECIMAL); + info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.VARBINARY, "VARCHAR {0} FOR BIT DATA"); + info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); + + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARCHAR, 254); + info.setDefaultSize(Types.BINARY, 254); + info.setDefaultSize(Types.VARBINARY, 254); + info.setStoresUpperCaseInCatalog(true); + + info.setMaxIdentifierLength(128); + info.setMaxColumnNameLength(128); + info.setMaxConstraintNameLength(128); + info.setMaxForeignKeyNameLength(128); + + modelReader = new Db2ModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new Db2Builder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/db2/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/db2/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyBuilder.java similarity index 54% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyBuilder.java index 93b4edd4b9..5f2ee04336 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyBuilder.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.derby; +package org.jumpmind.symmetric.db.platform.derby; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,69 +19,57 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.sql.Types; import java.util.Iterator; import java.util.List; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.cloudscape.CloudscapeBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; + +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; +import org.jumpmind.symmetric.util.Log; /* * The SQL Builder for Derby. - * - * @version $Revision: 279413 $ */ -public class DerbyBuilder extends CloudscapeBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public DerbyBuilder(Platform platform) - { - super(platform); +public class DerbyBuilder extends SqlBuilder { + + public DerbyBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + addEscapedCharSequence("'", "''"); } - /* - * {@inheritDoc} - */ - protected String getNativeDefaultValue(Column column) - { - if ((column.getTypeCode() == Types.BIT) || - (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode()))) - { - return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString(); - } - else - { + @Override + protected String getNativeDefaultValue(Column column) { + if ((column.getTypeCode() == Types.BIT) + || (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils + .determineBooleanTypeCode()))) { + return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), + Types.SMALLINT).toString(); + } else { return super.getNativeDefaultValue(column); } } - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { + @Override + public String getSelectLastIdentityValues(Table table) { + return "VALUES IDENTITY_VAL_LOCAL()"; + } + + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { print("GENERATED BY DEFAULT AS IDENTITY"); } - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { // Index names in Derby are unique to a schema and hence Derby does not // use the ON clause print("DROP INDEX "); @@ -89,25 +77,19 @@ public void writeExternalIndexDropStmt(Table table, Index index) throws IOExcept printEndOfStatement(); } - /* - * {@inheritDoc} - */ - protected void writeCastExpression(Column sourceColumn, Column targetColumn) throws IOException - { + @Override + protected void writeCastExpression(Column sourceColumn, Column targetColumn) { String sourceNativeType = getBareNativeType(sourceColumn); String targetNativeType = getBareNativeType(targetColumn); - if (sourceNativeType.equals(targetNativeType)) - { + if (sourceNativeType.equals(targetNativeType)) { printIdentifier(getColumnName(sourceColumn)); - } - else - { - // Derby currently has the limitation that it cannot convert numeric values + } else { + // Derby currently has the limitation that it cannot convert numeric + // values // to VARCHAR, though it can convert them to CHAR - if (TypeMap.isNumericType(sourceColumn.getTypeCode()) && - "VARCHAR".equalsIgnoreCase(targetNativeType)) - { + if (TypeMap.isNumericType(sourceColumn.getTypeCode()) + && "VARCHAR".equalsIgnoreCase(targetNativeType)) { targetNativeType = "CHAR"; } @@ -118,50 +100,46 @@ protected void writeCastExpression(Column sourceColumn, Column targetColumn) thr } } - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, Database desiredModel, Table sourceTable, Table targetTable, Map parameters, List changes) throws IOException - { + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { // Derby provides a way to alter the size of a column but it is limited // (no pk or fk columns, only for VARCHAR columns), so we don't use it - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; // Derby can only add not insert columns, and the columns // cannot be identity columns - if (addColumnChange.isAtEnd() && !addColumnChange.getNewColumn().isAutoIncrement()) - { + if (addColumnChange.isAtEnd() && !addColumnChange.getNewColumn().isAutoIncrement()) { processChange(currentModel, desiredModel, addColumnChange); changeIt.remove(); } } } - super.processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, parameters, changes); + super.processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, + changes); } /* * Processes the addition of a column to a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("ADD COLUMN "); writeColumn(change.getChangedTable(), change.getNewColumn()); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyModelReader.java similarity index 83% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyModelReader.java index a21b8ab578..012a7fb3b8 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/DerbyModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.derby; +package org.jumpmind.symmetric.db.platform.derby; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -23,14 +23,14 @@ import java.sql.SQLException; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a Derby database. @@ -44,7 +44,7 @@ public class DerbyModelReader extends JdbcModelReader * * @param platform The platform that this model reader belongs to */ - public DerbyModelReader(Platform platform) + public DerbyModelReader(IDatabasePlatform platform) { super(platform); } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyPlatform.java new file mode 100644 index 0000000000..f24d931e71 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/DerbyPlatform.java @@ -0,0 +1,87 @@ +package org.jumpmind.symmetric.db.platform.derby; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for Derby. + */ +public class DerbyPlatform extends AbstractDatabasePlatform { + + /* Database name of this platform. */ + public static final String DATABASENAME = "Derby"; + + /* The derby jdbc driver for use as a client for a normal server. */ + public static final String JDBC_DRIVER = "org.apache.derby.jdbc.ClientDriver"; + + /* The derby jdbc driver for use as an embedded database. */ + public static final String JDBC_DRIVER_EMBEDDED = "org.apache.derby.jdbc.EmbeddedDriver"; + + /* The subprotocol used by the derby drivers. */ + public static final String JDBC_SUBPROTOCOL = "derby"; + + /* + * Creates a new Derby platform instance. + */ + public DerbyPlatform() { + + info.setMaxIdentifierLength(128); + info.setSystemForeignKeyIndicesAlwaysNonUnique(true); + info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.BINARY, "CHAR {0} FOR BIT DATA"); + info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.DISTINCT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.LONGVARBINARY, "LONG VARCHAR FOR BIT DATA"); + info.addNativeTypeMapping(Types.LONGVARCHAR, "LONG VARCHAR"); + info.addNativeTypeMapping(Types.NULL, "LONG VARCHAR FOR BIT DATA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.REF, "LONG VARCHAR FOR BIT DATA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.VARBINARY, "VARCHAR {0} FOR BIT DATA"); + info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); + info.addNativeTypeMapping("DATALINK", "LONG VARCHAR FOR BIT DATA", "LONGVARBINARY"); + + info.setDefaultSize(Types.BINARY, 254); + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARBINARY, 254); + info.setDefaultSize(Types.VARCHAR, 254); + + info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE"); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); + info.setStoresUpperCaseInCatalog(true); + modelReader = new DerbyModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new DerbyBuilder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/derby/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/derby/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdBuilder.java similarity index 51% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdBuilder.java index 4a62226000..f0821137c5 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdBuilder.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.firebird; +package org.jumpmind.symmetric.db.platform.firebird; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,82 +19,68 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.sql.Types; import java.util.Iterator; import java.util.List; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; + +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; +import org.jumpmind.symmetric.util.Log; /* * The SQL Builder for the FireBird database. - * - * @version $Revision: 231306 $ */ -public class FirebirdBuilder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public FirebirdBuilder(Platform platform) - { - super(platform); +public class FirebirdBuilder extends SqlBuilder { + public FirebirdBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); addEscapedCharSequence("'", "''"); } - /* - * {@inheritDoc} - */ - public void createTable(Database database, Table table, Map parameters) throws IOException - { - super.createTable(database, table, parameters); + @Override + public void createTable(Database database, Table table) { + super.createTable(database, table); // creating generator and trigger for auto-increment Column[] columns = table.getAutoIncrementColumns(); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { writeAutoIncrementCreateStmts(database, table, columns[idx]); } } - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { + @Override + public void dropTable(Table table) { // dropping generators for auto-increment Column[] columns = table.getAutoIncrementColumns(); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { writeAutoIncrementDropStmts(table, columns[idx]); } super.dropTable(table); } /* - * Writes the creation statements to make the given column an auto-increment column. + * Writes the creation statements to make the given column an auto-increment + * column. * * @param database The database model - * @param table The table - * @param column The column to make auto-increment + * + * @param table The table + * + * @param column The column to make auto-increment */ - private void writeAutoIncrementCreateStmts(Database database, Table table, Column column) throws IOException - { + private void writeAutoIncrementCreateStmts(Database database, Table table, Column column) + { print("CREATE GENERATOR "); printIdentifier(getGeneratorName(table, column)); printEndOfStatement(); @@ -115,13 +101,14 @@ private void writeAutoIncrementCreateStmts(Database database, Table table, Colum } /* - * Writes the statements to drop the auto-increment status for the given column. + * Writes the statements to drop the auto-increment status for the given + * column. + * + * @param table The table * - * @param table The table * @param column The column to remove the auto-increment status for */ - private void writeAutoIncrementDropStmts(Table table, Column column) throws IOException - { + private void writeAutoIncrementDropStmts(Table table, Column column) { print("DROP TRIGGER "); printIdentifier(getTriggerName(table, column)); printEndOfStatement(); @@ -134,12 +121,13 @@ private void writeAutoIncrementDropStmts(Table table, Column column) throws IOEx /* * Determines the name of the trigger for an auto-increment column. * - * @param table The table + * @param table The table + * * @param column The auto-increment column + * * @return The trigger name */ - protected String getTriggerName(Table table, Column column) - { + protected String getTriggerName(Table table, Column column) { String secondPart = column.getName(); // make sure a backup table gets a different name than the original if (table.getName().endsWith("_")) { @@ -151,12 +139,13 @@ protected String getTriggerName(Table table, Column column) /* * Determines the name of the generator for an auto-increment column. * - * @param table The table + * @param table The table + * * @param column The auto-increment column + * * @return The generator name */ - protected String getGeneratorName(Table table, Column column) - { + protected String getGeneratorName(Table table, Column column) { String secondPart = column.getName(); // make sure a backup table gets a different name than the original if (table.getName().endsWith("_")) { @@ -165,32 +154,22 @@ protected String getGeneratorName(Table table, Column column) return getConstraintName("gen", table, secondPart, null); } - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { // we're using a generator } - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { + @Override + public String getSelectLastIdentityValues(Table table) { Column[] columns = table.getAutoIncrementColumns(); - if (columns.length == 0) - { + if (columns.length == 0) { return null; - } - else - { + } else { StringBuffer result = new StringBuffer(); - + result.append("SELECT "); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { result.append("GEN_ID("); result.append(getDelimitedIdentifier(getGeneratorName(table, columns[idx]))); result.append(", 0)"); @@ -200,101 +179,81 @@ public String getSelectLastIdentityValues(Table table) } } - /* - * {@inheritDoc} - */ - protected String getNativeDefaultValue(Column column) - { - if ((column.getTypeCode() == Types.BIT) || - (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode()))) - { - return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString(); - } - else - { + @Override + protected String getNativeDefaultValue(Column column) { + if ((column.getTypeCode() == Types.BIT) + || (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils + .determineBooleanTypeCode()))) { + return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), + Types.SMALLINT).toString(); + } else { return super.getNativeDefaultValue(column); } } - /* - * - * {@inheritDoc} - */ - public void createExternalForeignKeys(Database database) throws IOException - { - for (int idx = 0; idx < database.getTableCount(); idx++) - { + @Override + public void createExternalForeignKeys(Database database) { + for (int idx = 0; idx < database.getTableCount(); idx++) { createExternalForeignKeys(database, database.getTable(idx)); } } - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { - // Index names in Firebird are unique to a schema and hence Firebird does not + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { + // Index names in Firebird are unique to a schema and hence Firebird + // does not // use the ON clause print("DROP INDEX "); printIdentifier(getIndexName(index)); printEndOfStatement(); } - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, Database desiredModel, Table sourceTable, Table targetTable, Map parameters, List changes) throws IOException - { - // TODO: Dropping of primary keys is currently not supported because we cannot - // determine the pk constraint names and drop them in one go - // (We could used a stored procedure if Firebird would allow them to use DDL) - // This will be easier once named primary keys are supported + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + // TODO: Dropping of primary keys is currently not supported because we + // cannot + // determine the pk constraint names and drop them in one go + // (We could used a stored procedure if Firebird would allow them to use + // DDL) + // This will be easier once named primary keys are supported boolean pkColumnAdded = false; - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; - // TODO: we cannot add columns to the primary key this way - // because we would have to drop the pk first and then - // add a new one afterwards which is not supported yet - if (addColumnChange.getNewColumn().isPrimaryKey()) - { - pkColumnAdded = true; + // TODO: we cannot add columns to the primary key this way + // because we would have to drop the pk first and then + // add a new one afterwards which is not supported yet + if (addColumnChange.getNewColumn().isPrimaryKey()) { + pkColumnAdded = true; + } else { + processChange(currentModel, desiredModel, addColumnChange); + changeIt.remove(); + } + } else if (change instanceof RemoveColumnChange) { + RemoveColumnChange removeColumnChange = (RemoveColumnChange) change; + + // TODO: we cannot drop primary key columns this way + // because we would have to drop the pk first and then + // add a new one afterwards which is not supported yet + if (!removeColumnChange.getColumn().isPrimaryKey()) { + processChange(currentModel, desiredModel, removeColumnChange); + changeIt.remove(); } - else - { - processChange(currentModel, desiredModel, addColumnChange); - changeIt.remove(); - } - } - else if (change instanceof RemoveColumnChange) - { - RemoveColumnChange removeColumnChange = (RemoveColumnChange)change; - - // TODO: we cannot drop primary key columns this way - // because we would have to drop the pk first and then - // add a new one afterwards which is not supported yet - if (!removeColumnChange.getColumn().isPrimaryKey()) - { - processChange(currentModel, desiredModel, removeColumnChange); - changeIt.remove(); - } } } - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - // we can only add a primary key if all columns are present in the table + // we can only add a primary key if all columns are present in the + // table // i.e. none was added during this alteration - if ((change instanceof AddPrimaryKeyChange) && !pkColumnAdded) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); + if ((change instanceof AddPrimaryKeyChange) && !pkColumnAdded) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); changeIt.remove(); } } @@ -304,13 +263,13 @@ else if (change instanceof RemoveColumnChange) * Processes the addition of a column to a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); @@ -318,18 +277,20 @@ protected void processChange(Database currentModel, writeColumn(change.getChangedTable(), change.getNewColumn()); printEndOfStatement(); - Table curTable = currentModel.findTable(change.getChangedTable().getName(), getPlatform().isDelimitedIdentifierModeOn()); + Table curTable = currentModel.findTable(change.getChangedTable().getName(), + platform.isDelimitedIdentifierModeOn()); - if (!change.isAtEnd()) - { + if (!change.isAtEnd()) { Column prevColumn = change.getPreviousColumn(); - if (prevColumn != null) - { - // we need the corresponding column object from the current table - prevColumn = curTable.findColumn(prevColumn.getName(), getPlatform().isDelimitedIdentifierModeOn()); + if (prevColumn != null) { + // we need the corresponding column object from the current + // table + prevColumn = curTable.findColumn(prevColumn.getName(), + platform.isDelimitedIdentifierModeOn()); } - // Even though Firebird can only add columns, we can move them later on + // Even though Firebird can only add columns, we can move them later + // on print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); @@ -337,29 +298,28 @@ protected void processChange(Database currentModel, printIdentifier(getColumnName(change.getNewColumn())); print(" POSITION "); // column positions start at 1 in Firebird - print(prevColumn == null ? "1" : String.valueOf(curTable.getColumnIndex(prevColumn) + 2)); + print(prevColumn == null ? "1" : String + .valueOf(curTable.getColumnIndex(prevColumn) + 2)); printEndOfStatement(); } - if (change.getNewColumn().isAutoIncrement()) - { + if (change.getNewColumn().isAutoIncrement()) { writeAutoIncrementCreateStmts(currentModel, curTable, change.getNewColumn()); } - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a column from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { - if (change.getColumn().isAutoIncrement()) - { + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { + if (change.getColumn().isAutoIncrement()) { writeAutoIncrementDropStmts(change.getChangedTable(), change.getColumn()); } print("ALTER TABLE "); @@ -368,6 +328,6 @@ protected void processChange(Database currentModel, print("DROP "); printIdentifier(getColumnName(change.getColumn())); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdModelReader.java similarity index 56% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdModelReader.java index e6c894a1e3..2bbceaaf23 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.firebird; +package org.jumpmind.symmetric.db.platform.firebird; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -32,29 +32,26 @@ import java.util.Map; import org.apache.commons.collections.map.ListOrderedMap; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.platform.SqlBuilder; /* * The Jdbc Model Reader for Firebird. - * - * @version $Revision: $ */ -public class FirebirdModelReader extends JdbcModelReader -{ +public class FirebirdModelReader extends JdbcModelReader { /* * Creates a new model reader for Firebird databases. * * @param platform The platform that this model reader belongs to */ - public FirebirdModelReader(Platform platform) - { + public FirebirdModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); setDefaultSchemaPattern(null); @@ -62,175 +59,145 @@ public FirebirdModelReader(Platform platform) } @Override - protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { + protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, Map values) + throws SQLException { Table table = super.readTable(connection, metaData, values); - if (table != null) - { - determineAutoIncrementColumns(connection, table); + if (table != null) { + determineAutoIncrementColumns(connection, table); } return table; } @Override - protected Collection readColumns(DatabaseMetaDataWrapper metaData, String tableName) throws SQLException - { + protected Collection readColumns(DatabaseMetaDataWrapper metaData, String tableName) + throws SQLException { ResultSet columnData = null; - try - { + try { List columns = new ArrayList(); - if (getPlatform().isDelimitedIdentifierModeOn()) - { + if (getPlatform().isDelimitedIdentifierModeOn()) { // Jaybird has a problem when delimited identifiers are used as // it is not able to find the columns for the table // So we have to filter manually below - columnData = metaData.getColumns(getDefaultTablePattern(), getDefaultColumnPattern()); + columnData = metaData.getColumns(getDefaultTablePattern(), + getDefaultColumnPattern()); - while (columnData.next()) - { + while (columnData.next()) { Map values = readColumns(columnData, getColumnsForColumn()); - if (tableName.equals(values.get("TABLE_NAME"))) - { + if (tableName.equals(values.get("TABLE_NAME"))) { columns.add(readColumn(metaData, values)); } } - } - else - { + } else { columnData = metaData.getColumns(tableName, getDefaultColumnPattern()); - while (columnData.next()) - { + while (columnData.next()) { Map values = readColumns(columnData, getColumnsForColumn()); - if (tableName.equals(values.get("TABLE_NAME"))) - { + if (tableName.equals(values.get("TABLE_NAME"))) { columns.add(readColumn(metaData, values)); } } } return columns; - } - finally - { - if (columnData != null) - { + } finally { + if (columnData != null) { columnData.close(); } } } @Override - protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { - Column column = super.readColumn(metaData, values); - - if (column.getTypeCode() == Types.FLOAT) - { - column.setTypeCode(Types.REAL); - } - else if (TypeMap.isTextType(column.getTypeCode())) - { + protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException { + Column column = super.readColumn(metaData, values); + + if (column.getTypeCode() == Types.FLOAT) { + column.setTypeCode(Types.REAL); + } else if (TypeMap.isTextType(column.getTypeCode())) { column.setDefaultValue(unescape(column.getDefaultValue(), "'", "''")); } - return column; - } + return column; + } - /* - * Helper method that determines the auto increment status using Firebird's system tables. - * + /* + * Helper method that determines the auto increment status using Firebird's + * system tables. + * * @param table The table */ - protected void determineAutoIncrementColumns(Connection connection, Table table) throws SQLException - { - // Since for long table and column names, the generator name will be shortened - // we have to determine for each column whether there is a generator for it - FirebirdBuilder builder = (FirebirdBuilder)getPlatform().getSqlBuilder(); - Column[] columns = table.getColumns(); - HashMap names = new HashMap(); - String name; - - for (int idx = 0; idx < columns.length; idx++) - { - name = builder.getGeneratorName(table, columns[idx]); - if (!getPlatform().isDelimitedIdentifierModeOn()) - { + protected void determineAutoIncrementColumns(Connection connection, Table table) + throws SQLException { + // Since for long table and column names, the generator name will be + // shortened + // we have to determine for each column whether there is a generator for + // it + Column[] columns = table.getColumns(); + HashMap names = new HashMap(); + String name; + + for (int idx = 0; idx < columns.length; idx++) { + name = ((FirebirdBuilder) getPlatform().createSqlBuilder(null)).getGeneratorName(table, + columns[idx]); + if (!getPlatform().isDelimitedIdentifierModeOn()) { name = name.toUpperCase(); } - names.put(name, columns[idx]); - } + names.put(name, columns[idx]); + } - Statement stmt = connection.createStatement(); + Statement stmt = connection.createStatement(); - try - { + try { ResultSet rs = stmt.executeQuery("SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS"); - while (rs.next()) - { + while (rs.next()) { String generatorName = rs.getString(1).trim(); - Column column = (Column)names.get(generatorName); + Column column = (Column) names.get(generatorName); - if (column != null) - { + if (column != null) { column.setAutoIncrement(true); } } - rs.close(); - } - finally - { + rs.close(); + } finally { stmt.close(); } } @Override - protected Collection readPrimaryKeyNames(DatabaseMetaDataWrapper metaData, String tableName) throws SQLException - { - List pks = new ArrayList(); + protected Collection readPrimaryKeyNames(DatabaseMetaDataWrapper metaData, String tableName) + throws SQLException { + List pks = new ArrayList(); ResultSet pkData = null; - try - { - if (getPlatform().isDelimitedIdentifierModeOn()) - { + try { + if (getPlatform().isDelimitedIdentifierModeOn()) { // Jaybird has a problem when delimited identifiers are used as // it is not able to find the primary key info for the table // So we have to filter manually below pkData = metaData.getPrimaryKeys(getDefaultTablePattern()); - while (pkData.next()) - { + while (pkData.next()) { Map values = readColumns(pkData, getColumnsForPK()); - - if (tableName.equals(values.get("TABLE_NAME"))) - { + + if (tableName.equals(values.get("TABLE_NAME"))) { pks.add(readPrimaryKeyName(metaData, values)); } } - } - else - { + } else { pkData = metaData.getPrimaryKeys(tableName); - while (pkData.next()) - { + while (pkData.next()) { Map values = readColumns(pkData, getColumnsForPK()); - - if (tableName.equals(values.get("TABLE_NAME"))) - { + + if (tableName.equals(values.get("TABLE_NAME"))) { pks.add(readPrimaryKeyName(metaData, values)); } } } - } - finally - { - if (pkData != null) - { + } finally { + if (pkData != null) { pkData.close(); } } @@ -238,47 +205,36 @@ protected Collection readPrimaryKeyNames(DatabaseMetaDataWrapper metaData, Strin } @Override - protected Collection readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException - { - Map fks = new ListOrderedMap(); + protected Collection readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, + String tableName) throws SQLException { + Map fks = new ListOrderedMap(); ResultSet fkData = null; - try - { - if (getPlatform().isDelimitedIdentifierModeOn()) - { + try { + if (getPlatform().isDelimitedIdentifierModeOn()) { // Jaybird has a problem when delimited identifiers are used as // it is not able to find the foreign key info for the table // So we have to filter manually below fkData = metaData.getForeignKeys(getDefaultTablePattern()); - while (fkData.next()) - { + while (fkData.next()) { Map values = readColumns(fkData, getColumnsForFK()); - - if (tableName.equals(values.get("FKTABLE_NAME"))) - { + + if (tableName.equals(values.get("FKTABLE_NAME"))) { readForeignKey(metaData, values, fks); } } - } - else - { + } else { fkData = metaData.getForeignKeys(tableName); - while (fkData.next()) - { + while (fkData.next()) { Map values = readColumns(fkData, getColumnsForFK()); - - if (tableName.equals(values.get("FKTABLE_NAME"))) - { + + if (tableName.equals(values.get("FKTABLE_NAME"))) { readForeignKey(metaData, values, fks); } } } - } - finally - { - if (fkData != null) - { + } finally { + if (fkData != null) { fkData.close(); } } @@ -286,43 +242,42 @@ protected Collection readForeignKeys(Connection connection, DatabaseMetaDataWrap } @Override - protected Collection readIndices(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException - { - // Jaybird is not able to read indices when delimited identifiers are turned on, + protected Collection readIndices(Connection connection, DatabaseMetaDataWrapper metaData, + String tableName) throws SQLException { + // Jaybird is not able to read indices when delimited identifiers are + // turned on, // so we gather the data manually using Firebird's system tables - Map indices = new ListOrderedMap(); - StringBuffer query = new StringBuffer(); - + Map indices = new ListOrderedMap(); + StringBuilder query = new StringBuilder(); + query.append("SELECT a.RDB$INDEX_NAME INDEX_NAME, b.RDB$RELATION_NAME TABLE_NAME, b.RDB$UNIQUE_FLAG NON_UNIQUE,"); query.append(" a.RDB$FIELD_POSITION ORDINAL_POSITION, a.RDB$FIELD_NAME COLUMN_NAME, 3 INDEX_TYPE"); query.append(" FROM RDB$INDEX_SEGMENTS a, RDB$INDICES b WHERE a.RDB$INDEX_NAME=b.RDB$INDEX_NAME AND b.RDB$RELATION_NAME = ?"); - PreparedStatement stmt = connection.prepareStatement(query.toString()); - ResultSet indexData = null; + PreparedStatement stmt = connection.prepareStatement(query.toString()); + ResultSet indexData = null; - stmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName.toUpperCase()); + stmt.setString(1, + getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName.toUpperCase()); - try - { - indexData = stmt.executeQuery(); + try { + indexData = stmt.executeQuery(); - while (indexData.next()) - { + while (indexData.next()) { Map values = readColumns(indexData, getColumnsForIndex()); // we have to reverse the meaning of the unique flag - values.put("NON_UNIQUE", Boolean.FALSE.equals(values.get("NON_UNIQUE")) ? Boolean.TRUE : Boolean.FALSE); + values.put("NON_UNIQUE", + Boolean.FALSE.equals(values.get("NON_UNIQUE")) ? Boolean.TRUE + : Boolean.FALSE); // and trim the names - values.put("INDEX_NAME", ((String)values.get("INDEX_NAME")).trim()); - values.put("TABLE_NAME", ((String)values.get("TABLE_NAME")).trim()); - values.put("COLUMN_NAME", ((String)values.get("COLUMN_NAME")).trim()); + values.put("INDEX_NAME", ((String) values.get("INDEX_NAME")).trim()); + values.put("TABLE_NAME", ((String) values.get("TABLE_NAME")).trim()); + values.put("COLUMN_NAME", ((String) values.get("COLUMN_NAME")).trim()); readIndex(metaData, values, indices); } - } - finally - { - if (indexData != null) - { + } finally { + if (indexData != null) { indexData.close(); } } @@ -330,50 +285,54 @@ protected Collection readIndices(Connection connection, DatabaseMetaDataWrapper } @Override - protected boolean isInternalPrimaryKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, Index index) throws SQLException - { - String tableName = getPlatform().getSqlBuilder().getTableName(table); - String indexName = getPlatform().getSqlBuilder().getIndexName(index); - StringBuffer query = new StringBuffer(); + protected boolean isInternalPrimaryKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, Index index) throws SQLException { + SqlBuilder builder = getPlatform().createSqlBuilder(null); + String tableName = builder.getTableName(table); + String indexName = builder.getIndexName(index); + StringBuilder query = new StringBuilder(); query.append("SELECT RDB$CONSTRAINT_NAME FROM RDB$RELATION_CONSTRAINTS where RDB$RELATION_NAME=? AND RDB$CONSTRAINT_TYPE=? AND RDB$INDEX_NAME=?"); PreparedStatement stmt = connection.prepareStatement(query.toString()); - try - { - stmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName.toUpperCase()); + try { + stmt.setString( + 1, + getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName + .toUpperCase()); stmt.setString(2, "PRIMARY KEY"); stmt.setString(3, indexName); ResultSet resultSet = stmt.executeQuery(); return resultSet.next(); - } - finally - { - if (stmt != null) - { + } finally { + if (stmt != null) { stmt.close(); } } } @Override - protected boolean isInternalForeignKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) throws SQLException - { - String tableName = getPlatform().getSqlBuilder().getTableName(table); - String indexName = getPlatform().getSqlBuilder().getIndexName(index); - String fkName = getPlatform().getSqlBuilder().getForeignKeyName(table, fk); - StringBuffer query = new StringBuffer(); + protected boolean isInternalForeignKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) + throws SQLException { + SqlBuilder builder = getPlatform().createSqlBuilder(null); + String tableName = builder.getTableName(table); + String indexName = builder.getIndexName(index); + String fkName = builder.getForeignKeyName(table, fk); + StringBuilder query = new StringBuilder(); query.append("SELECT RDB$CONSTRAINT_NAME FROM RDB$RELATION_CONSTRAINTS where RDB$RELATION_NAME=? AND RDB$CONSTRAINT_TYPE=? AND RDB$CONSTRAINT_NAME=? AND RDB$INDEX_NAME=?"); PreparedStatement stmt = connection.prepareStatement(query.toString()); - try - { - stmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName.toUpperCase()); + try { + stmt.setString( + 1, + getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName + .toUpperCase()); stmt.setString(2, "FOREIGN KEY"); stmt.setString(3, fkName); stmt.setString(4, indexName); @@ -381,78 +340,68 @@ protected boolean isInternalForeignKeyIndex(Connection connection, DatabaseMetaD ResultSet resultSet = stmt.executeQuery(); return resultSet.next(); - } - finally - { - if (stmt != null) - { + } finally { + if (stmt != null) { stmt.close(); } } } @Override - public String determineSchemaOf(Connection connection, String schemaPattern, Table table) throws SQLException - { - ResultSet tableData = null; + public String determineSchemaOf(Connection connection, String schemaPattern, Table table) + throws SQLException { + ResultSet tableData = null; ResultSet columnData = null; - try - { + try { DatabaseMetaDataWrapper metaData = new DatabaseMetaDataWrapper(); metaData.setMetaData(connection.getMetaData()); metaData.setCatalog(getDefaultCatalogPattern()); - metaData.setSchemaPattern(schemaPattern == null ? getDefaultSchemaPattern() : schemaPattern); + metaData.setSchemaPattern(schemaPattern == null ? getDefaultSchemaPattern() + : schemaPattern); metaData.setTableTypes(getDefaultTableTypes()); String tablePattern = table.getName(); - if (getPlatform().isDelimitedIdentifierModeOn()) - { + if (getPlatform().isDelimitedIdentifierModeOn()) { tablePattern = tablePattern.toUpperCase(); } tableData = metaData.getTables(tablePattern); - boolean found = false; - String schema = null; + boolean found = false; + String schema = null; - while (!found && tableData.next()) - { - Map values = readColumns(tableData, getColumnsForTable()); - String tableName = (String)values.get("TABLE_NAME"); + while (!found && tableData.next()) { + Map values = readColumns(tableData, getColumnsForTable()); + String tableName = (String) values.get("TABLE_NAME"); - if ((tableName != null) && (tableName.length() > 0)) - { - schema = (String)values.get("TABLE_SCHEM"); - found = true; + if ((tableName != null) && (tableName.length() > 0)) { + schema = (String) values.get("TABLE_SCHEM"); + found = true; - if (getPlatform().isDelimitedIdentifierModeOn()) - { - // Jaybird has a problem when delimited identifiers are used as + if (getPlatform().isDelimitedIdentifierModeOn()) { + // Jaybird has a problem when delimited identifiers are + // used as // it is not able to find the columns for the table // So we have to filter manually below - columnData = metaData.getColumns(getDefaultTablePattern(), getDefaultColumnPattern()); - } - else - { + columnData = metaData.getColumns(getDefaultTablePattern(), + getDefaultColumnPattern()); + } else { columnData = metaData.getColumns(tableName, getDefaultColumnPattern()); } - while (found && columnData.next()) - { + while (found && columnData.next()) { values = readColumns(columnData, getColumnsForColumn()); - if (getPlatform().isDelimitedIdentifierModeOn() && - !tableName.equals(values.get("TABLE_NAME"))) - { + if (getPlatform().isDelimitedIdentifierModeOn() + && !tableName.equals(values.get("TABLE_NAME"))) { continue; } - if (table.findColumn((String)values.get("COLUMN_NAME"), - getPlatform().isDelimitedIdentifierModeOn()) == null) - { + if (table.findColumn((String) values.get("COLUMN_NAME"), getPlatform() + .isDelimitedIdentifierModeOn()) == null) { found = false; } } @@ -461,20 +410,16 @@ public String determineSchemaOf(Connection connection, String schemaPattern, Tab } } return found ? schema : null; - } - finally - { - if (columnData != null) - { + } finally { + if (columnData != null) { columnData.close(); } - if (tableData != null) - { + if (tableData != null) { tableData.close(); } } } - + @Override protected String getTableNamePattern(String tableName) { /* diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdPlatform.java similarity index 84% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdPlatform.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdPlatform.java index 30b063dc5a..a99cc8ab14 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/FirebirdPlatform.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/FirebirdPlatform.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.firebird; +package org.jumpmind.symmetric.db.platform.firebird; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,32 +19,34 @@ * under the License. */ +import java.io.Writer; import java.sql.Types; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.DatabasePlatformInfo; +import org.jumpmind.symmetric.db.platform.SqlBuilder; /* * The platform implementation for the Firebird database. * It is assumed that the database is configured with sql dialect 3! - * - * @version $Revision: 231306 $ */ -public class FirebirdPlatform extends PlatformImplBase +public class FirebirdPlatform extends AbstractDatabasePlatform { /* Database name of this platform. */ public static final String DATABASENAME = "Firebird"; + /* The standard Firebird jdbc driver. */ public static final String JDBC_DRIVER = "org.firebirdsql.jdbc.FBDriver"; + /* The subprotocol used by the standard Firebird driver. */ public static final String JDBC_SUBPROTOCOL = "firebirdsql"; /* * Creates a new Firebird platform instance. */ - public FirebirdPlatform() - { - PlatformInfo info = getPlatformInfo(); + public FirebirdPlatform() { + + DatabasePlatformInfo info = getPlatformInfo(); info.setMaxIdentifierLength(31); info.setSystemForeignKeyIndicesAlwaysNonUnique(true); @@ -79,13 +81,13 @@ public FirebirdPlatform() info.setStoresUpperCaseInCatalog(true); - setSqlBuilder(new FirebirdBuilder(this)); - setModelReader(new FirebirdModelReader(this)); + modelReader = new FirebirdModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new FirebirdBuilder(log, this, writer); } - /* - * {@inheritDoc} - */ public String getName() { return DATABASENAME; diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/firebird/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/firebird/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/greenplum/GreenplumModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/greenplum/GreenplumModelReader.java similarity index 86% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/greenplum/GreenplumModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/greenplum/GreenplumModelReader.java index 2932c84850..d57ff671ac 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/greenplum/GreenplumModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/greenplum/GreenplumModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.greenplum; +package org.jumpmind.symmetric.db.platform.greenplum; import java.sql.Connection; import java.sql.PreparedStatement; @@ -6,15 +6,15 @@ import java.sql.SQLException; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.postgresql.PostgreSqlModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.postgresql.PostgreSqlModelReader; public class GreenplumModelReader extends PostgreSqlModelReader { - public GreenplumModelReader(Platform platform) { + public GreenplumModelReader(IDatabasePlatform platform) { super(platform); } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/greenplum/GreenplumPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/greenplum/GreenplumPlatform.java similarity index 66% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/greenplum/GreenplumPlatform.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/greenplum/GreenplumPlatform.java index 976cf6e025..65d3595140 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/greenplum/GreenplumPlatform.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/greenplum/GreenplumPlatform.java @@ -1,7 +1,6 @@ -package org.jumpmind.symmetric.db.ddl.platform.greenplum; +package org.jumpmind.symmetric.db.platform.greenplum; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.postgresql.PostgreSqlPlatform; +import org.jumpmind.symmetric.db.platform.postgresql.PostgreSqlPlatform; public class GreenplumPlatform extends PostgreSqlPlatform { @@ -14,10 +13,8 @@ public class GreenplumPlatform extends PostgreSqlPlatform { public static final String SQL_GET_GREENPLUM_VERSION = "select productversion from gp_version_at_initdb"; public GreenplumPlatform() { - super(); - PlatformInfo info = getPlatformInfo(); info.setTriggersSupported(false); - setModelReader(new GreenplumModelReader(this)); + this.modelReader = new GreenplumModelReader(this); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/h2/H2Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/h2/H2Builder.java new file mode 100644 index 0000000000..a760e0b3cd --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/h2/H2Builder.java @@ -0,0 +1,133 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.jumpmind.symmetric.db.platform.h2; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.apache.commons.lang.StringUtils; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ModelException; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.util.Log; + +/* + * The SQL Builder for the H2 database. + */ +public class H2Builder extends SqlBuilder { + + public H2Builder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + addEscapedCharSequence("'", "''"); + } + + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("ADD COLUMN "); + writeColumn(change.getChangedTable(), change.getNewColumn()); + if (change.getNextColumn() != null) { + print(" BEFORE "); + printIdentifier(getColumnName(change.getNextColumn())); + } + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a column from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP COLUMN "); + printIdentifier(getColumnName(change.getColumn())); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + @Override + protected void writeColumnDefaultValueStmt(Table table, Column column) { + Object parsedDefault = column.getParsedDefaultValue(); + + if (parsedDefault != null) { + if (!platform.getPlatformInfo().isDefaultValuesForLongTypesSupported() + && ((column.getTypeCode() == Types.LONGVARBINARY) || (column.getTypeCode() == Types.LONGVARCHAR))) { + throw new ModelException( + "The platform does not support default values for LONGVARCHAR or LONGVARBINARY columns"); + } + // we write empty default value strings only if the type is not a + // numeric or date/time type + if (isValidDefaultValue(column.getDefaultValue(), column.getTypeCode())) { + print(" DEFAULT "); + writeColumnDefaultValue(table, column); + } + } else if (platform.getPlatformInfo().isDefaultValueUsedForIdentitySpec() + && column.isAutoIncrement()) { + print(" DEFAULT "); + writeColumnDefaultValue(table, column); + } else if (!StringUtils.isBlank(column.getDefaultValue())) { + print(" DEFAULT "); + writeColumnDefaultValue(table, column); + } + } + + @Override + protected void printDefaultValue(Object defaultValue, int typeCode) { + if (defaultValue != null) { + String defaultValueStr = defaultValue.toString(); + boolean shouldUseQuotes = !TypeMap.isNumericType(typeCode) + && !defaultValueStr.startsWith("TO_DATE(") + && !defaultValue.equals("CURRENT_TIMESTAMP") + && !defaultValue.equals("CURRENT_TIME") && !defaultValue.equals("CURRENT_DATE"); + ; + + if (shouldUseQuotes) { + // characters are only escaped when within a string literal + print(platform.getPlatformInfo().getValueQuoteToken()); + print(escapeStringValue(defaultValueStr)); + print(platform.getPlatformInfo().getValueQuoteToken()); + } else { + print(defaultValueStr); + } + } + } +} \ No newline at end of file diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/h2/H2ModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/h2/H2ModelReader.java similarity index 85% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/h2/H2ModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/h2/H2ModelReader.java index 5f56a2e876..d296ec0fd7 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/h2/H2ModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/h2/H2ModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.h2; +package org.jumpmind.symmetric.db.platform.h2; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -24,15 +24,15 @@ import java.util.List; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; -import org.jumpmind.symmetric.db.ddl.platform.MetaDataColumnDescriptor; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.platform.MetaDataColumnDescriptor; /* * Reads a database model from a H2 database. From patch https://issues.apache.org/jira/browse/DDLUTILS-185 - * - * @version $Revision: 231306 $ + * The platform implementation for the H2 database. */ -public class H2Platform extends PlatformImplBase implements Platform { +public class H2Platform extends AbstractDatabasePlatform implements IDatabasePlatform { /* Database name of this platform. */ - public static final String[] DATABASENAMES = {"H2","H21"}; - + public static final String[] DATABASENAMES = { "H2", "H21" }; + /* The standard H2 driver. */ public static final String JDBC_DRIVER = "org.h2.Driver"; - + /* The sub protocol used by the H2 driver. */ public static final String JDBC_SUBPROTOCOL = "h2"; @@ -47,7 +44,6 @@ public class H2Platform extends PlatformImplBase implements Platform { * Creates a new instance of the H2 platform. */ public H2Platform() { - PlatformInfo info = getPlatformInfo(); info.setNonPKIdentityColumnsSupported(false); info.setIdentityOverrideAllowed(false); @@ -58,9 +54,8 @@ public H2Platform() { info.addNativeTypeMapping(Types.NULL, "BINARY", Types.BINARY); info.addNativeTypeMapping(Types.REF, "BINARY", Types.BINARY); info.addNativeTypeMapping(Types.STRUCT, "BINARY", Types.BINARY); - info.addNativeTypeMapping(Types.DATALINK, "BINARY", Types.BINARY); - - info.addNativeTypeMapping(Types.BIT, "BOOLEAN", Types.BIT);; + info.addNativeTypeMapping(Types.DATALINK, "BINARY", Types.BINARY); + info.addNativeTypeMapping(Types.BIT, "BOOLEAN", Types.BIT); info.addNativeTypeMapping(Types.NUMERIC, "DECIMAL", Types.DECIMAL); info.addNativeTypeMapping(Types.BINARY, "BINARY", Types.BINARY); info.addNativeTypeMapping(Types.BLOB, "BLOB", Types.BLOB); @@ -75,14 +70,14 @@ public H2Platform() { info.setDefaultSize(Types.VARBINARY, Integer.MAX_VALUE); info.setStoresUpperCaseInCatalog(true); - - setSqlBuilder(new H2Builder(this)); - setModelReader(new H2ModelReader(this)); + + modelReader = new H2ModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new H2Builder(log, this, writer); } - /* - * {@inheritDoc} - */ public String getName() { return DATABASENAMES[0]; } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbBuilder.java new file mode 100644 index 0000000000..83195c1c25 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbBuilder.java @@ -0,0 +1,153 @@ +package org.jumpmind.symmetric.db.platform.hsqldb; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.util.Log; + +/* + * The SQL Builder for the HsqlDb database. + */ +public class HsqlDbBuilder extends SqlBuilder { + + public HsqlDbBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + addEscapedCharSequence("'", "''"); + } + + @Override + public void dropTable(Table table) { + print("DROP TABLE "); + printIdentifier(getTableName(table)); + print(" IF EXISTS"); + printEndOfStatement(); + } + + @Override + public String getSelectLastIdentityValues(Table table) { + return "CALL IDENTITY()"; + } + + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + // HsqlDb can only drop columns that are not part of a primary key + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if ((change instanceof RemoveColumnChange) + && ((RemoveColumnChange) change).getColumn().isPrimaryKey()) { + return; + } + } + + // in order to utilize the ALTER TABLE ADD COLUMN BEFORE statement + // we have to apply the add column changes in the correct order + // thus we first gather all add column changes and then execute them + // Since we get them in target table column order, we can simply + // iterate backwards + ArrayList addColumnChanges = new ArrayList(); + + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddColumnChange) { + addColumnChanges.add((AddColumnChange) change); + changeIt.remove(); + } + } + + for (ListIterator changeIt = addColumnChanges + .listIterator(addColumnChanges.size()); changeIt.hasPrevious();) { + AddColumnChange addColumnChange = (AddColumnChange) changeIt.previous(); + + processChange(currentModel, desiredModel, addColumnChange); + changeIt.remove(); + } + + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof RemoveColumnChange) { + RemoveColumnChange removeColumnChange = (RemoveColumnChange) change; + + processChange(currentModel, desiredModel, removeColumnChange); + changeIt.remove(); + } + } + } + + /* + * Processes the addition of a column to a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("ADD COLUMN "); + writeColumn(change.getChangedTable(), change.getNewColumn()); + if (change.getNextColumn() != null) { + print(" BEFORE "); + printIdentifier(getColumnName(change.getNextColumn())); + } + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a column from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP COLUMN "); + printIdentifier(getColumnName(change.getColumn())); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbModelReader.java similarity index 61% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbModelReader.java index 7822da15a7..e6cd3e9ee9 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/HsqlDbModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.hsqldb; +package org.jumpmind.symmetric.db.platform.hsqldb; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -23,76 +23,73 @@ import java.sql.SQLException; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a HsqlDb database. */ -public class HsqlDbModelReader extends JdbcModelReader -{ +public class HsqlDbModelReader extends JdbcModelReader { /* * Creates a new model reader for HsqlDb databases. * * @param platform The platform that this model reader belongs to */ - public HsqlDbModelReader(Platform platform) - { + public HsqlDbModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); setDefaultSchemaPattern(null); } @Override - protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { + protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, + Map values) throws SQLException { Table table = super.readTable(connection, metaData, values); - if (table != null) - { - // For at least version 1.7.2 we have to determine the auto-increment columns - // from a result set meta data because the database does not put this info - // into the database metadata - // Since Hsqldb only allows IDENTITY for primary key columns, we restrict - // our search to those columns - determineAutoIncrementFromResultSetMetaData(connection, table, table.getPrimaryKeyColumns()); + if (table != null) { + // For at least version 1.7.2 we have to determine the + // auto-increment columns from a result set meta data because the + // database does not put this info into the database metadata + // Since Hsqldb only allows IDENTITY for primary key columns, we + // restrict our search to those columns + determineAutoIncrementFromResultSetMetaData(connection, table, + table.getPrimaryKeyColumns()); } - + return table; } @Override - protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { + protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) + throws SQLException { Column column = super.readColumn(metaData, values); - if (TypeMap.isTextType(column.getTypeCode()) && - (column.getDefaultValue() != null)) - { + if (TypeMap.isTextType(column.getTypeCode()) && (column.getDefaultValue() != null)) { column.setDefaultValue(unescape(column.getDefaultValue(), "'", "''")); } return column; } @Override - protected boolean isInternalForeignKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) - { + protected boolean isInternalForeignKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) { String name = index.getName(); return (name != null) && name.startsWith("SYS_IDX_"); } @Override - protected boolean isInternalPrimaryKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, Index index) - { + protected boolean isInternalPrimaryKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, Index index) { String name = index.getName(); return (name != null) && (name.startsWith("SYS_PK_") || name.startsWith("SYS_IDX_")); } + } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbPlatform.java new file mode 100644 index 0000000000..49bbd0bf7c --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/HsqlDbPlatform.java @@ -0,0 +1,88 @@ +package org.jumpmind.symmetric.db.platform.hsqldb; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for the HsqlDb database. + * + * @version $Revision: 231306 $ + */ +public class HsqlDbPlatform extends AbstractDatabasePlatform { + /* Database name of this platform. */ + public static final String DATABASENAME = "HsqlDb"; + + /* The standard Hsqldb jdbc driver. */ + public static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; + + /* The subprotocol used by the standard Hsqldb driver. */ + public static final String JDBC_SUBPROTOCOL = "hsqldb"; + + /* + * Creates a new instance of the Hsqldb platform. + */ + public HsqlDbPlatform() { + + + info.setNonPKIdentityColumnsSupported(false); + info.setIdentityOverrideAllowed(false); + info.setSystemForeignKeyIndicesAlwaysNonUnique(true); + + info.addNativeTypeMapping(Types.ARRAY, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.BLOB, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.CLOB, "LONGVARCHAR", Types.LONGVARCHAR); + info.addNativeTypeMapping(Types.DISTINCT, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "OBJECT"); + info.addNativeTypeMapping(Types.NULL, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.REF, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "LONGVARBINARY", Types.LONGVARBINARY); + // JDBC's TINYINT requires a value range of -255 to 255, but HsqlDb's is + // only -128 to 127 + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + + info.addNativeTypeMapping("BIT", "BOOLEAN", "BOOLEAN"); + info.addNativeTypeMapping("DATALINK", "LONGVARBINARY", "LONGVARBINARY"); + + info.setDefaultSize(Types.CHAR, Integer.MAX_VALUE); + info.setDefaultSize(Types.VARCHAR, Integer.MAX_VALUE); + info.setDefaultSize(Types.BINARY, Integer.MAX_VALUE); + info.setDefaultSize(Types.VARBINARY, Integer.MAX_VALUE); + + info.setStoresUpperCaseInCatalog(true); + + modelReader = new HsqlDbModelReader(this); + + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new HsqlDbBuilder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2Builder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2Builder.java similarity index 56% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2Builder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2Builder.java index 6ecce8fc42..fc90173ea1 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2Builder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2Builder.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.hsqldb2; +package org.jumpmind.symmetric.db.platform.hsqldb2; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,45 +19,38 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.sql.Types; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDataTypeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnSizeChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; + +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.ColumnDataTypeChange; +import org.jumpmind.symmetric.db.alter.ColumnSizeChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.util.Log; /* * The SQL Builder for the HsqlDb database. */ -public class HsqlDb2Builder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public HsqlDb2Builder(Platform platform) - { - super(platform); +public class HsqlDb2Builder extends SqlBuilder { + + public HsqlDb2Builder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); addEscapedCharSequence("'", "''"); } @Override - public void dropTable(Table table) throws IOException - { + public void dropTable(Table table) { print("DROP TABLE "); printIdentifier(getTableName(table)); print(" IF EXISTS"); @@ -65,13 +58,11 @@ public void dropTable(Table table) throws IOException } @Override - public String getSelectLastIdentityValues(Table table) - { + public String getSelectLastIdentityValues(Table table) { return "CALL IDENTITY()"; } - - protected boolean shouldGeneratePrimaryKeys(Column[] primaryKeyColumns) - { + + protected boolean shouldGeneratePrimaryKeys(Column[] primaryKeyColumns) { if (primaryKeyColumns != null && primaryKeyColumns.length == 1) { return !primaryKeyColumns[0].isAutoIncrement(); } else { @@ -80,29 +71,22 @@ protected boolean shouldGeneratePrimaryKeys(Column[] primaryKeyColumns) } @Override - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { - - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); // HsqlDb can only drop columns that are not part of a primary key - if ((change instanceof RemoveColumnChange) && - ((RemoveColumnChange)change).getColumn().isPrimaryKey()) - { + if ((change instanceof RemoveColumnChange) + && ((RemoveColumnChange) change).getColumn().isPrimaryKey()) { changeIt.remove(); } - + // LONGVARCHAR columns always report changes if (change instanceof ColumnSizeChange) { ColumnSizeChange sizeChange = (ColumnSizeChange) change; - if (sizeChange.getChangedColumn().getTypeCode() == Types.VARCHAR && sizeChange.getNewSize() == 0) { + if (sizeChange.getChangedColumn().getTypeCode() == Types.VARCHAR + && sizeChange.getNewSize() == 0) { changeIt.remove(); } } @@ -122,33 +106,30 @@ protected void processTableStructureChanges(Database currentModel, // thus we first gather all add column changes and then execute them // Since we get them in target table column order, we can simply // iterate backwards - ArrayList addColumnChanges = new ArrayList(); + ArrayList addColumnChanges = new ArrayList(); - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - if (change instanceof AddColumnChange) - { - addColumnChanges.add(change); + if (change instanceof AddColumnChange) { + addColumnChanges.add((AddColumnChange) change); changeIt.remove(); } } - for (ListIterator changeIt = addColumnChanges.listIterator(addColumnChanges.size()); changeIt.hasPrevious();) - { - AddColumnChange addColumnChange = (AddColumnChange)changeIt.previous(); + + for (ListIterator changeIt = addColumnChanges + .listIterator(addColumnChanges.size()); changeIt.hasPrevious();) { + AddColumnChange addColumnChange = changeIt.previous(); processChange(currentModel, desiredModel, addColumnChange); changeIt.remove(); } - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - if (change instanceof RemoveColumnChange) - { - RemoveColumnChange removeColumnChange = (RemoveColumnChange)change; + if (change instanceof RemoveColumnChange) { + RemoveColumnChange removeColumnChange = (RemoveColumnChange) change; processChange(currentModel, desiredModel, removeColumnChange); changeIt.remove(); @@ -160,53 +141,51 @@ protected void processTableStructureChanges(Database currentModel, * Processes the addition of a column to a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("ADD COLUMN "); writeColumn(change.getChangedTable(), change.getNewColumn()); - if (change.getNextColumn() != null) - { + if (change.getNextColumn() != null) { print(" BEFORE "); printIdentifier(getColumnName(change.getNextColumn())); } printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a column from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("DROP COLUMN "); printIdentifier(getColumnName(change.getColumn())); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } - + @Override - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { + public void writeExternalIndexDropStmt(Table table, Index index) { print("DROP INDEX "); printIdentifier(getIndexName(index)); printEndOfStatement(); } - + } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2ModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2ModelReader.java similarity index 79% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2ModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2ModelReader.java index 2b9863e3da..6f071ed832 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/hsqldb2/HsqlDb2ModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2ModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.hsqldb2; +package org.jumpmind.symmetric.db.platform.hsqldb2; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -23,14 +23,14 @@ import java.sql.SQLException; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a HsqlDb database. @@ -42,7 +42,7 @@ public class HsqlDb2ModelReader extends JdbcModelReader * * @param platform The platform that this model reader belongs to */ - public HsqlDb2ModelReader(Platform platform) + public HsqlDb2ModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2Platform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2Platform.java new file mode 100644 index 0000000000..5d0a719736 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/hsqldb2/HsqlDb2Platform.java @@ -0,0 +1,84 @@ +package org.jumpmind.symmetric.db.platform.hsqldb2; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for the HsqlDb database. + */ +public class HsqlDb2Platform extends AbstractDatabasePlatform { + /* Database name of this platform. */ + public static final String DATABASENAME = "HSQL Database Engine2"; + + /* The standard Hsqldb jdbc driver. */ + public static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; + + /* The subprotocol used by the standard Hsqldb driver. */ + public static final String JDBC_SUBPROTOCOL = "hsqldb"; + + /* + * Creates a new instance of the Hsqldb platform. + */ + public HsqlDb2Platform() { + + info.setNonPKIdentityColumnsSupported(false); + info.setIdentityOverrideAllowed(false); + info.setSystemForeignKeyIndicesAlwaysNonUnique(true); + + info.addNativeTypeMapping(Types.ARRAY, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.BLOB, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.CLOB, "LONGVARCHAR", Types.LONGVARCHAR); + info.addNativeTypeMapping(Types.DISTINCT, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "OBJECT"); + info.addNativeTypeMapping(Types.NULL, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.REF, "LONGVARBINARY", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "LONGVARBINARY", Types.LONGVARBINARY); + // JDBC's TINYINT requires a value range of -255 to 255, but HsqlDb's is + // only -128 to 127 + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + + info.addNativeTypeMapping("BIT", "BOOLEAN", "BOOLEAN"); + info.addNativeTypeMapping("DATALINK", "LONGVARBINARY", "LONGVARBINARY"); + + info.setDefaultSize(Types.CHAR, Integer.MAX_VALUE); + info.setDefaultSize(Types.VARCHAR, Integer.MAX_VALUE); + info.setDefaultSize(Types.BINARY, Integer.MAX_VALUE); + info.setDefaultSize(Types.VARBINARY, Integer.MAX_VALUE); + + info.setStoresUpperCaseInCatalog(true); + + modelReader = new HsqlDb2ModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new HsqlDb2Builder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixBuilder.java similarity index 67% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixBuilder.java index ab4387e9f5..b2db7b7048 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixBuilder.java @@ -1,24 +1,25 @@ -package org.jumpmind.symmetric.db.ddl.platform.informix; +package org.jumpmind.symmetric.db.platform.informix; -import java.io.IOException; +import java.io.Writer; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.PrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.util.Log; public class InformixBuilder extends SqlBuilder { - public InformixBuilder(Platform platform) { - super(platform); + public InformixBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); } @Override - protected void writeColumn(Table table, Column column) throws IOException { + protected void writeColumn(Table table, Column column) { if (column.isAutoIncrement()) { printIdentifier(getColumnName(column)); print(" SERIAL"); @@ -34,7 +35,7 @@ public String getSelectLastIdentityValues(Table table) { @Override protected void writeExternalPrimaryKeysCreateStmt(Table table, Column primaryKeyColumns[]) - throws IOException { + { if (primaryKeyColumns.length > 0 && shouldGeneratePrimaryKeys(primaryKeyColumns)) { print("ALTER TABLE "); printlnIdentifier(getTableName(table)); @@ -48,9 +49,9 @@ protected void writeExternalPrimaryKeysCreateStmt(Table table, Column primaryKey } protected void writeExternalForeignKeyCreateStmt(Database database, Table table, ForeignKey key) - throws IOException { + { if (key.getForeignTableName() == null) { - _log.warn("Foreign key table is null for key " + key); + log.warn("Foreign key table is null for key " + key); } else { writeTableAlterStmt(table); print("ADD CONSTRAINT FOREIGN KEY ("); @@ -66,18 +67,18 @@ protected void writeExternalForeignKeyCreateStmt(Database database, Table table, } protected void processChange(Database currentModel, Database desiredModel, - RemovePrimaryKeyChange change) throws IOException { + RemovePrimaryKeyChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("DROP CONSTRAINT "); printIdentifier(getConstraintName(null, change.getChangedTable(), "PK", null)); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } protected void processChange(Database currentModel, Database desiredModel, - PrimaryKeyChange change) throws IOException { + PrimaryKeyChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); @@ -86,6 +87,6 @@ protected void processChange(Database currentModel, Database desiredModel, printEndOfStatement(); writeExternalPrimaryKeysCreateStmt(change.getChangedTable(), change.getNewPrimaryKeyColumns()); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixModelReader.java similarity index 83% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixModelReader.java index a265618798..33facb5c6e 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.informix; +package org.jumpmind.symmetric.db.platform.informix; import java.sql.Connection; import java.sql.PreparedStatement; @@ -8,17 +8,17 @@ import java.util.Map; import org.apache.commons.collections.map.ListOrderedMap; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; public class InformixModelReader extends JdbcModelReader { - public InformixModelReader(Platform platform) { + public InformixModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); setDefaultSchemaPattern(null); @@ -40,7 +40,7 @@ protected void determineAutoIncrementFromResultSetMetaData(Connection connection } @Override - public Collection readIndices(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) + public Collection readIndices(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException { String sql = "select rtrim(dbinfo('dbname')) as TABLE_CAT, st.owner as TABLE_SCHEM, st.tabname as TABLE_NAME, " + "case when idxtype = 'U' then 0 else 1 end NON_UNIQUE, si.owner as INDEX_QUALIFIER, si.idxname as INDEX_NAME, " diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixPlatform.java similarity index 70% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixPlatform.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixPlatform.java index eb3ed89e12..2033d57458 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/informix/InformixPlatform.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/informix/InformixPlatform.java @@ -1,21 +1,21 @@ -package org.jumpmind.symmetric.db.ddl.platform.informix; +package org.jumpmind.symmetric.db.platform.informix; +import java.io.Writer; import java.sql.Types; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; -public class InformixPlatform extends PlatformImplBase implements Platform { +public class InformixPlatform extends AbstractDatabasePlatform implements IDatabasePlatform { public static final String DATABASENAME = "Informix Dynamic Server11"; - + public static final String JDBC_DRIVER = "com.informix.jdbc.IfxDriver"; - + public static final String JDBC_SUBPROTOCOL = "informix-sqli"; public InformixPlatform() { - PlatformInfo info = getPlatformInfo(); info.addNativeTypeMapping(Types.VARCHAR, "VARCHAR", Types.VARCHAR); info.addNativeTypeMapping(Types.LONGVARCHAR, "LVARCHAR", Types.LONGVARCHAR); @@ -28,15 +28,18 @@ public InformixPlatform() { info.addNativeTypeMapping(Types.BIT, "BOOLEAN", Types.BOOLEAN); info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); info.addNativeTypeMapping(Types.DOUBLE, "FLOAT", Types.DOUBLE); - + info.setDefaultSize(Types.VARCHAR, 255); info.setDefaultSize(Types.CHAR, 255); - + info.setAlterTableForDropUsed(true); info.setSystemIndicesReturned(true); - - setSqlBuilder(new InformixBuilder(this)); - setModelReader(new InformixModelReader(this)); + + modelReader = new InformixModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new InformixBuilder(log, this, writer); } public String getName() { diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbaseBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbaseBuilder.java similarity index 58% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbaseBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbaseBuilder.java index 66c5941ce5..5d7c052336 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbaseBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbaseBuilder.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.interbase; +package org.jumpmind.symmetric.db.platform.interbase; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,94 +19,71 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.sql.Types; import java.util.Iterator; import java.util.List; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; + +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; +import org.jumpmind.symmetric.util.Log; /* * The SQL Builder for the Interbase database. - * - * @version $Revision: 231306 $ */ -public class InterbaseBuilder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public InterbaseBuilder(Platform platform) - { - super(platform); +public class InterbaseBuilder extends SqlBuilder { + + public InterbaseBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); addEscapedCharSequence("'", "''"); } - /* - * {@inheritDoc} - */ - public void createTable(Database database, Table table, Map parameters) throws IOException - { - super.createTable(database, table, parameters); + @Override + public void createTable(Database database, Table table) { + super.createTable(database, table); // creating generator and trigger for auto-increment Column[] columns = table.getAutoIncrementColumns(); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { writeAutoIncrementCreateStmts(database, table, columns[idx]); } } - /* - * {@inheritDoc} - */ - protected String getNativeDefaultValue(Column column) - { - if ((column.getTypeCode() == Types.BIT) || - (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode()))) - { - return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString(); - } - else - { + @Override + protected String getNativeDefaultValue(Column column) { + if ((column.getTypeCode() == Types.BIT) + || (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils + .determineBooleanTypeCode()))) { + return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), + Types.SMALLINT).toString(); + } else { return super.getNativeDefaultValue(column); } } - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { + @Override + public void dropTable(Table table) { // dropping generators for auto-increment Column[] columns = table.getAutoIncrementColumns(); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { writeAutoIncrementDropStmts(table, columns[idx]); } super.dropTable(table); } - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { // Index names in Interbase are unique to a schema and hence we do not // need the ON clause print("DROP INDEX "); @@ -115,14 +92,17 @@ public void writeExternalIndexDropStmt(Table table, Index index) throws IOExcept } /* - * Writes the creation statements to make the given column an auto-increment column. + * Writes the creation statements to make the given column an auto-increment + * column. * * @param database The database model - * @param table The table - * @param column The column to make auto-increment + * + * @param table The table + * + * @param column The column to make auto-increment */ - private void writeAutoIncrementCreateStmts(Database database, Table table, Column column) throws IOException - { + private void writeAutoIncrementCreateStmts(Database database, Table table, Column column) + { print("CREATE GENERATOR "); printIdentifier(getGeneratorName(table, column)); printEndOfStatement(); @@ -143,13 +123,14 @@ private void writeAutoIncrementCreateStmts(Database database, Table table, Colum } /* - * Writes the statements to drop the auto-increment status for the given column. + * Writes the statements to drop the auto-increment status for the given + * column. + * + * @param table The table * - * @param table The table * @param column The column to remove the auto-increment status for */ - private void writeAutoIncrementDropStmts(Table table, Column column) throws IOException - { + private void writeAutoIncrementDropStmts(Table table, Column column) { print("DROP TRIGGER "); printIdentifier(getTriggerName(table, column)); printEndOfStatement(); @@ -162,12 +143,13 @@ private void writeAutoIncrementDropStmts(Table table, Column column) throws IOEx /* * Determines the name of the trigger for an auto-increment column. * - * @param table The table + * @param table The table + * * @param column The auto-increment column + * * @return The trigger name */ - protected String getTriggerName(Table table, Column column) - { + protected String getTriggerName(Table table, Column column) { String secondPart = column.getName(); // make sure a backup table gets a different name than the original if (table.getName().endsWith("_")) { @@ -179,12 +161,13 @@ protected String getTriggerName(Table table, Column column) /* * Determines the name of the generator for an auto-increment column. * - * @param table The table + * @param table The table + * * @param column The auto-increment column + * * @return The generator name */ - protected String getGeneratorName(Table table, Column column) - { + protected String getGeneratorName(Table table, Column column) { String secondPart = column.getName(); // make sure a backup table gets a different name than the original if (table.getName().endsWith("_")) { @@ -193,32 +176,22 @@ protected String getGeneratorName(Table table, Column column) return getConstraintName("gen", table, secondPart, null); } - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { // we're using a generator } - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { + @Override + public String getSelectLastIdentityValues(Table table) { Column[] columns = table.getAutoIncrementColumns(); - if (columns.length == 0) - { + if (columns.length == 0) { return null; - } - else - { + } else { StringBuffer result = new StringBuffer(); - + result.append("SELECT "); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { result.append("GEN_ID("); result.append(getDelimitedIdentifier(getGeneratorName(table, columns[idx]))); result.append(", 0)"); @@ -228,21 +201,16 @@ public String getSelectLastIdentityValues(Table table) } } - public String fixLastIdentityValues(Table table) - { + public String fixLastIdentityValues(Table table) { Column[] columns = table.getAutoIncrementColumns(); - if (columns.length == 0) - { + if (columns.length == 0) { return null; - } - else - { + } else { StringBuffer result = new StringBuffer(); - + result.append("SELECT "); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { result.append("GEN_ID("); result.append(getDelimitedIdentifier(getGeneratorName(table, columns[idx]))); result.append(", (SELECT MAX(").append(columns[idx].getName()).append(")+1 FROM "); @@ -253,61 +221,53 @@ public String fixLastIdentityValues(Table table) } } - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, Database desiredModel, Table sourceTable, Table targetTable, Map parameters, List changes) throws IOException - { - // TODO: Dropping of primary keys is currently not supported because we cannot - // determine the pk constraint names and drop them in one go - // (We could used a stored procedure if Interbase would allow them to use DDL) - // This will be easier once named primary keys are supported + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + // TODO: Dropping of primary keys is currently not supported because we + // cannot + // determine the pk constraint names and drop them in one go + // (We could used a stored procedure if Interbase would allow them to + // use DDL) + // This will be easier once named primary keys are supported boolean pkColumnAdded = false; - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; // TODO: we cannot add columns to the primary key this way - // because we would have to drop the pk first and then - // add a new one afterwards which is not supported yet - if (addColumnChange.getNewColumn().isPrimaryKey()) - { - pkColumnAdded = true; - } - else - { + // because we would have to drop the pk first and then + // add a new one afterwards which is not supported yet + if (addColumnChange.getNewColumn().isPrimaryKey()) { + pkColumnAdded = true; + } else { processChange(currentModel, desiredModel, addColumnChange); changeIt.remove(); } - } - else if (change instanceof RemoveColumnChange) - { - RemoveColumnChange removeColumnChange = (RemoveColumnChange)change; + } else if (change instanceof RemoveColumnChange) { + RemoveColumnChange removeColumnChange = (RemoveColumnChange) change; // TODO: we cannot drop primary key columns this way - // because we would have to drop the pk first and then - // add a new one afterwards which is not supported yet - if (!removeColumnChange.getColumn().isPrimaryKey()) - { + // because we would have to drop the pk first and then + // add a new one afterwards which is not supported yet + if (!removeColumnChange.getColumn().isPrimaryKey()) { processChange(currentModel, desiredModel, removeColumnChange); changeIt.remove(); } } } - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); - // we can only add a primary key if all columns are present in the table + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + // we can only add a primary key if all columns are present in the + // table // i.e. none was added during this alteration - if ((change instanceof AddPrimaryKeyChange) && !pkColumnAdded) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); + if ((change instanceof AddPrimaryKeyChange) && !pkColumnAdded) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); changeIt.remove(); } } @@ -317,13 +277,13 @@ else if (change instanceof RemoveColumnChange) * Processes the addition of a column to a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); @@ -331,18 +291,20 @@ protected void processChange(Database currentModel, writeColumn(change.getChangedTable(), change.getNewColumn()); printEndOfStatement(); - Table curTable = currentModel.findTable(change.getChangedTable().getName(), getPlatform().isDelimitedIdentifierModeOn()); + Table curTable = currentModel.findTable(change.getChangedTable().getName(), + platform.isDelimitedIdentifierModeOn()); - if (!change.isAtEnd()) - { + if (!change.isAtEnd()) { Column prevColumn = change.getPreviousColumn(); - if (prevColumn != null) - { - // we need the corresponding column object from the current table - prevColumn = curTable.findColumn(prevColumn.getName(), getPlatform().isDelimitedIdentifierModeOn()); + if (prevColumn != null) { + // we need the corresponding column object from the current + // table + prevColumn = curTable.findColumn(prevColumn.getName(), + platform.isDelimitedIdentifierModeOn()); } - // Even though Interbase can only add columns, we can move them later on + // Even though Interbase can only add columns, we can move them + // later on print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); @@ -350,29 +312,28 @@ protected void processChange(Database currentModel, printIdentifier(getColumnName(change.getNewColumn())); print(" POSITION "); // column positions start at 1 in Interbase - print(prevColumn == null ? "1" : String.valueOf(curTable.getColumnIndex(prevColumn) + 1)); + print(prevColumn == null ? "1" : String + .valueOf(curTable.getColumnIndex(prevColumn) + 1)); printEndOfStatement(); } - if (change.getNewColumn().isAutoIncrement()) - { + if (change.getNewColumn().isAutoIncrement()) { writeAutoIncrementCreateStmts(currentModel, curTable, change.getNewColumn()); } - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a column from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { - if (change.getColumn().isAutoIncrement()) - { + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { + if (change.getColumn().isAutoIncrement()) { writeAutoIncrementDropStmts(change.getChangedTable(), change.getColumn()); } print("ALTER TABLE "); @@ -381,6 +342,6 @@ protected void processChange(Database currentModel, print("DROP "); printIdentifier(getColumnName(change.getColumn())); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbaseModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbaseModelReader.java similarity index 58% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbaseModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbaseModelReader.java index 4695c1fe0e..8aedb1f074 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/InterbaseModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbaseModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.interbase; +package org.jumpmind.symmetric.db.platform.interbase; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -32,29 +32,25 @@ import java.util.Map; import org.apache.commons.collections.map.ListOrderedMap; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * The Jdbc Model Reader for Interbase. - * - * @version $Revision: $ */ -public class InterbaseModelReader extends JdbcModelReader -{ +public class InterbaseModelReader extends JdbcModelReader { /* * Creates a new model reader for Interbase databases. * * @param platform The platform that this model reader belongs to */ - public InterbaseModelReader(Platform platform) - { + public InterbaseModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); setDefaultSchemaPattern(null); @@ -63,12 +59,11 @@ public InterbaseModelReader(Platform platform) } @Override - protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { + protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, + Map values) throws SQLException { Table table = super.readTable(connection, metaData, values); - if (table != null) - { + if (table != null) { determineExtraColumnInfo(connection, table); determineAutoIncrementColumns(connection, table); adjustColumns(table); @@ -76,7 +71,7 @@ protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaDat return table; } - + protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException { Column column = super.readColumn(metaData, values); @@ -90,142 +85,127 @@ protected Column readColumn(DatabaseMetaDataWrapper metaData, Map readColumns(DatabaseMetaDataWrapper metaData, String tableName) + throws SQLException { ResultSet columnData = null; - try - { - List columns = new ArrayList(); + try { + List columns = new ArrayList(); - if (getPlatform().isDelimitedIdentifierModeOn()) - { + if (getPlatform().isDelimitedIdentifierModeOn()) { // Jaybird has a problem when delimited identifiers are used as // it is not able to find the columns for the table // So we have to filter manually below - columnData = metaData.getColumns(getDefaultTablePattern(), getDefaultColumnPattern()); + columnData = metaData.getColumns(getDefaultTablePattern(), + getDefaultColumnPattern()); - while (columnData.next()) - { - Map values = readColumns(columnData, getColumnsForColumn()); + while (columnData.next()) { + Map values = readColumns(columnData, getColumnsForColumn()); - if (tableName.equals(values.get("TABLE_NAME"))) - { + if (tableName.equals(values.get("TABLE_NAME"))) { columns.add(readColumn(metaData, values)); } } - } - else - { + } else { columnData = metaData.getColumns(tableName, getDefaultColumnPattern()); - while (columnData.next()) - { - Map values = readColumns(columnData, getColumnsForColumn()); + while (columnData.next()) { + Map values = readColumns(columnData, getColumnsForColumn()); columns.add(readColumn(metaData, values)); } } return columns; - } - finally - { - if (columnData != null) - { + } finally { + if (columnData != null) { columnData.close(); } } } /* - * Helper method that determines extra column info from the system tables: default value, precision, scale. - * + * Helper method that determines extra column info from the system tables: + * default value, precision, scale. + * * @param table The table */ - protected void determineExtraColumnInfo(Connection connection, Table table) throws SQLException - { - StringBuffer query = new StringBuffer(); - + protected void determineExtraColumnInfo(Connection connection, Table table) throws SQLException { + StringBuffer query = new StringBuffer(); + query.append("SELECT a.RDB$FIELD_NAME, a.RDB$DEFAULT_SOURCE, b.RDB$FIELD_PRECISION, b.RDB$FIELD_SCALE,"); query.append(" b.RDB$FIELD_TYPE, b.RDB$FIELD_SUB_TYPE FROM RDB$RELATION_FIELDS a, RDB$FIELDS b"); query.append(" WHERE a.RDB$RELATION_NAME=? AND a.RDB$FIELD_SOURCE=b.RDB$FIELD_NAME"); PreparedStatement prepStmt = connection.prepareStatement(query.toString()); - try - { - prepStmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? table.getName() : table.getName().toUpperCase()); + try { + prepStmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? table.getName() + : table.getName().toUpperCase()); ResultSet rs = prepStmt.executeQuery(); - while (rs.next()) - { + while (rs.next()) { String columnName = rs.getString(1).trim(); - Column column = table.findColumn(columnName, getPlatform().isDelimitedIdentifierModeOn()); + Column column = table.findColumn(columnName, getPlatform() + .isDelimitedIdentifierModeOn()); - if (column != null) - { + if (column != null) { String defaultValue = rs.getString(2); - if (!rs.wasNull() && (defaultValue != null)) - { + if (!rs.wasNull() && (defaultValue != null)) { defaultValue = defaultValue.trim(); - if (defaultValue.startsWith("DEFAULT ")) - { + if (defaultValue.startsWith("DEFAULT ")) { defaultValue = defaultValue.substring("DEFAULT ".length()); } column.setDefaultValue(defaultValue); } - - short precision = rs.getShort(3); + + short precision = rs.getShort(3); boolean precisionSpecified = !rs.wasNull(); - short scale = rs.getShort(4); - boolean scaleSpecified = !rs.wasNull(); + short scale = rs.getShort(4); + boolean scaleSpecified = !rs.wasNull(); - if (precisionSpecified) - { + if (precisionSpecified) { // for some reason, Interbase stores the negative scale column.setSizeAndScale(precision, scaleSpecified ? -scale : 0); } - short dbType = rs.getShort(5); + short dbType = rs.getShort(5); short blobSubType = rs.getShort(6); // CLOBs are returned by the driver as VARCHAR - if (!rs.wasNull() && (dbType == 261) && (blobSubType == 1)) - { + if (!rs.wasNull() && (dbType == 261) && (blobSubType == 1)) { column.setTypeCode(Types.CLOB); } } } rs.close(); - } - finally - { + } finally { prepStmt.close(); } } /* - * Helper method that determines the auto increment status using Interbase's system tables. - * + * Helper method that determines the auto increment status using Interbase's + * system tables. + * * @param table The table */ - protected void determineAutoIncrementColumns(Connection connection, Table table) throws SQLException - { - // Since for long table and column names, the generator name will be shortened - // we have to determine for each column whether there is a generator for it - InterbaseBuilder builder = (InterbaseBuilder)getPlatform().getSqlBuilder(); - Column[] columns = table.getColumns(); - HashMap names = new HashMap(); - String name; - - for (int idx = 0; idx < columns.length; idx++) - { + protected void determineAutoIncrementColumns(Connection connection, Table table) + throws SQLException { + // Since for long table and column names, the generator name will be + // shortened + // we have to determine for each column whether there is a generator for + // it + InterbaseBuilder builder = (InterbaseBuilder) getPlatform().createSqlBuilder(null); + Column[] columns = table.getColumns(); + HashMap names = new HashMap(); + String name; + + for (int idx = 0; idx < columns.length; idx++) { name = builder.getGeneratorName(table, columns[idx]); - if (!getPlatform().isDelimitedIdentifierModeOn()) - { + if (!getPlatform().isDelimitedIdentifierModeOn()) { name = name.toUpperCase(); } names.put(name, columns[idx]); @@ -233,24 +213,19 @@ protected void determineAutoIncrementColumns(Connection connection, Table table) Statement stmt = connection.createStatement(); - try - { + try { ResultSet rs = stmt.executeQuery("SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS"); - while (rs.next()) - { + while (rs.next()) { String generatorName = rs.getString(1).trim(); - Column column = (Column)names.get(generatorName); + Column column = (Column) names.get(generatorName); - if (column != null) - { + if (column != null) { column.setAutoIncrement(true); } } rs.close(); - } - finally - { + } finally { stmt.close(); } } @@ -260,69 +235,53 @@ protected void determineAutoIncrementColumns(Connection connection, Table table) * * @param table The table */ - protected void adjustColumns(Table table) - { + protected void adjustColumns(Table table) { Column[] columns = table.getColumns(); - for (int idx = 0; idx < columns.length; idx++) - { - if (columns[idx].getTypeCode() == Types.FLOAT) - { + for (int idx = 0; idx < columns.length; idx++) { + if (columns[idx].getTypeCode() == Types.FLOAT) { columns[idx].setTypeCode(Types.REAL); - } - else if ((columns[idx].getTypeCode() == Types.NUMERIC) || (columns[idx].getTypeCode() == Types.DECIMAL)) - { - if ((columns[idx].getTypeCode() == Types.NUMERIC) && (columns[idx].getSizeAsInt() == 18) && (columns[idx].getScale() == 0)) - { + } else if ((columns[idx].getTypeCode() == Types.NUMERIC) + || (columns[idx].getTypeCode() == Types.DECIMAL)) { + if ((columns[idx].getTypeCode() == Types.NUMERIC) + && (columns[idx].getSizeAsInt() == 18) && (columns[idx].getScale() == 0)) { columns[idx].setTypeCode(Types.BIGINT); } - } - else if (TypeMap.isTextType(columns[idx].getTypeCode())) - { + } else if (TypeMap.isTextType(columns[idx].getTypeCode())) { columns[idx].setDefaultValue(unescape(columns[idx].getDefaultValue(), "'", "''")); } } } @Override - protected Collection readPrimaryKeyNames(DatabaseMetaDataWrapper metaData, String tableName) throws SQLException - { - List pks = new ArrayList(); + protected Collection readPrimaryKeyNames(DatabaseMetaDataWrapper metaData, String tableName) + throws SQLException { + List pks = new ArrayList(); ResultSet pkData = null; - try - { - if (getPlatform().isDelimitedIdentifierModeOn()) - { + try { + if (getPlatform().isDelimitedIdentifierModeOn()) { // Jaybird has a problem when delimited identifiers are used as // it is not able to find the primary key info for the table // So we have to filter manually below pkData = metaData.getPrimaryKeys(getDefaultTablePattern()); - while (pkData.next()) - { - Map values = readColumns(pkData, getColumnsForPK()); - - if (tableName.equals(values.get("TABLE_NAME"))) - { + while (pkData.next()) { + Map values = readColumns(pkData, getColumnsForPK()); + + if (tableName.equals(values.get("TABLE_NAME"))) { pks.add(readPrimaryKeyName(metaData, values)); } } - } - else - { + } else { pkData = metaData.getPrimaryKeys(tableName); - while (pkData.next()) - { - Map values = readColumns(pkData, getColumnsForPK()); - + while (pkData.next()) { + Map values = readColumns(pkData, getColumnsForPK()); + pks.add(readPrimaryKeyName(metaData, values)); } } - } - finally - { - if (pkData != null) - { + } finally { + if (pkData != null) { pkData.close(); } } @@ -330,94 +289,87 @@ protected Collection readPrimaryKeyNames(DatabaseMetaDataWrapper metaData, Strin } @Override - protected Collection readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException - { - Map fks = new ListOrderedMap(); + protected Collection readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, + String tableName) throws SQLException { + Map fks = new ListOrderedMap(); ResultSet fkData = null; - try - { - if (getPlatform().isDelimitedIdentifierModeOn()) - { + try { + if (getPlatform().isDelimitedIdentifierModeOn()) { // Jaybird has a problem when delimited identifiers are used as // it is not able to find the foreign key info for the table // So we have to filter manually below fkData = metaData.getForeignKeys(getDefaultTablePattern()); - while (fkData.next()) - { + while (fkData.next()) { Map values = readColumns(fkData, getColumnsForFK()); - - if (tableName.equals(values.get("FKTABLE_NAME"))) - { + + if (tableName.equals(values.get("FKTABLE_NAME"))) { readForeignKey(metaData, values, fks); } } - } - else - { + } else { fkData = metaData.getForeignKeys(tableName); - while (fkData.next()) - { + while (fkData.next()) { Map values = readColumns(fkData, getColumnsForFK()); - + readForeignKey(metaData, values, fks); } } - } - finally - { - if (fkData != null) - { + } finally { + if (fkData != null) { fkData.close(); } } return fks.values(); } - protected boolean isInternalPrimaryKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, Index index) throws SQLException - { - String tableName = getPlatform().getSqlBuilder().getTableName(table); - String indexName = getPlatform().getSqlBuilder().getIndexName(index); - StringBuffer query = new StringBuffer(); + protected boolean isInternalPrimaryKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, Index index) throws SQLException { + InterbaseBuilder builder = (InterbaseBuilder)getPlatform().createSqlBuilder(null); + String tableName = builder.getTableName(table); + String indexName = builder.getIndexName(index); + StringBuffer query = new StringBuffer(); query.append("SELECT RDB$CONSTRAINT_NAME FROM RDB$RELATION_CONSTRAINTS where RDB$RELATION_NAME=? AND RDB$CONSTRAINT_TYPE=? AND RDB$INDEX_NAME=?"); PreparedStatement stmt = connection.prepareStatement(query.toString()); - try - { - stmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName.toUpperCase()); + try { + stmt.setString( + 1, + getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName + .toUpperCase()); stmt.setString(2, "PRIMARY KEY"); stmt.setString(3, indexName); ResultSet resultSet = stmt.executeQuery(); return resultSet.next(); - } - finally - { - if (stmt != null) - { + } finally { + if (stmt != null) { stmt.close(); } } } - - protected boolean isInternalForeignKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) throws SQLException - { - String tableName = getPlatform().getSqlBuilder().getTableName(table); - String indexName = getPlatform().getSqlBuilder().getIndexName(index); - String fkName = getPlatform().getSqlBuilder().getForeignKeyName(table, fk); - StringBuffer query = new StringBuffer(); + protected boolean isInternalForeignKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) + throws SQLException { + InterbaseBuilder builder = (InterbaseBuilder)getPlatform().createSqlBuilder(null); + String tableName = builder.getTableName(table); + String indexName = builder.getIndexName(index); + String fkName = builder.getForeignKeyName(table, fk); + StringBuffer query = new StringBuffer(); query.append("SELECT RDB$CONSTRAINT_NAME FROM RDB$RELATION_CONSTRAINTS where RDB$RELATION_NAME=? AND RDB$CONSTRAINT_TYPE=? AND RDB$CONSTRAINT_NAME=? AND RDB$INDEX_NAME=?"); PreparedStatement stmt = connection.prepareStatement(query.toString()); - try - { - stmt.setString(1, getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName.toUpperCase()); + try { + stmt.setString( + 1, + getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName + .toUpperCase()); stmt.setString(2, "FOREIGN KEY"); stmt.setString(3, fkName); stmt.setString(4, indexName); @@ -425,78 +377,68 @@ protected boolean isInternalForeignKeyIndex(Connection connection, DatabaseMetaD ResultSet resultSet = stmt.executeQuery(); return resultSet.next(); - } - finally - { - if (stmt != null) - { + } finally { + if (stmt != null) { stmt.close(); } } } @Override - public String determineSchemaOf(Connection connection, String schemaPattern, Table table) throws SQLException - { - ResultSet tableData = null; + public String determineSchemaOf(Connection connection, String schemaPattern, Table table) + throws SQLException { + ResultSet tableData = null; ResultSet columnData = null; - try - { + try { DatabaseMetaDataWrapper metaData = new DatabaseMetaDataWrapper(); metaData.setMetaData(connection.getMetaData()); metaData.setCatalog(getDefaultCatalogPattern()); - metaData.setSchemaPattern(schemaPattern == null ? getDefaultSchemaPattern() : schemaPattern); + metaData.setSchemaPattern(schemaPattern == null ? getDefaultSchemaPattern() + : schemaPattern); metaData.setTableTypes(getDefaultTableTypes()); String tablePattern = table.getName(); - if (getPlatform().isDelimitedIdentifierModeOn()) - { + if (getPlatform().isDelimitedIdentifierModeOn()) { tablePattern = tablePattern.toUpperCase(); } tableData = metaData.getTables(tablePattern); - boolean found = false; - String schema = null; + boolean found = false; + String schema = null; - while (!found && tableData.next()) - { - Map values = readColumns(tableData, getColumnsForTable()); - String tableName = (String)values.get("TABLE_NAME"); + while (!found && tableData.next()) { + Map values = readColumns(tableData, getColumnsForTable()); + String tableName = (String) values.get("TABLE_NAME"); - if ((tableName != null) && (tableName.length() > 0)) - { - schema = (String)values.get("TABLE_SCHEM"); - found = true; + if ((tableName != null) && (tableName.length() > 0)) { + schema = (String) values.get("TABLE_SCHEM"); + found = true; - if (getPlatform().isDelimitedIdentifierModeOn()) - { - // Jaybird has a problem when delimited identifiers are used as + if (getPlatform().isDelimitedIdentifierModeOn()) { + // Jaybird has a problem when delimited identifiers are + // used as // it is not able to find the columns for the table // So we have to filter manually below - columnData = metaData.getColumns(getDefaultTablePattern(), getDefaultColumnPattern()); - } - else - { + columnData = metaData.getColumns(getDefaultTablePattern(), + getDefaultColumnPattern()); + } else { columnData = metaData.getColumns(tableName, getDefaultColumnPattern()); } - while (found && columnData.next()) - { + while (found && columnData.next()) { values = readColumns(columnData, getColumnsForColumn()); - if (getPlatform().isDelimitedIdentifierModeOn() && - !tableName.equals(values.get("TABLE_NAME"))) - { + if (getPlatform().isDelimitedIdentifierModeOn() + && !tableName.equals(values.get("TABLE_NAME"))) { continue; } - if (table.findColumn((String)values.get("COLUMN_NAME"), - getPlatform().isDelimitedIdentifierModeOn()) == null) - { + if (table.findColumn((String) values.get("COLUMN_NAME"), getPlatform() + .isDelimitedIdentifierModeOn()) == null) { found = false; } } @@ -505,15 +447,11 @@ public String determineSchemaOf(Connection connection, String schemaPattern, Tab } } return found ? schema : null; - } - finally - { - if (columnData != null) - { + } finally { + if (columnData != null) { columnData.close(); } - if (tableData != null) - { + if (tableData != null) { tableData.close(); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbasePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbasePlatform.java new file mode 100644 index 0000000000..e10ca497ac --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/InterbasePlatform.java @@ -0,0 +1,100 @@ +package org.jumpmind.symmetric.db.platform.interbase; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for the Interbase database. + */ +public class InterbasePlatform extends AbstractDatabasePlatform { + /* Database name of this platform. */ + public static final String DATABASENAME = "Interbase"; + + /* The interbase jdbc driver. */ + public static final String JDBC_DRIVER = "interbase.interclient.Driver"; + + /* The subprotocol used by the interbase driver. */ + public static final String JDBC_SUBPROTOCOL = "interbase"; + + public static int SWITCH_TO_LONGVARCHAR_SIZE = 4096; + + /* + * Creates a new platform instance. + */ + public InterbasePlatform() { + + info.setMaxIdentifierLength(31); + info.setCommentPrefix("/*"); + info.setCommentSuffix("*/"); + info.setSystemForeignKeyIndicesAlwaysNonUnique(true); + + // BINARY and VARBINARY are also handled by the + // InterbaseBuilder.getSqlType method + info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.BIGINT, "NUMERIC(18,0)"); + // Theoretically we could use (VAR)CHAR CHARACTER SET OCTETS but the + // JDBC driver is not + // able to handle that properly (the byte[]/BinaryStream accessors do + // not work) + info.addNativeTypeMapping(Types.BINARY, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.BLOB, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.CLOB, "BLOB SUB_TYPE TEXT"); + info.addNativeTypeMapping(Types.DISTINCT, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE PRECISION", Types.DOUBLE); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.LONGVARBINARY, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.LONGVARCHAR, "VARCHAR(" + SWITCH_TO_LONGVARCHAR_SIZE + ")", + Types.VARCHAR); + info.addNativeTypeMapping(Types.NULL, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.REAL, "FLOAT"); + info.addNativeTypeMapping(Types.REF, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.VARBINARY, "BLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); + info.addNativeTypeMapping("DATALINK", "BLOB", "LONGVARBINARY"); + + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARCHAR, 254); + info.setHasSize(Types.BINARY, false); + info.setHasSize(Types.VARBINARY, false); + + info.setStoresUpperCaseInCatalog(true); + + modelReader = new InterbaseModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new InterbaseBuilder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/interbase/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/interbase/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlBuilder.java similarity index 55% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlBuilder.java index 0798f36c34..a228c6686f 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlBuilder.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.mssql; +package org.jumpmind.symmetric.db.platform.mssql; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,7 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.sql.Types; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -29,69 +29,55 @@ import java.util.List; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddForeignKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddIndexChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnAutoIncrementChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDataTypeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnSizeChange; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveForeignKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveIndexChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.CreationParameters; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddForeignKeyChange; +import org.jumpmind.symmetric.db.alter.AddIndexChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.ColumnAutoIncrementChange; +import org.jumpmind.symmetric.db.alter.ColumnChange; +import org.jumpmind.symmetric.db.alter.ColumnDataTypeChange; +import org.jumpmind.symmetric.db.alter.ColumnSizeChange; +import org.jumpmind.symmetric.db.alter.IModelChange; +import org.jumpmind.symmetric.db.alter.PrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.RemoveForeignKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveIndexChange; +import org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; +import org.jumpmind.symmetric.util.Log; /* * The SQL Builder for the Microsoft SQL Server. - * - * @version $Revision: 504014 $ */ -public class MSSqlBuilder extends SqlBuilder -{ +public class MSSqlBuilder extends SqlBuilder { /* We use a generic date format. */ private DateFormat _genericDateFormat = new SimpleDateFormat("yyyy-MM-dd"); /* We use a generic date format. */ private DateFormat _genericTimeFormat = new SimpleDateFormat("HH:mm:ss"); - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public MSSqlBuilder(Platform platform) - { - super(platform); + public MSSqlBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); addEscapedCharSequence("'", "''"); } - /* - * {@inheritDoc} - */ - public void createTable(Database database, Table table, Map parameters) throws IOException - { + @Override + public void createTable(Database database, Table table) { writeQuotationOnStatement(); - super.createTable(database, table, parameters); + super.createTable(database, table); } - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { - String tableName = getTableName(table); - String tableNameVar = "tn" + createUniqueIdentifier(); + @Override + public void dropTable(Table table) { + String tableName = getTableName(table); + String tableNameVar = "tn" + createUniqueIdentifier(); String constraintNameVar = "cn" + createUniqueIdentifier(); writeQuotationOnStatement(); @@ -99,7 +85,8 @@ public void dropTable(Table table) throws IOException printAlwaysSingleQuotedIdentifier(tableName); println(")"); println("BEGIN"); - println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + " nvarchar(256)"); + println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + + " nvarchar(256)"); println(" DECLARE refcursor CURSOR FOR"); println(" SELECT object_name(objs.parent_obj) tablename, objs.name constraintname"); println(" FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid"); @@ -109,7 +96,8 @@ public void dropTable(Table table) throws IOException println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar); println(" WHILE @@FETCH_STATUS = 0"); println(" BEGIN"); - println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")"); + println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + + constraintNameVar + ")"); println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar); println(" END"); println(" CLOSE refcursor"); @@ -120,81 +108,66 @@ public void dropTable(Table table) throws IOException printEndOfStatement(); } - /* - * {@inheritDoc} - */ - public void dropExternalForeignKeys(Table table) throws IOException - { + @Override + public void dropExternalForeignKeys(Table table) { writeQuotationOnStatement(); super.dropExternalForeignKeys(table); } - /* - * {@inheritDoc} - */ - protected DateFormat getValueDateFormat() - { + @Override + protected DateFormat getValueDateFormat() { return _genericDateFormat; } - /* - * {@inheritDoc} - */ - protected DateFormat getValueTimeFormat() - { + @Override + protected DateFormat getValueTimeFormat() { return _genericTimeFormat; } - /* - * {@inheritDoc} - */ - protected String getValueAsString(Column column, Object value) - { - if (value == null) - { + @Override + protected String getValueAsString(Column column, Object value) { + if (value == null) { return "NULL"; } StringBuffer result = new StringBuffer(); - switch (column.getTypeCode()) - { - case Types.REAL: - case Types.NUMERIC: - case Types.FLOAT: - case Types.DOUBLE: - case Types.DECIMAL: - // SQL Server does not want quotes around the value - if (!(value instanceof String) && (getValueNumberFormat() != null)) - { - result.append(getValueNumberFormat().format(value)); - } - else - { - result.append(value.toString()); - } - break; - case Types.DATE: - result.append("CAST("); - result.append(getPlatformInfo().getValueQuoteToken()); - result.append(value instanceof String ? (String)value : getValueDateFormat().format(value)); - result.append(getPlatformInfo().getValueQuoteToken()); - result.append(" AS datetime)"); - break; - case Types.TIME: - result.append("CAST("); - result.append(getPlatformInfo().getValueQuoteToken()); - result.append(value instanceof String ? (String)value : getValueTimeFormat().format(value)); - result.append(getPlatformInfo().getValueQuoteToken()); - result.append(" AS datetime)"); - break; - case Types.TIMESTAMP: - result.append("CAST("); - result.append(getPlatformInfo().getValueQuoteToken()); + switch (column.getTypeCode()) { + case Types.REAL: + case Types.NUMERIC: + case Types.FLOAT: + case Types.DOUBLE: + case Types.DECIMAL: + // SQL Server does not want quotes around the value + if (!(value instanceof String) && (getValueNumberFormat() != null)) { + result.append(getValueNumberFormat().format(value)); + } else { result.append(value.toString()); - result.append(getPlatformInfo().getValueQuoteToken()); - result.append(" AS datetime)"); - break; + } + break; + case Types.DATE: + result.append("CAST("); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + result.append(value instanceof String ? (String) value : getValueDateFormat().format( + value)); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + result.append(" AS datetime)"); + break; + case Types.TIME: + result.append("CAST("); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + result.append(value instanceof String ? (String) value : getValueTimeFormat().format( + value)); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + result.append(" AS datetime)"); + break; + case Types.TIMESTAMP: + result.append("CAST("); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + result.append(value.toString()); + result.append(platform.getPlatformInfo().getValueQuoteToken()); + result.append(" AS datetime)"); + break; } return super.getValueAsString(column, value); } @@ -202,33 +175,25 @@ protected String getValueAsString(Column column, Object value) /* * {@inheritDoc} */ - protected String getNativeDefaultValue(Column column) - { - // Sql Server wants BIT default values as 0 or 1 - if ((column.getTypeCode() == Types.BIT) || - (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode()))) - { - return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString(); - } - else - { + protected String getNativeDefaultValue(Column column) { + // Sql Server wants BIT default values as 0 or 1 + if ((column.getTypeCode() == Types.BIT) + || (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils + .determineBooleanTypeCode()))) { + return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), + Types.SMALLINT).toString(); + } else { return super.getNativeDefaultValue(column); } } - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { print("IDENTITY (1,1) "); } - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { print("DROP INDEX "); printIdentifier(getTableName(table)); print("."); @@ -236,11 +201,9 @@ public void writeExternalIndexDropStmt(Table table, Index index) throws IOExcept printEndOfStatement(); } - /* - * {@inheritDoc} - */ - protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) throws IOException - { + @Override + protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) + { String constraintName = getForeignKeyName(table, foreignKey); print("IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'F' AND name = "); @@ -255,35 +218,30 @@ protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKe } /* - * Returns the statement that turns on the ability to write delimited identifiers. + * Returns the statement that turns on the ability to write delimited + * identifiers. * * @return The quotation-on statement */ - private String getQuotationOnStatement() - { - if (getPlatform().isDelimitedIdentifierModeOn()) - { - return "SET quoted_identifier on" + getPlatformInfo().getSqlCommandDelimiter() + "\n"; - } - else - { + private String getQuotationOnStatement() { + if (platform.isDelimitedIdentifierModeOn()) { + return "SET quoted_identifier on" + platform.getPlatformInfo().getSqlCommandDelimiter() + + "\n"; + } else { return ""; } } /* - * Writes the statement that turns on the ability to write delimited identifiers. + * Writes the statement that turns on the ability to write delimited + * identifiers. */ - private void writeQuotationOnStatement() throws IOException - { + private void writeQuotationOnStatement() { print(getQuotationOnStatement()); } - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { + @Override + public String getSelectLastIdentityValues(Table table) { return "SELECT @@IDENTITY"; } @@ -291,17 +249,17 @@ public String getSelectLastIdentityValues(Table table) * Returns the SQL to enable identity override mode. * * @param table The table to enable the mode for + * * @return The SQL */ - protected String getEnableIdentityOverrideSql(Table table) - { + protected String getEnableIdentityOverrideSql(Table table) { StringBuffer result = new StringBuffer(); result.append(getQuotationOnStatement()); result.append("SET IDENTITY_INSERT "); result.append(getDelimitedIdentifier(getTableName(table))); result.append(" ON"); - result.append(getPlatformInfo().getSqlCommandDelimiter()); + result.append(platform.getPlatformInfo().getSqlCommandDelimiter()); return result.toString(); } @@ -310,78 +268,65 @@ protected String getEnableIdentityOverrideSql(Table table) * Returns the SQL to disable identity override mode. * * @param table The table to disable the mode for + * * @return The SQL */ - protected String getDisableIdentityOverrideSql(Table table) - { + protected String getDisableIdentityOverrideSql(Table table) { StringBuffer result = new StringBuffer(); result.append(getQuotationOnStatement()); result.append("SET IDENTITY_INSERT "); result.append(getDelimitedIdentifier(getTableName(table))); result.append(" OFF"); - result.append(getPlatformInfo().getSqlCommandDelimiter()); + result.append(platform.getPlatformInfo().getSqlCommandDelimiter()); return result.toString(); } - /* - * {@inheritDoc} - */ - public String getDeleteSql(Table table, Map pkValues, boolean genPlaceholders) - { + @Override + public String getDeleteSql(Table table, Map pkValues, boolean genPlaceholders) { return getQuotationOnStatement() + super.getDeleteSql(table, pkValues, genPlaceholders); } - - /* - * {@inheritDoc} - */ - public String getInsertSql(Table table, Map columnValues, boolean genPlaceholders) - { + + @Override + public String getInsertSql(Table table, Map columnValues, boolean genPlaceholders) { return getQuotationOnStatement() + super.getInsertSql(table, columnValues, genPlaceholders); } - /* - * {@inheritDoc} - */ - public String getUpdateSql(Table table, Map columnValues, boolean genPlaceholders) - { + @Override + public String getUpdateSql(Table table, Map columnValues, boolean genPlaceholders) { return getQuotationOnStatement() + super.getUpdateSql(table, columnValues, genPlaceholders); } /* - * Prints the given identifier with enforced single quotes around it regardless of whether - * delimited identifiers are turned on or not. + * Prints the given identifier with enforced single quotes around it + * regardless of whether delimited identifiers are turned on or not. * * @param identifier The identifier */ - private void printAlwaysSingleQuotedIdentifier(String identifier) throws IOException - { + private void printAlwaysSingleQuotedIdentifier(String identifier) { print("'"); print(identifier); print("'"); } - /* - * {@inheritDoc} - */ - public void writeCopyDataStatement(Table sourceTable, Table targetTable) throws IOException - { - // Sql Server per default does not allow us to insert values explicitly into + @Override + public void writeCopyDataStatement(Table sourceTable, Table targetTable) { + // Sql Server per default does not allow us to insert values explicitly + // into // identity columns. However, we can change this behavior boolean hasIdentityColumns = targetTable.getAutoIncrementColumns().length > 0; - if (hasIdentityColumns) - { + if (hasIdentityColumns) { print("SET IDENTITY_INSERT "); printIdentifier(getTableName(targetTable)); print(" ON"); printEndOfStatement(); } super.writeCopyDataStatement(sourceTable, targetTable); - // We have to turn it off ASAP because it can be on only for one table per session - if (hasIdentityColumns) - { + // We have to turn it off ASAP because it can be on only for one table + // per session + if (hasIdentityColumns) { print("SET IDENTITY_INSERT "); printIdentifier(getTableName(targetTable)); print(" OFF"); @@ -389,84 +334,69 @@ public void writeCopyDataStatement(Table sourceTable, Table targetTable) throws } } - /* - * {@inheritDoc} - */ - protected void processChanges(Database currentModel, Database desiredModel, List changes, CreationParameters params) throws IOException - { - if (!changes.isEmpty()) - { + @Override + protected void processChanges(Database currentModel, Database desiredModel, + List changes) { + if (!changes.isEmpty()) { writeQuotationOnStatement(); } - // For column data type and size changes, we need to drop and then re-create indexes - // and foreign keys using the column, as well as any primary keys containg + // For column data type and size changes, we need to drop and then + // re-create indexes + // and foreign keys using the column, as well as any primary keys + // containg // these columns - // However, if the index/foreign key/primary key is already slated for removal or + // However, if the index/foreign key/primary key is already slated for + // removal or // change, then we don't want to generate change duplication - HashSet removedIndexes = new HashSet(); + HashSet removedIndexes = new HashSet(); HashSet removedForeignKeys = new HashSet(); - HashSet removedPKs = new HashSet(); + HashSet removedPKs = new HashSet(); - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { Object change = changeIt.next(); - if (change instanceof RemoveIndexChange) - { - removedIndexes.add(((RemoveIndexChange)change).getIndex()); - } - else if (change instanceof RemoveForeignKeyChange) - { - removedForeignKeys.add(((RemoveForeignKeyChange)change).getForeignKey()); - } - else if (change instanceof RemovePrimaryKeyChange) - { - removedPKs.add(((RemovePrimaryKeyChange)change).getChangedTable()); + if (change instanceof RemoveIndexChange) { + removedIndexes.add(((RemoveIndexChange) change).getIndex()); + } else if (change instanceof RemoveForeignKeyChange) { + removedForeignKeys.add(((RemoveForeignKeyChange) change).getForeignKey()); + } else if (change instanceof RemovePrimaryKeyChange) { + removedPKs.add(((RemovePrimaryKeyChange) change).getChangedTable()); } } ArrayList additionalChanges = new ArrayList(); - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { Object change = changeIt.next(); - if ((change instanceof ColumnDataTypeChange) || - (change instanceof ColumnSizeChange)) - { - Column column = ((ColumnChange)change).getChangedColumn(); - Table table = ((ColumnChange)change).getChangedTable(); + if ((change instanceof ColumnDataTypeChange) || (change instanceof ColumnSizeChange)) { + Column column = ((ColumnChange) change).getChangedColumn(); + Table table = ((ColumnChange) change).getChangedTable(); - if (column.isPrimaryKey() && !removedPKs.contains(table)) - { + if (column.isPrimaryKey() && !removedPKs.contains(table)) { Column[] pk = table.getPrimaryKeyColumns(); additionalChanges.add(new RemovePrimaryKeyChange(table, pk)); additionalChanges.add(new AddPrimaryKeyChange(table, pk)); removedPKs.add(table); } - for (int idx = 0; idx < table.getIndexCount(); idx++) - { + for (int idx = 0; idx < table.getIndexCount(); idx++) { Index index = table.getIndex(idx); - if (index.hasColumn(column) && !removedIndexes.contains(index)) - { + if (index.hasColumn(column) && !removedIndexes.contains(index)) { additionalChanges.add(new RemoveIndexChange(table, index)); additionalChanges.add(new AddIndexChange(table, index)); removedIndexes.add(index); } } - for (int tableIdx = 0; tableIdx < currentModel.getTableCount(); tableIdx++) - { + for (int tableIdx = 0; tableIdx < currentModel.getTableCount(); tableIdx++) { Table curTable = currentModel.getTable(tableIdx); - for (int fkIdx = 0; fkIdx < curTable.getForeignKeyCount(); fkIdx++) - { + for (int fkIdx = 0; fkIdx < curTable.getForeignKeyCount(); fkIdx++) { ForeignKey curFk = curTable.getForeignKey(fkIdx); - if ((curFk.hasLocalColumn(column) || curFk.hasForeignColumn(column)) && - !removedForeignKeys.contains(curFk)) - { + if ((curFk.hasLocalColumn(column) || curFk.hasForeignColumn(column)) + && !removedForeignKeys.contains(curFk)) { additionalChanges.add(new RemoveForeignKeyChange(curTable, curFk)); additionalChanges.add(new AddForeignKeyChange(curTable, curFk)); removedForeignKeys.add(curFk); @@ -476,34 +406,23 @@ else if (change instanceof RemovePrimaryKeyChange) } } changes.addAll(additionalChanges); - super.processChanges(currentModel, desiredModel, changes, params); + super.processChanges(currentModel, desiredModel, changes); } - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { // First we drop primary keys as necessary - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - if (change instanceof RemovePrimaryKeyChange) - { - processChange(currentModel, desiredModel, (RemovePrimaryKeyChange)change); + if (change instanceof RemovePrimaryKeyChange) { + processChange(currentModel, desiredModel, (RemovePrimaryKeyChange) change); changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - PrimaryKeyChange pkChange = (PrimaryKeyChange)change; - RemovePrimaryKeyChange removePkChange = new RemovePrimaryKeyChange(pkChange.getChangedTable(), - pkChange.getOldPrimaryKeyColumns()); + } else if (change instanceof PrimaryKeyChange) { + PrimaryKeyChange pkChange = (PrimaryKeyChange) change; + RemovePrimaryKeyChange removePkChange = new RemovePrimaryKeyChange( + pkChange.getChangedTable(), pkChange.getOldPrimaryKeyColumns()); processChange(currentModel, desiredModel, removePkChange); } @@ -512,78 +431,64 @@ else if (change instanceof PrimaryKeyChange) ArrayList columnChanges = new ArrayList(); // Next we add/remove columns - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = (TableChange) changeIt.next(); - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; // Sql Server can only add not insert columns - if (addColumnChange.isAtEnd()) - { + if (addColumnChange.isAtEnd()) { processChange(currentModel, desiredModel, addColumnChange); changeIt.remove(); } - } - else if (change instanceof RemoveColumnChange) - { - processChange(currentModel, desiredModel, (RemoveColumnChange)change); + } else if (change instanceof RemoveColumnChange) { + processChange(currentModel, desiredModel, (RemoveColumnChange) change); changeIt.remove(); - } - else if (change instanceof ColumnAutoIncrementChange) - { - // Sql Server has no way of adding or removing an IDENTITY constraint - // Thus we have to rebuild the table anyway and can ignore all the other + } else if (change instanceof ColumnAutoIncrementChange) { + // Sql Server has no way of adding or removing an IDENTITY + // constraint + // Thus we have to rebuild the table anyway and can ignore all + // the other // column changes columnChanges = null; - } - else if ((change instanceof ColumnChange) && (columnChanges != null)) - { - // we gather all changed columns because we can use the ALTER TABLE ALTER COLUMN + } else if ((change instanceof ColumnChange) && (columnChanges != null)) { + // we gather all changed columns because we can use the ALTER + // TABLE ALTER COLUMN // statement for them columnChanges.add(change); } } - if (columnChanges != null) - { + if (columnChanges != null) { HashSet processedColumns = new HashSet(); - for (Iterator changeIt = columnChanges.iterator(); changeIt.hasNext();) - { - ColumnChange change = (ColumnChange)changeIt.next(); - Column sourceColumn = change.getChangedColumn(); - Column targetColumn = targetTable.findColumn(sourceColumn.getName(), getPlatform().isDelimitedIdentifierModeOn()); - - if (!processedColumns.contains(targetColumn)) - { - processColumnChange(sourceTable, - targetTable, - sourceColumn, - targetColumn, - (change instanceof ColumnDataTypeChange) || (change instanceof ColumnSizeChange)); + for (Iterator changeIt = columnChanges.iterator(); changeIt.hasNext();) { + ColumnChange change = (ColumnChange) changeIt.next(); + Column sourceColumn = change.getChangedColumn(); + Column targetColumn = targetTable.findColumn(sourceColumn.getName(), + platform.isDelimitedIdentifierModeOn()); + + if (!processedColumns.contains(targetColumn)) { + processColumnChange(sourceTable, targetTable, sourceColumn, targetColumn, + (change instanceof ColumnDataTypeChange) + || (change instanceof ColumnSizeChange)); processedColumns.add(targetColumn); } changes.remove(change); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } } // Finally we add primary keys - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = (TableChange) changeIt.next(); - if (change instanceof AddPrimaryKeyChange) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); + if (change instanceof AddPrimaryKeyChange) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - PrimaryKeyChange pkChange = (PrimaryKeyChange)change; - AddPrimaryKeyChange addPkChange = new AddPrimaryKeyChange(pkChange.getChangedTable(), - pkChange.getNewPrimaryKeyColumns()); + } else if (change instanceof PrimaryKeyChange) { + PrimaryKeyChange pkChange = (PrimaryKeyChange) change; + AddPrimaryKeyChange addPkChange = new AddPrimaryKeyChange( + pkChange.getChangedTable(), pkChange.getNewPrimaryKeyColumns()); processChange(currentModel, desiredModel, addPkChange); changeIt.remove(); @@ -595,61 +500,62 @@ else if (change instanceof PrimaryKeyChange) * Processes the addition of a column to a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("ADD "); writeColumn(change.getChangedTable(), change.getNewColumn()); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a column from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("DROP COLUMN "); printIdentifier(getColumnName(change.getColumn())); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a primary key from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemovePrimaryKeyChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + RemovePrimaryKeyChange change) { // TODO: this would be easier when named primary keys are supported - // because then we can use ALTER TABLE DROP - String tableName = getTableName(change.getChangedTable()); - String tableNameVar = "tn" + createUniqueIdentifier(); + // because then we can use ALTER TABLE DROP + String tableName = getTableName(change.getChangedTable()); + String tableNameVar = "tn" + createUniqueIdentifier(); String constraintNameVar = "cn" + createUniqueIdentifier(); println("BEGIN"); - println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + " nvarchar(256)"); + println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + + " nvarchar(256)"); println(" DECLARE refcursor CURSOR FOR"); println(" SELECT object_name(objs.parent_obj) tablename, objs.name constraintname"); println(" FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid"); @@ -659,51 +565,52 @@ protected void processChange(Database currentModel, println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar); println(" WHILE @@FETCH_STATUS = 0"); println(" BEGIN"); - println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")"); + println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + + constraintNameVar + ")"); println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar); println(" END"); println(" CLOSE refcursor"); println(" DEALLOCATE refcursor"); print("END"); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes a change to a column. * - * @param sourceTable The current table - * @param targetTable The desired table + * @param sourceTable The current table + * + * @param targetTable The desired table + * * @param sourceColumn The current column + * * @param targetColumn The desired column - * @param typeChange Whether this is a type change + * + * @param typeChange Whether this is a type change */ - protected void processColumnChange(Table sourceTable, - Table targetTable, - Column sourceColumn, - Column targetColumn, - boolean typeChange) throws IOException - { - boolean hasDefault = sourceColumn.getParsedDefaultValue() != null; + protected void processColumnChange(Table sourceTable, Table targetTable, Column sourceColumn, + Column targetColumn, boolean typeChange) { + boolean hasDefault = sourceColumn.getParsedDefaultValue() != null; boolean shallHaveDefault = targetColumn.getParsedDefaultValue() != null; - String newDefault = targetColumn.getDefaultValue(); + String newDefault = targetColumn.getDefaultValue(); - // Sql Server does not like it if there is a default spec in the ALTER TABLE ALTER COLUMN + // Sql Server does not like it if there is a default spec in the ALTER + // TABLE ALTER COLUMN // statement; thus we have to change the default manually - if (newDefault != null) - { + if (newDefault != null) { targetColumn.setDefaultValue(null); } - if (hasDefault) - { + if (hasDefault) { // we're dropping the old default - String tableName = getTableName(sourceTable); - String columnName = getColumnName(sourceColumn); - String tableNameVar = "tn" + createUniqueIdentifier(); + String tableName = getTableName(sourceTable); + String columnName = getColumnName(sourceColumn); + String tableNameVar = "tn" + createUniqueIdentifier(); String constraintNameVar = "cn" + createUniqueIdentifier(); println("BEGIN"); - println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + " nvarchar(256)"); + println(" DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + + " nvarchar(256)"); println(" DECLARE refcursor CURSOR FOR"); println(" SELECT object_name(objs.parent_obj) tablename, objs.name constraintname"); println(" FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid"); @@ -719,8 +626,10 @@ protected void processColumnChange(Table sourceTable, println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar); println(" WHILE @@FETCH_STATUS = 0"); println(" BEGIN"); - println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")"); - println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar); + println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + + constraintNameVar + ")"); + println(" FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + + constraintNameVar); println(" END"); println(" CLOSE refcursor"); println(" DEALLOCATE refcursor"); @@ -735,11 +644,11 @@ protected void processColumnChange(Table sourceTable, writeColumn(sourceTable, targetColumn); printEndOfStatement(); - if (shallHaveDefault) - { + if (shallHaveDefault) { targetColumn.setDefaultValue(newDefault); - // if the column shall have a default, then we have to add it as a constraint + // if the column shall have a default, then we have to add it as a + // constraint print("ALTER TABLE "); printlnIdentifier(getTableName(sourceTable)); printIndent(); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlModelReader.java similarity index 90% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlModelReader.java index fa29f4da6e..93e7adfe63 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/MSSqlModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.mssql; +package org.jumpmind.symmetric.db.platform.mssql; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -34,14 +34,14 @@ import org.apache.oro.text.regex.PatternMatcher; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a Microsoft Sql Server database. @@ -62,7 +62,7 @@ public class MSSqlModelReader extends JdbcModelReader * * @param platform The platform that this model reader belongs to */ - public MSSqlModelReader(Platform platform) + public MSSqlModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlPlatform.java new file mode 100644 index 0000000000..57cbd88092 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/MSSqlPlatform.java @@ -0,0 +1,102 @@ +package org.jumpmind.symmetric.db.platform.mssql; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for the Microsoft SQL Server database. + */ +public class MSSqlPlatform extends AbstractDatabasePlatform { + /* Database name of this platform. */ + public static final String DATABASENAME = "MsSql"; + + /* The standard SQLServer jdbc driver. */ + public static final String JDBC_DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver"; + + /* + * The new SQLServer 2005 jdbc driver which can also be used for SQL Server + * 2000. + */ + public static final String JDBC_DRIVER_NEW = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; + + /* The subprotocol used by the standard SQL Server driver. */ + public static final String JDBC_SUBPROTOCOL = "microsoft:sqlserver"; + + /* The subprotocol recommended for the newer SQL Server 2005 driver. */ + public static final String JDBC_SUBPROTOCOL_NEW = "sqlserver"; + + /* The subprotocol internally returned by the newer SQL Server 2005 driver. */ + public static final String JDBC_SUBPROTOCOL_INTERNAL = "sqljdbc"; + + /* + * Creates a new platform instance. + */ + public MSSqlPlatform() { + + info.setMaxIdentifierLength(128); + + info.addNativeTypeMapping(Types.ARRAY, "IMAGE", Types.LONGVARBINARY); + // BIGINT will be mapped back to BIGINT by the model reader + info.addNativeTypeMapping(Types.BIGINT, "DECIMAL(19,0)"); + info.addNativeTypeMapping(Types.BLOB, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.CLOB, "TEXT", Types.LONGVARCHAR); + info.addNativeTypeMapping(Types.DATE, "DATETIME", Types.TIMESTAMP); + info.addNativeTypeMapping(Types.DISTINCT, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.DOUBLE, "FLOAT", Types.FLOAT); + info.addNativeTypeMapping(Types.INTEGER, "INT"); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.LONGVARBINARY, "IMAGE"); + info.addNativeTypeMapping(Types.LONGVARCHAR, "TEXT"); + info.addNativeTypeMapping(Types.NULL, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.OTHER, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.REF, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.TIME, "DATETIME", Types.TIMESTAMP); + info.addNativeTypeMapping(Types.TIMESTAMP, "DATETIME"); + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping("BOOLEAN", "BIT", "BIT"); + info.addNativeTypeMapping("DATALINK", "IMAGE", "LONGVARBINARY"); + + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARCHAR, 254); + info.setDefaultSize(Types.BINARY, 254); + info.setDefaultSize(Types.VARBINARY, 254); + + info.setStoresUpperCaseInCatalog(true); + + modelReader = new MSSqlModelReader(this); + + setDelimitedIdentifierModeOn(true); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new MSSqlBuilder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mssql/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mssql/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlBuilder.java new file mode 100644 index 0000000000..29d94008ec --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlBuilder.java @@ -0,0 +1,282 @@ +package org.jumpmind.symmetric.db.platform.mysql; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.collections.set.ListOrderedSet; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.ColumnChange; +import org.jumpmind.symmetric.db.alter.PrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.util.Log; + +/* + * The SQL Builder for MySQL. + */ +public class MySqlBuilder extends SqlBuilder { + + public MySqlBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + + // we need to handle the backslash first otherwise the other + // already escaped sequences would be affected + addEscapedCharSequence("\\", "\\\\"); + addEscapedCharSequence("\0", "\\0"); + addEscapedCharSequence("'", "\\'"); + addEscapedCharSequence("\"", "\\\""); + addEscapedCharSequence("\b", "\\b"); + addEscapedCharSequence("\n", "\\n"); + addEscapedCharSequence("\r", "\\r"); + addEscapedCharSequence("\t", "\\t"); + addEscapedCharSequence("\u001A", "\\Z"); + addEscapedCharSequence("%", "\\%"); + addEscapedCharSequence("_", "\\_"); + } + + @Override + public void dropTable(Table table) { + print("DROP TABLE IF EXISTS "); + printIdentifier(getTableName(table)); + printEndOfStatement(); + } + + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { + print("AUTO_INCREMENT"); + } + + @Override + protected boolean shouldGeneratePrimaryKeys(Column[] primaryKeyColumns) { + // mySQL requires primary key indication for autoincrement key columns + // I'm not sure why the default skips the pk statement if all are + // identity + return true; + } + + /* + * Normally mysql will return the LAST_INSERT_ID as the column name for the + * inserted id. Since ddlutils expects the real column name of the field + * that is autoincrementing, the column has an alias of that column name. + */ + @Override + public String getSelectLastIdentityValues(Table table) { + String autoIncrementKeyName = ""; + if (table.getAutoIncrementColumns().length > 0) { + autoIncrementKeyName = table.getAutoIncrementColumns()[0].getName(); + } + return "SELECT LAST_INSERT_ID() " + autoIncrementKeyName; + } + + @Override + protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) + { + writeTableAlterStmt(table); + print("DROP FOREIGN KEY "); + printIdentifier(getForeignKeyName(table, foreignKey)); + printEndOfStatement(); + + if (foreignKey.isAutoIndexPresent()) { + writeTableAlterStmt(table); + print("DROP INDEX "); + printIdentifier(getForeignKeyName(table, foreignKey)); + printEndOfStatement(); + } + } + + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + // in order to utilize the ALTER TABLE ADD COLUMN AFTER statement + // we have to apply the add column changes in the correct order + // thus we first gather all add column changes and then execute them + ArrayList addColumnChanges = new ArrayList(); + + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddColumnChange) { + addColumnChanges.add((AddColumnChange) change); + changeIt.remove(); + } + } + for (Iterator changeIt = addColumnChanges.iterator(); changeIt.hasNext();) { + AddColumnChange addColumnChange = changeIt.next(); + + processChange(currentModel, desiredModel, addColumnChange); + changeIt.remove(); + } + + ListOrderedSet changedColumns = new ListOrderedSet(); + + // we don't have to care about the order because the comparator will + // have ensured that a add primary key change comes after all necessary + // columns are present + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof RemoveColumnChange) { + processChange(currentModel, desiredModel, (RemoveColumnChange) change); + changeIt.remove(); + } else if (change instanceof AddPrimaryKeyChange) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); + changeIt.remove(); + } else if (change instanceof PrimaryKeyChange) { + processChange(currentModel, desiredModel, (PrimaryKeyChange) change); + changeIt.remove(); + } else if (change instanceof RemovePrimaryKeyChange) { + processChange(currentModel, desiredModel, (RemovePrimaryKeyChange) change); + changeIt.remove(); + } else if (change instanceof ColumnChange) { + // we gather all changed columns because we can use the ALTER + // TABLE MODIFY COLUMN + // statement for them + changedColumns.add(((ColumnChange) change).getChangedColumn()); + changeIt.remove(); + } + } + for (Iterator columnIt = changedColumns.iterator(); columnIt.hasNext();) { + Column sourceColumn = columnIt.next(); + Column targetColumn = targetTable.findColumn(sourceColumn.getName(), + platform.isDelimitedIdentifierModeOn()); + + processColumnChange(sourceTable, targetTable, sourceColumn, targetColumn); + } + } + + /* + * Processes the addition of a column to a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("ADD COLUMN "); + writeColumn(change.getChangedTable(), change.getNewColumn()); + if (change.getPreviousColumn() != null) { + print(" AFTER "); + printIdentifier(getColumnName(change.getPreviousColumn())); + } else { + print(" FIRST"); + } + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a column from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP COLUMN "); + printIdentifier(getColumnName(change.getColumn())); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a primary key from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemovePrimaryKeyChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP PRIMARY KEY"); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the change of the primary key of a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + PrimaryKeyChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP PRIMARY KEY"); + printEndOfStatement(); + writeExternalPrimaryKeysCreateStmt(change.getChangedTable(), + change.getNewPrimaryKeyColumns()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes a change to a column. + * + * @param sourceTable The current table + * + * @param targetTable The desired table + * + * @param sourceColumn The current column + * + * @param targetColumn The desired column + */ + protected void processColumnChange(Table sourceTable, Table targetTable, Column sourceColumn, + Column targetColumn) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(sourceTable)); + printIndent(); + print("MODIFY COLUMN "); + writeColumn(targetTable, targetColumn); + printEndOfStatement(); + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlModelReader.java similarity index 55% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlModelReader.java index 7240eb1e18..a0ed8de717 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/MySqlModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.mysql; +package org.jumpmind.symmetric.db.platform.mysql; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -24,26 +24,25 @@ import java.sql.Types; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a MySql database. */ -public class MySqlModelReader extends JdbcModelReader -{ +public class MySqlModelReader extends JdbcModelReader { + /* * Creates a new model reader for MySql databases. * * @param platform The platform that this model reader belongs to */ - public MySqlModelReader(Platform platform) - { + public MySqlModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); setDefaultSchemaPattern(null); @@ -51,26 +50,27 @@ public MySqlModelReader(Platform platform) } @Override - protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { - // TODO This needs some more work, since table names can be case sensitive or lowercase - // depending on the platform (really cute). - // See http://dev.mysql.com/doc/refman/4.1/en/name-case-sensitivity.html for more info. + protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, + Map values) throws SQLException { + // TODO This needs some more work, since table names can be case + // sensitive or lowercase + // depending on the platform (really cute). + // See http://dev.mysql.com/doc/refman/4.1/en/name-case-sensitivity.html + // for more info. Table table = super.readTable(connection, metaData, values); - if (table != null) - { - determineAutoIncrementFromResultSetMetaData(connection, table, table.getPrimaryKeyColumns()); + if (table != null) { + determineAutoIncrementFromResultSetMetaData(connection, table, + table.getPrimaryKeyColumns()); } return table; } - @Override - protected Integer overrideJdbcTypeForColumn(Map values) { - String typeName = (String)values.get("TYPE_NAME"); - if("YEAR".equals(typeName)) { + protected Integer overrideJdbcTypeForColumn(Map values) { + String typeName = (String) values.get("TYPE_NAME"); + if ("YEAR".equals(typeName)) { // it is safe to map a YEAR to INTEGER return Types.INTEGER; } else { @@ -79,31 +79,35 @@ protected Integer overrideJdbcTypeForColumn(Map values) { } @Override - protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException - { + protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) + throws SQLException { Column column = super.readColumn(metaData, values); - // MySQL converts illegal date/time/timestamp values to "0000-00-00 00:00:00", but this + // MySQL converts illegal date/time/timestamp values to + // "0000-00-00 00:00:00", but this // is an illegal ISO value, so we replace it with NULL - if ((column.getTypeCode() == Types.TIMESTAMP) && - "0000-00-00 00:00:00".equals(column.getDefaultValue())) - { + if ((column.getTypeCode() == Types.TIMESTAMP) + && "0000-00-00 00:00:00".equals(column.getDefaultValue())) { + column.setDefaultValue(null); + } + // make sure the defaultvalue is null when an empty is returned. + if ("".equals(column.getDefaultValue())) { column.setDefaultValue(null); } return column; } @Override - protected boolean isInternalPrimaryKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, Index index) - { + protected boolean isInternalPrimaryKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, Index index) { // MySql defines a unique index "PRIMARY" for primary keys return "PRIMARY".equals(index.getName()); } @Override - protected boolean isInternalForeignKeyIndex(Connection connection, DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) - { + protected boolean isInternalForeignKeyIndex(Connection connection, + DatabaseMetaDataWrapper metaData, Table table, ForeignKey fk, Index index) { // MySql defines a non-unique index of the same name as the fk - return getPlatform().getSqlBuilder().getForeignKeyName(table, fk).equals(index.getName()); + return getPlatform().createSqlBuilder(null).getForeignKeyName(table, fk).equals(index.getName()); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlPlatform.java new file mode 100644 index 0000000000..6a48bb4bb4 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/MySqlPlatform.java @@ -0,0 +1,110 @@ +package org.jumpmind.symmetric.db.platform.mysql; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for MySQL. + */ +public class MySqlPlatform extends AbstractDatabasePlatform { + + /* Database name of this platform. */ + public static final String DATABASENAME = "MySQL"; + + /* The standard MySQL jdbc driver. */ + public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; + + /* The old MySQL jdbc driver. */ + public static final String JDBC_DRIVER_OLD = "org.gjt.mm.mysql.Driver"; + + /* The subprotocol used by the standard MySQL driver. */ + public static final String JDBC_SUBPROTOCOL = "mysql"; + + /* + * Creates a new platform instance. + */ + public MySqlPlatform() { + + info.setMaxIdentifierLength(64); + info.setNullAsDefaultValueRequired(true); + info.setDefaultValuesForLongTypesSupported(false); + // see + // http://dev.mysql.com/doc/refman/4.1/en/example-auto-increment.html + info.setNonPKIdentityColumnsSupported(false); + // MySql returns synthetic default values for pk columns + info.setSyntheticDefaultValueForRequiredReturned(true); + info.setCommentPrefix("#"); + // Double quotes are only allowed for delimiting identifiers if the + // server SQL mode includes ANSI_QUOTES + info.setDelimiterToken("`"); + + info.addNativeTypeMapping(Types.ARRAY, "LONGBLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.BIT, "TINYINT(1)"); + info.addNativeTypeMapping(Types.BLOB, "LONGBLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.CLOB, "LONGTEXT", Types.LONGVARCHAR); + info.addNativeTypeMapping(Types.DISTINCT, "LONGBLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "LONGBLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.LONGVARBINARY, "MEDIUMBLOB"); + info.addNativeTypeMapping(Types.LONGVARCHAR, "MEDIUMTEXT"); + info.addNativeTypeMapping(Types.NULL, "MEDIUMBLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.NUMERIC, "DECIMAL", Types.DECIMAL); + info.addNativeTypeMapping(Types.OTHER, "LONGBLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.REAL, "FLOAT"); + info.addNativeTypeMapping(Types.REF, "MEDIUMBLOB", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "LONGBLOB", Types.LONGVARBINARY); + // Since TIMESTAMP is not a stable datatype yet, and does not support a + // higher precision + // than DATETIME (year to seconds) as of MySQL 5, we map the JDBC type + // here to DATETIME + // TODO: Make this configurable + info.addNativeTypeMapping(Types.TIMESTAMP, "DATETIME"); + // In MySql, TINYINT has only a range of -128 to 127 + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping("BOOLEAN", "TINYINT(1)", "BIT"); + info.addNativeTypeMapping("DATALINK", "MEDIUMBLOB", "LONGVARBINARY"); + + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARCHAR, 254); + info.setDefaultSize(Types.BINARY, 254); + info.setDefaultSize(Types.VARBINARY, 254); + + setDelimitedIdentifierModeOn(true); + + // MySql 5.0 returns an empty string for default values for pk columns + // which is different from the MySql 4 behaviour + info.setSyntheticDefaultValueForRequiredReturned(false); + + modelReader = new MySqlModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new MySqlBuilder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/mysql/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/mysql/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleBuilder.java new file mode 100644 index 0000000000..48282e09af --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleBuilder.java @@ -0,0 +1,458 @@ +package org.jumpmind.symmetric.db.platform.oracle; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; +import java.util.Iterator; +import java.util.List; + +import org.apache.oro.text.regex.MalformedPatternException; +import org.apache.oro.text.regex.Pattern; +import org.apache.oro.text.regex.PatternCompiler; +import org.apache.oro.text.regex.Perl5Compiler; +import org.apache.oro.text.regex.Perl5Matcher; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.PrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; +import org.jumpmind.symmetric.util.Log; + +/* + * The SQL Builder for Oracle. + */ +public class OracleBuilder extends SqlBuilder { + + /* The regular expression pattern for ISO dates, i.e. 'YYYY-MM-DD'. */ + private Pattern isoDatePattern; + + /* The regular expression pattern for ISO times, i.e. 'HH:MI:SS'. */ + private Pattern isoTimePattern; + + /* + * The regular expression pattern for ISO timestamps, i.e. 'YYYY-MM-DD + * HH:MI:SS.fffffffff'. + */ + private Pattern isoTimestampPattern; + + public OracleBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + + addEscapedCharSequence("'", "''"); + + PatternCompiler compiler = new Perl5Compiler(); + + try { + isoDatePattern = compiler.compile("\\d{4}\\-\\d{2}\\-\\d{2}"); + isoTimePattern = compiler.compile("\\d{2}:\\d{2}:\\d{2}"); + isoTimestampPattern = compiler + .compile("\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2}[\\.\\d{1,8}]?"); + } catch (MalformedPatternException ex) { + throw new DdlUtilsException(ex); + } + } + + @Override + public void createTable(Database database, Table table) { + // lets create any sequences + Column[] columns = table.getAutoIncrementColumns(); + + for (int idx = 0; idx < columns.length; idx++) { + createAutoIncrementSequence(table, columns[idx]); + } + + super.createTable(database, table); + + for (int idx = 0; idx < columns.length; idx++) { + createAutoIncrementTrigger(table, columns[idx]); + } + } + + @Override + public void dropTable(Table table) { + // The only difference to the Oracle 8/9 variant is the purge which + // prevents the + // table from being moved to the recycle bin (which is new in Oracle 10) + Column[] columns = table.getAutoIncrementColumns(); + + for (int idx = 0; idx < columns.length; idx++) { + dropAutoIncrementTrigger(table, columns[idx]); + dropAutoIncrementSequence(table, columns[idx]); + } + + print("DROP TABLE "); + printIdentifier(getTableName(table)); + print(" CASCADE CONSTRAINTS PURGE"); + printEndOfStatement(); + } + + /* + * Creates the sequence necessary for the auto-increment of the given + * column. + * + * @param table The table + * + * @param column The column + */ + protected void createAutoIncrementSequence(Table table, Column column) { + print("CREATE SEQUENCE "); + printIdentifier(getConstraintName("seq", table, column.getName(), null)); + printEndOfStatement(); + } + + /* + * Creates the trigger necessary for the auto-increment of the given column. + * + * @param table The table + * + * @param column The column + */ + protected void createAutoIncrementTrigger(Table table, Column column) { + String columnName = getColumnName(column); + String triggerName = getConstraintName("trg", table, column.getName(), null); + + if (platform.isScriptModeOn()) { + // For the script, we output a more nicely formatted version + print("CREATE OR REPLACE TRIGGER "); + printlnIdentifier(triggerName); + print("BEFORE INSERT ON "); + printlnIdentifier(getTableName(table)); + print("FOR EACH ROW WHEN (new."); + printIdentifier(columnName); + println(" IS NULL)"); + println("BEGIN"); + print(" SELECT "); + printIdentifier(getConstraintName("seq", table, column.getName(), null)); + print(".nextval INTO :new."); + printIdentifier(columnName); + print(" FROM dual"); + println(platform.getPlatformInfo().getSqlCommandDelimiter()); + print("END"); + println(platform.getPlatformInfo().getSqlCommandDelimiter()); + println("/"); + println(); + } else { + // note that the BEGIN ... SELECT ... END; is all in one line and + // does + // not contain a semicolon except for the END-one + // this way, the tokenizer will not split the statement before the + // END + print("CREATE OR REPLACE TRIGGER "); + printIdentifier(triggerName); + print(" BEFORE INSERT ON "); + printIdentifier(getTableName(table)); + print(" FOR EACH ROW WHEN (new."); + printIdentifier(columnName); + println(" IS NULL)"); + print("BEGIN SELECT "); + printIdentifier(getConstraintName("seq", table, column.getName(), null)); + print(".nextval INTO :new."); + printIdentifier(columnName); + print(" FROM dual"); + print(platform.getPlatformInfo().getSqlCommandDelimiter()); + print(" END"); + // It is important that there is a semicolon at the end of the + // statement (or more + // precisely, at the end of the PL/SQL block), and thus we put two + // semicolons here + // because the tokenizer will remove the one at the end + print(platform.getPlatformInfo().getSqlCommandDelimiter()); + printEndOfStatement(); + } + } + + /* + * Drops the sequence used for the auto-increment of the given column. + * + * @param table The table + * + * @param column The column + */ + protected void dropAutoIncrementSequence(Table table, Column column) { + print("DROP SEQUENCE "); + printIdentifier(getConstraintName("seq", table, column.getName(), null)); + printEndOfStatement(); + } + + /* + * Drops the trigger used for the auto-increment of the given column. + * + * @param table The table + * + * @param column The column + */ + protected void dropAutoIncrementTrigger(Table table, Column column) { + print("DROP TRIGGER "); + printIdentifier(getConstraintName("trg", table, column.getName(), null)); + printEndOfStatement(); + } + + @Override + protected void createTemporaryTable(Database database, Table table) { + createTable(database, table); + } + + @Override + protected void dropTemporaryTable(Database database, Table table) { + dropTable(table); + } + + @Override + public void dropExternalForeignKeys(Table table) { + // no need to as we drop the table with CASCASE CONSTRAINTS + } + + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { + // Index names in Oracle are unique to a schema and hence Oracle does + // not + // use the ON clause + print("DROP INDEX "); + printIdentifier(getIndexName(index)); + printEndOfStatement(); + } + + @Override + protected void printDefaultValue(Object defaultValue, int typeCode) { + if (defaultValue != null) { + String defaultValueStr = defaultValue.toString(); + boolean shouldUseQuotes = !TypeMap.isNumericType(typeCode) + && !defaultValueStr.startsWith("TO_DATE("); + + if (shouldUseQuotes) { + // characters are only escaped when within a string literal + print(platform.getPlatformInfo().getValueQuoteToken()); + print(escapeStringValue(defaultValueStr)); + print(platform.getPlatformInfo().getValueQuoteToken()); + } else { + print(defaultValueStr); + } + } + } + + @Override + protected String getNativeDefaultValue(Column column) { + if ((column.getTypeCode() == Types.BIT) + || (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils + .determineBooleanTypeCode()))) { + return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), + Types.SMALLINT).toString(); + } + // Oracle does not accept ISO formats, so we have to convert an ISO spec + // if we find one + // But these are the only formats that we make sure work, every other + // format has to be database-dependent + // and thus the user has to ensure that it is correct + else if (column.getTypeCode() == Types.DATE) { + if (new Perl5Matcher().matches(column.getDefaultValue(), isoDatePattern)) { + return "TO_DATE('" + column.getDefaultValue() + "', 'YYYY-MM-DD')"; + } + } else if (column.getTypeCode() == Types.TIME) { + if (new Perl5Matcher().matches(column.getDefaultValue(), isoTimePattern)) { + return "TO_DATE('" + column.getDefaultValue() + "', 'HH24:MI:SS')"; + } + } else if (column.getTypeCode() == Types.TIMESTAMP) { + if (new Perl5Matcher().matches(column.getDefaultValue(), isoTimestampPattern)) { + return "TO_DATE('" + column.getDefaultValue() + "', 'YYYY-MM-DD HH24:MI:SS')"; + } + } + return super.getNativeDefaultValue(column); + } + + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { + // we're using sequences instead + } + + @Override + public String getSelectLastIdentityValues(Table table) { + Column[] columns = table.getAutoIncrementColumns(); + + if (columns.length > 0) { + StringBuffer result = new StringBuffer(); + + result.append("SELECT "); + for (int idx = 0; idx < columns.length; idx++) { + if (idx > 0) { + result.append(","); + } + result.append(getDelimitedIdentifier(getConstraintName("seq", table, + columns[idx].getName(), null))); + result.append(".currval"); + } + result.append(" FROM dual"); + return result.toString(); + } else { + return null; + } + } + + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + // While Oracle has an ALTER TABLE MODIFY statement, it is somewhat + // limited + // esp. if there is data in the table, so we don't use it + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; + + // Oracle can only add not insert columns + // Also, we cannot add NOT NULL columns unless they have a + // default value + if (!addColumnChange.isAtEnd() + || (addColumnChange.getNewColumn().isRequired() && (addColumnChange + .getNewColumn().getDefaultValue() == null))) { + // we need to rebuild the full table + return; + } + } + } + + // First we drop primary keys as necessary + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof RemovePrimaryKeyChange) { + processChange(currentModel, desiredModel, (RemovePrimaryKeyChange) change); + changeIt.remove(); + } else if (change instanceof PrimaryKeyChange) { + PrimaryKeyChange pkChange = (PrimaryKeyChange) change; + RemovePrimaryKeyChange removePkChange = new RemovePrimaryKeyChange( + pkChange.getChangedTable(), pkChange.getOldPrimaryKeyColumns()); + + processChange(currentModel, desiredModel, removePkChange); + } + } + + // Next we add/remove columns + // While Oracle has an ALTER TABLE MODIFY statement, it is somewhat + // limited + // esp. if there is data in the table, so we don't use it + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddColumnChange) { + processChange(currentModel, desiredModel, (AddColumnChange) change); + changeIt.remove(); + } else if (change instanceof RemoveColumnChange) { + processChange(currentModel, desiredModel, (RemoveColumnChange) change); + changeIt.remove(); + } + } + // Finally we add primary keys + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); + + if (change instanceof AddPrimaryKeyChange) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); + changeIt.remove(); + } else if (change instanceof PrimaryKeyChange) { + PrimaryKeyChange pkChange = (PrimaryKeyChange) change; + AddPrimaryKeyChange addPkChange = new AddPrimaryKeyChange( + pkChange.getChangedTable(), pkChange.getNewPrimaryKeyColumns()); + + processChange(currentModel, desiredModel, addPkChange); + changeIt.remove(); + } + } + } + + /* + * Processes the addition of a column to a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("ADD "); + writeColumn(change.getChangedTable(), change.getNewColumn()); + printEndOfStatement(); + if (change.getNewColumn().isAutoIncrement()) { + createAutoIncrementSequence(change.getChangedTable(), change.getNewColumn()); + createAutoIncrementTrigger(change.getChangedTable(), change.getNewColumn()); + } + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a column from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { + if (change.getColumn().isAutoIncrement()) { + dropAutoIncrementTrigger(change.getChangedTable(), change.getColumn()); + dropAutoIncrementSequence(change.getChangedTable(), change.getColumn()); + } + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP COLUMN "); + printIdentifier(getColumnName(change.getColumn())); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + + /* + * Processes the removal of a primary key from a table. + * + * @param currentModel The current database schema + * + * @param desiredModel The desired database schema + * + * @param change The change object + */ + protected void processChange(Database currentModel, Database desiredModel, + RemovePrimaryKeyChange change) { + print("ALTER TABLE "); + printlnIdentifier(getTableName(change.getChangedTable())); + printIndent(); + print("DROP PRIMARY KEY"); + printEndOfStatement(); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleModelReader.java new file mode 100644 index 0000000000..a70ae2b347 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OracleModelReader.java @@ -0,0 +1,382 @@ +package org.jumpmind.symmetric.db.platform.oracle; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.oro.text.regex.MalformedPatternException; +import org.apache.oro.text.regex.Pattern; +import org.apache.oro.text.regex.PatternCompiler; +import org.apache.oro.text.regex.PatternMatcher; +import org.apache.oro.text.regex.Perl5Compiler; +import org.apache.oro.text.regex.Perl5Matcher; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * Reads a database model from an Oracle 8 database. + */ +public class OracleModelReader extends JdbcModelReader { + + /* The regular expression pattern for the Oracle conversion of ISO dates. */ + private Pattern oracleIsoDatePattern; + + /* The regular expression pattern for the Oracle conversion of ISO times. */ + private Pattern oracleIsoTimePattern; + + /* + * The regular expression pattern for the Oracle conversion of ISO + * timestamps. + */ + private Pattern oracleIsoTimestampPattern; + + /* + * Creates a new model reader for Oracle 8 databases. + * + * @param platform The platform that this model reader belongs to + */ + public OracleModelReader(IDatabasePlatform platform) { + super(platform); + setDefaultCatalogPattern(null); + setDefaultSchemaPattern(null); + setDefaultTablePattern("%"); + + PatternCompiler compiler = new Perl5Compiler(); + + try { + oracleIsoDatePattern = compiler.compile("TO_DATE\\('([^']*)'\\, 'YYYY\\-MM\\-DD'\\)"); + oracleIsoTimePattern = compiler.compile("TO_DATE\\('([^']*)'\\, 'HH24:MI:SS'\\)"); + oracleIsoTimestampPattern = compiler + .compile("TO_DATE\\('([^']*)'\\, 'YYYY\\-MM\\-DD HH24:MI:SS'\\)"); + } catch (MalformedPatternException ex) { + throw new DdlUtilsException(ex); + } + } + + @Override + protected Table readTable(Connection connection, DatabaseMetaDataWrapper metaData, Map values) + throws SQLException { + // Oracle 10 added the recycle bin which contains dropped database + // objects not yet purged + // Since we don't want entries from the recycle bin, we filter them out + boolean tableHasBeenDeleted = isTableInRecycleBin(connection, values); + + if (!tableHasBeenDeleted) { + String tableName = (String) values.get("TABLE_NAME"); + + // system table ? + if (tableName.indexOf('$') > 0) { + return null; + } + + Table table = super.readTable(connection, metaData, values); + if (table != null) { + determineAutoIncrementColumns(connection, table); + } + + return table; + } else { + return null; + } + } + + protected boolean isTableInRecycleBin(Connection connection, Map values) throws SQLException { + ResultSet rs = null; + PreparedStatement stmt = null; + try { + stmt = connection.prepareStatement("SELECT * FROM RECYCLEBIN WHERE OBJECT_NAME=?"); + stmt.setString(1, (String) values.get("TABLE_NAME")); + + rs = stmt.executeQuery(); + return rs.next(); + } finally { + close(rs); + close(stmt); + } + } + + @Override + protected Integer overrideJdbcTypeForColumn(Map values) { + String typeName = (String) values.get("TYPE_NAME"); + if (typeName != null && typeName.startsWith("DATE")) { + return Types.DATE; + } else if (typeName != null && typeName.startsWith("TIMESTAMP")) { + // This is for Oracle's TIMESTAMP(9) + return Types.TIMESTAMP; + } else if (typeName != null && typeName.startsWith("NVARCHAR")) { + // This is for Oracle's NVARCHAR type + return Types.VARCHAR; + } else if (typeName != null && typeName.startsWith("LONGNVARCHAR")) { + return Types.LONGVARCHAR; + } else if (typeName != null && typeName.startsWith("NCHAR")) { + return Types.CHAR; + } else if (typeName != null && typeName.startsWith("NCLOB")) { + return Types.CLOB; + } else if (typeName != null && typeName.startsWith("BINARY_FLOAT")) { + return Types.FLOAT; + } else if (typeName != null && typeName.startsWith("BINARY_DOUBLE")) { + return Types.DOUBLE; + } else { + return super.overrideJdbcTypeForColumn(values); + } + } + + @Override + protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException { + Column column = super.readColumn(metaData, values); + if (column.getTypeCode() == Types.DECIMAL) { + // We're back-mapping the NUMBER columns returned by Oracle + // Note that the JDBC driver returns DECIMAL for these NUMBER + // columns + switch (column.getSizeAsInt()) { + case 1: + if (column.getScale() == 0) { + column.setTypeCode(Types.BIT); + } + break; + case 3: + if (column.getScale() == 0) { + column.setTypeCode(Types.TINYINT); + } + break; + case 5: + if (column.getScale() == 0) { + column.setTypeCode(Types.SMALLINT); + } + break; + case 18: + column.setTypeCode(Types.REAL); + break; + case 22: + if (column.getScale() == 0) { + column.setTypeCode(Types.INTEGER); + } + break; + case 38: + if (column.getScale() == 0) { + column.setTypeCode(Types.BIGINT); + } else { + column.setTypeCode(Types.DOUBLE); + } + break; + } + } else if (column.getTypeCode() == Types.FLOAT) { + // Same for REAL, FLOAT, DOUBLE PRECISION, which all back-map to + // FLOAT but with + // different sizes (63 for REAL, 126 for FLOAT/DOUBLE PRECISION) + switch (column.getSizeAsInt()) { + case 63: + column.setTypeCode(Types.REAL); + break; + case 126: + column.setTypeCode(Types.DOUBLE); + break; + } + } else if ((column.getTypeCode() == Types.DATE) + || (column.getTypeCode() == Types.TIMESTAMP)) { + // we also reverse the ISO-format adaptation, and adjust the default + // value to timestamp + if (column.getDefaultValue() != null) { + PatternMatcher matcher = new Perl5Matcher(); + Timestamp timestamp = null; + + if (matcher.matches(column.getDefaultValue(), oracleIsoTimestampPattern)) { + String timestampVal = matcher.getMatch().group(1); + + timestamp = Timestamp.valueOf(timestampVal); + } else if (matcher.matches(column.getDefaultValue(), oracleIsoDatePattern)) { + String dateVal = matcher.getMatch().group(1); + + timestamp = new Timestamp(Date.valueOf(dateVal).getTime()); + } else if (matcher.matches(column.getDefaultValue(), oracleIsoTimePattern)) { + String timeVal = matcher.getMatch().group(1); + + timestamp = new Timestamp(Time.valueOf(timeVal).getTime()); + } + if (timestamp != null) { + column.setDefaultValue(timestamp.toString()); + } + } + } else if (TypeMap.isTextType(column.getTypeCode())) { + column.setDefaultValue(unescape(column.getDefaultValue(), "'", "''")); + } + return column; + } + + /* + * Helper method that determines the auto increment status using Firebird's + * system tables. + * + * @param table The table + */ + protected void determineAutoIncrementColumns(Connection connection, Table table) + throws SQLException { + Column[] columns = table.getColumns(); + + for (int idx = 0; idx < columns.length; idx++) { + columns[idx].setAutoIncrement(isAutoIncrement(connection, table, columns[idx])); + } + } + + /* + * Tries to determine whether the given column is an identity column. + * + * @param table The table + * + * @param column The column + * + * @return true if the column is an identity column + */ + protected boolean isAutoIncrement(Connection connection, Table table, Column column) + throws SQLException { + // TODO: For now, we only check whether there is a sequence & trigger as + // generated by DdlUtils + // But once sequence/trigger support is in place, it might be possible + // to 'parse' the + // trigger body (via SELECT trigger_name, trigger_body FROM + // user_triggers) in order to + // determine whether it fits our auto-increment definition + PreparedStatement prepStmt = null; + SqlBuilder builder = getPlatform().createSqlBuilder(null); + String triggerName = builder.getConstraintName("trg", table, column.getName(), null); + String seqName = builder.getConstraintName("seq", table, column.getName(), null); + + if (!getPlatform().isDelimitedIdentifierModeOn()) { + triggerName = triggerName.toUpperCase(); + seqName = seqName.toUpperCase(); + } + try { + prepStmt = connection + .prepareStatement("SELECT * FROM user_triggers WHERE trigger_name = ?"); + prepStmt.setString(1, triggerName); + + ResultSet resultSet = prepStmt.executeQuery(); + + if (!resultSet.next()) { + return false; + } + // we have a trigger, so lets check the sequence + prepStmt.close(); + + prepStmt = connection + .prepareStatement("SELECT * FROM user_sequences WHERE sequence_name = ?"); + prepStmt.setString(1, seqName); + + resultSet = prepStmt.executeQuery(); + return resultSet.next(); + } finally { + if (prepStmt != null) { + prepStmt.close(); + } + } + } + + @Override + protected Collection readIndices(Connection connection, + DatabaseMetaDataWrapper metaData, String tableName) throws SQLException { + // Oracle bug 4999817 causes a table analyze to execute in response to a + // call to + // DatabaseMetaData#getIndexInfo. + // The bug is fixed in driver version 10.2.0.4. The bug is present in at + // least + // driver versions 10.2.0.1.0, 10.1.0.2.0, and 9.2.0.5. + // To avoid this bug, we will access user_indexes view. + // This also allows us to filter system-generated indices which are + // identified by either + // having GENERATED='Y' in the query result, or by their index names + // being equal to the + // name of the primary key of the table + + StringBuilder query = new StringBuilder(); + + query.append("SELECT a.INDEX_NAME, a.INDEX_TYPE, a.UNIQUENESS, b.COLUMN_NAME, b.COLUMN_POSITION FROM USER_INDEXES a, USER_IND_COLUMNS b WHERE "); + query.append("a.TABLE_NAME=? AND a.GENERATED=? AND a.TABLE_TYPE=? AND a.TABLE_NAME=b.TABLE_NAME AND a.INDEX_NAME=b.INDEX_NAME AND "); + query.append("a.INDEX_NAME NOT IN (SELECT DISTINCT c.CONSTRAINT_NAME FROM USER_CONSTRAINTS c WHERE c.CONSTRAINT_TYPE=? AND c.TABLE_NAME=a.TABLE_NAME"); + if (metaData.getSchemaPattern() != null) { + query.append(" AND c.OWNER LIKE ?) AND a.TABLE_OWNER LIKE ?"); + } else { + query.append(")"); + } + + Map indices = new LinkedHashMap(); + PreparedStatement stmt = null; + + try { + stmt = connection.prepareStatement(query.toString()); + stmt.setString( + 1, + getPlatform().isDelimitedIdentifierModeOn() ? tableName : tableName + .toUpperCase()); + stmt.setString(2, "N"); + stmt.setString(3, "TABLE"); + stmt.setString(4, "P"); + if (metaData.getSchemaPattern() != null) { + stmt.setString(5, metaData.getSchemaPattern().toUpperCase()); + stmt.setString(6, metaData.getSchemaPattern().toUpperCase()); + } + + ResultSet rs = stmt.executeQuery(); + Map values = new HashMap(); + + while (rs.next()) { + String name = rs.getString(1); + String type = rs.getString(2); + // Only read in normal oracle indexes + if (type.startsWith("NORMAL")) { + values.put("INDEX_TYPE", new Short(DatabaseMetaData.tableIndexOther)); + values.put("INDEX_NAME", name); + values.put("NON_UNIQUE", + "UNIQUE".equalsIgnoreCase(rs.getString(3)) ? Boolean.FALSE + : Boolean.TRUE); + values.put("COLUMN_NAME", rs.getString(4)); + values.put("ORDINAL_POSITION", new Short(rs.getShort(5))); + + readIndex(metaData, values, indices); + } else { + log.warn("Skipping index " + name + " of type " + type); + } + } + } finally { + if (stmt != null) { + stmt.close(); + } + } + return indices.values(); + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OraclePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OraclePlatform.java new file mode 100644 index 0000000000..c726ca1d1e --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/OraclePlatform.java @@ -0,0 +1,105 @@ +package org.jumpmind.symmetric.db.platform.oracle; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform for Oracle 8. + * + * TODO: We might support the {@link org.jumpmind.symmetric.ddl.Platform#createDatabase(String, String, String, String, Map)} + * functionality via "CREATE SCHEMA"/"CREATE USER" or "CREATE TABLESPACE" ? + * + * @version $Revision: 231306 $ + */ +public class OraclePlatform extends AbstractDatabasePlatform { + /* Database name of this platform. */ + public static final String DATABASENAME = "Oracle"; + /* The standard Oracle jdbc driver. */ + public static final String JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver"; + /* The old Oracle jdbc driver. */ + public static final String JDBC_DRIVER_OLD = "oracle.jdbc.dnlddriver.OracleDriver"; + /* The thin subprotocol used by the standard Oracle driver. */ + public static final String JDBC_SUBPROTOCOL_THIN = "oracle:thin"; + /* The thin subprotocol used by the standard Oracle driver. */ + public static final String JDBC_SUBPROTOCOL_OCI8 = "oracle:oci8"; + /* The old thin subprotocol used by the standard Oracle driver. */ + public static final String JDBC_SUBPROTOCOL_THIN_OLD = "oracle:dnldthin"; + + /* + * Creates a new platform instance. + */ + public OraclePlatform() { + + info.setMaxIdentifierLength(30); + info.setIdentityStatusReadingSupported(false); + + // Note that the back-mappings are partially done by the model reader, + // not the driver + info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.BIGINT, "NUMBER(38)"); + info.addNativeTypeMapping(Types.BINARY, "RAW", Types.VARBINARY); + info.addNativeTypeMapping(Types.BIT, "NUMBER(1)"); + info.addNativeTypeMapping(Types.DATE, "DATE", Types.TIMESTAMP); + info.addNativeTypeMapping(Types.DECIMAL, "NUMBER"); + info.addNativeTypeMapping(Types.DISTINCT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); + info.addNativeTypeMapping(Types.FLOAT, "FLOAT", Types.DOUBLE); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.LONGVARBINARY, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.LONGVARCHAR, "CLOB", Types.CLOB); + info.addNativeTypeMapping(Types.NULL, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.NUMERIC, "NUMBER", Types.DECIMAL); + info.addNativeTypeMapping(Types.INTEGER, "NUMBER(22)", Types.DECIMAL); + info.addNativeTypeMapping(Types.OTHER, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.REF, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.SMALLINT, "NUMBER(5)"); + info.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.BLOB); + info.addNativeTypeMapping(Types.TIME, "DATE", Types.DATE); + info.addNativeTypeMapping(Types.TIMESTAMP, "TIMESTAMP"); + info.addNativeTypeMapping(Types.TINYINT, "NUMBER(3)"); + info.addNativeTypeMapping(Types.VARBINARY, "RAW"); + info.addNativeTypeMapping(Types.VARCHAR, "VARCHAR2"); + + info.addNativeTypeMapping("BOOLEAN", "NUMBER(1)", "BIT"); + info.addNativeTypeMapping("DATALINK", "BLOB", "BLOB"); + + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARCHAR, 254); + info.setDefaultSize(Types.BINARY, 254); + info.setDefaultSize(Types.VARBINARY, 254); + + info.setStoresUpperCaseInCatalog(true); + + modelReader = new OracleModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new OracleBuilder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/oracle/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/oracle/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlBuilder.java similarity index 55% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlBuilder.java index 99de150a82..a8c1743725 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlBuilder.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.postgresql; +package org.jumpmind.symmetric.db.platform.postgresql; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,40 +19,33 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.util.Iterator; import java.util.List; -import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.util.Log; /* * The SQL Builder for PostgresSql. - * - * @version $Revision: 504014 $ */ -public class PostgreSqlBuilder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public PostgreSqlBuilder(Platform platform) - { - super(platform); +public class PostgreSqlBuilder extends SqlBuilder { + + public PostgreSqlBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + // we need to handle the backslash first otherwise the other // already escaped sequences would be affected addEscapedCharSequence("\\", "\\\\"); - addEscapedCharSequence("'", "\\'"); + addEscapedCharSequence("'", "\\'"); addEscapedCharSequence("\b", "\\b"); addEscapedCharSequence("\f", "\\f"); addEscapedCharSequence("\n", "\\n"); @@ -60,11 +53,8 @@ public PostgreSqlBuilder(Platform platform) addEscapedCharSequence("\t", "\\t"); } - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { + @Override + public void dropTable(Table table) { print("DROP TABLE "); printIdentifier(getTableName(table)); print(" CASCADE"); @@ -72,47 +62,38 @@ public void dropTable(Table table) throws IOException Column[] columns = table.getAutoIncrementColumns(); - for (int idx = 0; idx < columns.length; idx++) - { + for (int idx = 0; idx < columns.length; idx++) { dropAutoIncrementSequence(table, columns[idx]); } } - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { print("DROP INDEX "); printIdentifier(getIndexName(index)); printEndOfStatement(); } - /* - * {@inheritDoc} - */ - public void createTable(Database database, Table table, Map parameters) throws IOException - { - for (int idx = 0; idx < table.getColumnCount(); idx++) - { + @Override + public void createTable(Database database, Table table) { + for (int idx = 0; idx < table.getColumnCount(); idx++) { Column column = table.getColumn(idx); - if (column.isAutoIncrement()) - { + if (column.isAutoIncrement()) { createAutoIncrementSequence(table, column); } } - super.createTable(database, table, parameters); + super.createTable(database, table); } /* * Creates the auto-increment sequence that is then used in the column. - * - * @param table The table + * + * @param table The table + * * @param column The column */ - private void createAutoIncrementSequence(Table table, Column column) throws IOException - { + private void createAutoIncrementSequence(Table table, Column column) { print("CREATE SEQUENCE "); printIdentifier(getConstraintName(null, table, column.getName(), "seq")); printEndOfStatement(); @@ -120,51 +101,41 @@ private void createAutoIncrementSequence(Table table, Column column) throws IOEx /* * Creates the auto-increment sequence that is then used in the column. - * - * @param table The table + * + * @param table The table + * * @param column The column */ - private void dropAutoIncrementSequence(Table table, Column column) throws IOException - { + private void dropAutoIncrementSequence(Table table, Column column) { print("DROP SEQUENCE "); printIdentifier(getConstraintName(null, table, column.getName(), "seq")); printEndOfStatement(); } - /* - * {@inheritDoc} - */ - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException - { + @Override + protected void writeColumnAutoIncrementStmt(Table table, Column column) { print(" DEFAULT nextval('"); printIdentifier(getConstraintName(null, table, column.getName(), "seq")); print("')"); } - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { + @Override + public String getSelectLastIdentityValues(Table table) { Column[] columns = table.getAutoIncrementColumns(); - if (columns.length == 0) - { + if (columns.length == 0) { return null; - } - else - { + } else { StringBuffer result = new StringBuffer(); - + result.append("SELECT "); - for (int idx = 0; idx < columns.length; idx++) - { - if (idx > 0) - { + for (int idx = 0; idx < columns.length; idx++) { + if (idx > 0) { result.append(", "); } result.append("currval('"); - result.append(getDelimitedIdentifier(getConstraintName(null, table, columns[idx].getName(), "seq"))); + result.append(getDelimitedIdentifier(getConstraintName(null, table, + columns[idx].getName(), "seq"))); result.append("') AS "); result.append(getDelimitedIdentifier(columns[idx].getName())); } @@ -172,90 +143,82 @@ public String getSelectLastIdentityValues(Table table) } } - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = changeIt.next(); - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; // We can only use PostgreSQL-specific SQL if - // * the column is not set to NOT NULL (the constraint would be applied immediately - // which will not work if there is already data in the table) - // * the column has no default value (it would be applied after the change which - // means that PostgreSQL would behave differently from other databases where the - // default is applied to every column) - // * the column is added at the end of the table (PostgreSQL does not support - // insertion of a column) - if (!addColumnChange.getNewColumn().isRequired() && - (addColumnChange.getNewColumn().getDefaultValue() == null) && - (addColumnChange.getNextColumn() == null)) - { + // * the column is not set to NOT NULL (the constraint would be + // applied immediately + // which will not work if there is already data in the table) + // * the column has no default value (it would be applied after + // the change which + // means that PostgreSQL would behave differently from other + // databases where the + // default is applied to every column) + // * the column is added at the end of the table (PostgreSQL + // does not support + // insertion of a column) + if (!addColumnChange.getNewColumn().isRequired() + && (addColumnChange.getNewColumn().getDefaultValue() == null) + && (addColumnChange.getNextColumn() == null)) { processChange(currentModel, desiredModel, addColumnChange); changeIt.remove(); } - } - else if (change instanceof RemoveColumnChange) - { - processChange(currentModel, desiredModel, (RemoveColumnChange)change); + } else if (change instanceof RemoveColumnChange) { + processChange(currentModel, desiredModel, (RemoveColumnChange) change); changeIt.remove(); } } - super.processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, parameters, changes); + super.processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, + changes); } /* * Processes the addition of a column to a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("ADD COLUMN "); writeColumn(change.getChangedTable(), change.getNewColumn()); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a column from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("DROP COLUMN "); printIdentifier(getColumnName(change.getColumn())); printEndOfStatement(); - if (change.getColumn().isAutoIncrement()) - { + if (change.getColumn().isAutoIncrement()) { dropAutoIncrementSequence(change.getChangedTable(), change.getColumn()); } - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlModelReader.java similarity index 91% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlModelReader.java index 65e467c415..69d393b454 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/PostgreSqlModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.postgresql; +package org.jumpmind.symmetric.db.platform.postgresql; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -25,14 +25,14 @@ import java.util.HashMap; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a PostgreSql database. @@ -46,7 +46,7 @@ public class PostgreSqlModelReader extends JdbcModelReader * * @param platform The platform that this model reader belongs to */ - public PostgreSqlModelReader(Platform platform) + public PostgreSqlModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlPlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlPlatform.java new file mode 100644 index 0000000000..63daf0e1f7 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/PostgreSqlPlatform.java @@ -0,0 +1,92 @@ +package org.jumpmind.symmetric.db.platform.postgresql; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for PostgresSql. + */ +public class PostgreSqlPlatform extends AbstractDatabasePlatform { + /* Database name of this platform. */ + public static final String DATABASENAME = "PostgreSql"; + /* The standard PostgreSQL jdbc driver. */ + public static final String JDBC_DRIVER = "org.postgresql.Driver"; + /* The subprotocol used by the standard PostgreSQL driver. */ + public static final String JDBC_SUBPROTOCOL = "postgresql"; + + /* + * Creates a new platform instance. + */ + public PostgreSqlPlatform() { + + // this is the default length though it might be changed when building + // PostgreSQL + // in file src/include/postgres_ext.h + info.setMaxIdentifierLength(31); + + info.addNativeTypeMapping(Types.ARRAY, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.BINARY, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.BIT, "BOOLEAN"); + info.addNativeTypeMapping(Types.BLOB, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.CLOB, "TEXT", Types.LONGVARCHAR); + info.addNativeTypeMapping(Types.DECIMAL, "NUMERIC", Types.NUMERIC); + info.addNativeTypeMapping(Types.DISTINCT, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE PRECISION", Types.DOUBLE); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.LONGVARBINARY, "BYTEA"); + info.addNativeTypeMapping(Types.LONGVARCHAR, "TEXT", Types.LONGVARCHAR); + info.addNativeTypeMapping(Types.NULL, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.OTHER, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.REF, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.VARBINARY, "BYTEA", Types.LONGVARBINARY); + info.addNativeTypeMapping("BOOLEAN", "BOOLEAN", "BIT"); + info.addNativeTypeMapping("DATALINK", "BYTEA", "LONGVARBINARY"); + + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARCHAR, 254); + + // no support for specifying the size for these types (because they are + // mapped + // to BYTEA which back-maps to BLOB) + info.setHasSize(Types.BINARY, false); + info.setHasSize(Types.VARBINARY, false); + + setDelimitedIdentifierModeOn(true); + + modelReader = new PostgreSqlModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new PostgreSqlBuilder(log, this, writer); + } + + public String getName() { + return DATABASENAME; + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/postgresql/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/postgresql/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLiteBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLiteBuilder.java similarity index 80% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLiteBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLiteBuilder.java index 3c6ed1f522..8566f81267 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLiteBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLiteBuilder.java @@ -3,7 +3,7 @@ * and open the template in the editor. */ -package org.jumpmind.symmetric.db.ddl.platform.sqlite; +package org.jumpmind.symmetric.db.platform.sqlite; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -24,7 +24,7 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.sql.Types; import java.util.ArrayList; import java.util.Collection; @@ -32,52 +32,47 @@ import java.util.ListIterator; import org.apache.commons.lang.StringUtils; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDataTypeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnRequiredChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnSizeChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.ModelException; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.CreationParameters; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.ColumnChange; +import org.jumpmind.symmetric.db.alter.ColumnDataTypeChange; +import org.jumpmind.symmetric.db.alter.ColumnRequiredChange; +import org.jumpmind.symmetric.db.alter.ColumnSizeChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.ModelException; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.util.Log; /* - * The SQL Builder for the H2 database. From patch https://issues.apache.org/jira/browse/DDLUTILS-185 - * - * @version $Revision: 518485 $ + * The SQL Builder for the SqlLite database. */ public class SqLiteBuilder extends SqlBuilder { - + + public SqLiteBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); + + addEscapedCharSequence("'", "''"); + } @Override - public void dropTable(Table table) throws IOException { + public void dropTable(Table table) { print("DROP TABLE IF EXISTS "); printIdentifier(getTableName(table)); printEndOfStatement(); } - protected void writeColumnAutoIncrementStmt(Table table, Column column) throws IOException + protected void writeColumnAutoIncrementStmt(Table table, Column column) { if (!column.isPrimaryKey()){ print("PRIMARY KEY AUTOINCREMENT"); } } - - public SqLiteBuilder(Platform platform) { - super(platform); - addEscapedCharSequence("'", "''"); - } - @Override public String getSelectLastIdentityValues(Table table) { @@ -85,7 +80,7 @@ public String getSelectLastIdentityValues(Table table) { } @Override - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException { + public void writeExternalIndexDropStmt(Table table, Index index) { print("DROP INDEX IF EXISTS "); printIdentifier(getIndexName(index)); printEndOfStatement(); @@ -94,9 +89,9 @@ public void writeExternalIndexDropStmt(Table table, Index index) throws IOExcept @Override @SuppressWarnings("unchecked") protected void processTableStructureChanges(Database currentModel, Database desiredModel, - CreationParameters params, Collection changes) throws IOException { + Collection changes) { // Only drop columns that are not part of a primary key - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { TableChange change = (TableChange) changeIt.next(); if ((change instanceof RemoveColumnChange) && ((RemoveColumnChange) change).getColumn().isPrimaryKey()) { @@ -171,8 +166,8 @@ protected void processTableStructureChanges(Database currentModel, Database desi } - protected void processAlterColumn(Database currentModel, ColumnChange columnChange) throws IOException { - columnChange.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + protected void processAlterColumn(Database currentModel, ColumnChange columnChange) { + columnChange.apply(currentModel, platform.isDelimitedIdentifierModeOn()); print("ALTER TABLE "); printlnIdentifier(getTableName(columnChange.getChangedTable())); printIndent(); @@ -203,7 +198,7 @@ protected void processAlterColumn(Database currentModel, ColumnChange columnChan * The change object */ protected void processChange(Database currentModel, Database desiredModel, AddColumnChange change) - throws IOException { + { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); @@ -214,7 +209,7 @@ protected void processChange(Database currentModel, Database desiredModel, AddCo printIdentifier(getColumnName(change.getNextColumn())); } printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* @@ -228,22 +223,22 @@ protected void processChange(Database currentModel, Database desiredModel, AddCo * The change object */ protected void processChange(Database currentModel, Database desiredModel, RemoveColumnChange change) - throws IOException { + { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("DROP COLUMN "); printIdentifier(getColumnName(change.getColumn())); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } @Override - protected void writeColumnDefaultValueStmt(Table table, Column column) throws IOException { + protected void writeColumnDefaultValueStmt(Table table, Column column) { Object parsedDefault = column.getParsedDefaultValue(); if (parsedDefault != null) { - if (!getPlatformInfo().isDefaultValuesForLongTypesSupported() + if (!platform.getPlatformInfo().isDefaultValuesForLongTypesSupported() && ((column.getTypeCode() == Types.LONGVARBINARY) || (column.getTypeCode() == Types.LONGVARCHAR))) { throw new ModelException( "The platform does not support default values for LONGVARCHAR or LONGVARBINARY columns"); @@ -254,7 +249,7 @@ protected void writeColumnDefaultValueStmt(Table table, Column column) throws IO print(" DEFAULT "); writeColumnDefaultValue(table, column); } - } else if (getPlatformInfo().isDefaultValueUsedForIdentitySpec() && column.isAutoIncrement()) { + } else if (platform.getPlatformInfo().isDefaultValueUsedForIdentitySpec() && column.isAutoIncrement()) { print(" DEFAULT "); writeColumnDefaultValue(table, column); } else if (!StringUtils.isBlank(column.getDefaultValue())) { @@ -264,7 +259,7 @@ protected void writeColumnDefaultValueStmt(Table table, Column column) throws IO } @Override - protected void printDefaultValue(Object defaultValue, int typeCode) throws IOException { + protected void printDefaultValue(Object defaultValue, int typeCode) { if (defaultValue != null) { String defaultValueStr = defaultValue.toString(); boolean shouldUseQuotes = !TypeMap.isNumericType(typeCode) && !defaultValueStr.startsWith("TO_DATE(") @@ -274,9 +269,9 @@ protected void printDefaultValue(Object defaultValue, int typeCode) throws IOExc if (shouldUseQuotes) { // characters are only escaped when within a string literal - print(getPlatformInfo().getValueQuoteToken()); + print(platform.getPlatformInfo().getValueQuoteToken()); print(escapeStringValue(defaultValueStr)); - print(getPlatformInfo().getValueQuoteToken()); + print(platform.getPlatformInfo().getValueQuoteToken()); } else { print(defaultValueStr); } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLiteModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLiteModelReader.java similarity index 84% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLiteModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLiteModelReader.java index 682e568bd9..24982465f5 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLiteModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLiteModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.sqlite; +package org.jumpmind.symmetric.db.platform.sqlite; import java.sql.Connection; import java.sql.SQLException; @@ -7,15 +7,15 @@ import java.util.List; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; -import org.jumpmind.symmetric.db.ddl.platform.MetaDataColumnDescriptor; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.platform.MetaDataColumnDescriptor; /* * Reads a database model from a SQLite database. @@ -28,7 +28,7 @@ public class SqLiteModelReader extends JdbcModelReader { * @param platform * The platform that this model reader belongs to */ - public SqLiteModelReader(Platform platform) { + public SqLiteModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); setDefaultSchemaPattern(null); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLitePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLitePlatform.java similarity index 79% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLitePlatform.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLitePlatform.java index 1fd85e51e8..f025fc9fbe 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sqlite/SqLitePlatform.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sqlite/SqLitePlatform.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.sqlite; +package org.jumpmind.symmetric.db.platform.sqlite; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,35 +19,28 @@ * under the License. */ +import java.io.Writer; import java.sql.Types; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; /* * The platform implementation for the SQLite database. - * - * @version $Revision: 231306 $ */ -public class SqLitePlatform extends PlatformImplBase implements Platform { +public class SqLitePlatform extends AbstractDatabasePlatform implements IDatabasePlatform { /* Database name of this platform. */ public static final String DATABASENAME = "SQLite3"; - + /* The standard H2 driver. */ public static final String JDBC_DRIVER = "org.sqlite.JDBC"; - - /* The sub protocol used by the H2 driver. */ - // public static final String JDBC_SUBPROTOCOL = "h2"; - /* Below here copied from H2. May still need tweaking */ - /* * Creates a new instance of the H2 platform. */ public SqLitePlatform() { - PlatformInfo info = getPlatformInfo(); info.setNonPKIdentityColumnsSupported(false); info.setIdentityOverrideAllowed(false); @@ -74,13 +67,13 @@ public SqLitePlatform() { info.setDefaultSize(Types.BINARY, Integer.MAX_VALUE); info.setDefaultSize(Types.VARBINARY, Integer.MAX_VALUE); - setSqlBuilder(new SqLiteBuilder(this)); - setModelReader(new SqLiteModelReader(this)); + modelReader = new SqLiteModelReader(this); + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new SqLiteBuilder(log, this, writer); } - /* - * {@inheritDoc} - */ public String getName() { return DATABASENAME; } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseBuilder.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybaseBuilder.java similarity index 50% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseBuilder.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybaseBuilder.java index dbea7fca97..9219c79af2 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseBuilder.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybaseBuilder.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.sybase; +package org.jumpmind.symmetric.db.platform.sybase; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,7 @@ * under the License. */ -import java.io.IOException; +import java.io.Writer; import java.sql.Types; import java.util.ArrayList; import java.util.HashMap; @@ -27,175 +27,77 @@ import java.util.List; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnAutoIncrementChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDefaultValueChange; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.TableChange; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.CreationParameters; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.jumpmind.symmetric.db.ddl.util.Jdbc3Utils; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.alter.AddColumnChange; +import org.jumpmind.symmetric.db.alter.AddPrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.ColumnAutoIncrementChange; +import org.jumpmind.symmetric.db.alter.ColumnChange; +import org.jumpmind.symmetric.db.alter.ColumnDefaultValueChange; +import org.jumpmind.symmetric.db.alter.IModelChange; +import org.jumpmind.symmetric.db.alter.PrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.RemoveColumnChange; +import org.jumpmind.symmetric.db.alter.RemovePrimaryKeyChange; +import org.jumpmind.symmetric.db.alter.TableChange; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.util.Jdbc3Utils; +import org.jumpmind.symmetric.util.Log; /* * The SQL Builder for Sybase. - * - * @version $Revision: 532976 $ */ -public class SybaseBuilder extends SqlBuilder -{ - /* - * Creates a new builder instance. - * - * @param platform The plaftform this builder belongs to - */ - public SybaseBuilder(Platform platform) - { - super(platform); +public class SybaseBuilder extends SqlBuilder { + + public SybaseBuilder(Log log, IDatabasePlatform platform, Writer writer) { + super(log, platform, writer); addEscapedCharSequence("'", "''"); } - /* - * {@inheritDoc} - */ - public void createTable(Database database, Table table, Map parameters) throws IOException - { + @Override + public void createTable(Database database, Table table) { writeQuotationOnStatement(); - super.createTable(database, table, parameters); + super.createTable(database, table); } - /* - * {@inheritDoc} - */ - protected void writeTableCreationStmtEnding(Table table, Map parameters) throws IOException - { - if (parameters != null) - { - // We support - // - 'lock' - // - 'at' - // - 'external table at' - // - 'on' - // - with parameters as name value pairs - - String lockValue = (String)parameters.get("lock"); - String atValue = (String)parameters.get("at"); - String externalTableAtValue = (String)parameters.get("external table at"); - String onValue = (String)parameters.get("on"); - - if (lockValue != null) - { - print(" lock "); - print(lockValue); - } - - boolean writtenWithParameters = false; - - for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - String name = entry.getKey().toString(); - - if (!"lock".equals(name) && !"at".equals(name) && !"external table at".equals(name) && !"on".equals(name)) - { - if (!writtenWithParameters) - { - print(" with "); - writtenWithParameters = true; - } - else - { - print(", "); - } - print(name); - if (entry.getValue() != null) - { - print("="); - print(entry.getValue().toString()); - } - } - } - if (onValue != null) - { - print(" on "); - print(onValue); - } - if (externalTableAtValue != null) - { - print(" external table at \""); - print(externalTableAtValue); - print("\""); - } - else if (atValue != null) - { - print(" at \""); - print(atValue); - print("\""); - } - } - super.writeTableCreationStmtEnding(table, parameters); - } - - /* - * {@inheritDoc} - */ - protected void writeColumn(Table table, Column column) throws IOException - { + @Override + protected void writeColumn(Table table, Column column) { printIdentifier(getColumnName(column)); print(" "); print(getSqlType(column)); writeColumnDefaultValueStmt(table, column); // Sybase does not like NULL/NOT NULL and IDENTITY together - if (column.isAutoIncrement()) - { + if (column.isAutoIncrement()) { print(" "); writeColumnAutoIncrementStmt(table, column); - } - else - { + } else { print(" "); - if (column.isRequired()) - { + if (column.isRequired()) { writeColumnNotNullableStmt(); - } - else - { - // we'll write a NULL for all columns that are not required + } else { + // we'll write a NULL for all columns that are not required writeColumnNullableStmt(); } } - } + } - /* - * {@inheritDoc} - */ - protected String getNativeDefaultValue(Column column) - { - if ((column.getTypeCode() == Types.BIT) || - (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils.determineBooleanTypeCode()))) - { - return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), Types.SMALLINT).toString(); - } - else - { + @Override + protected String getNativeDefaultValue(Column column) { + if ((column.getTypeCode() == Types.BIT) + || (Jdbc3Utils.supportsJava14JdbcTypes() && (column.getTypeCode() == Jdbc3Utils + .determineBooleanTypeCode()))) { + return getDefaultValueHelper().convert(column.getDefaultValue(), column.getTypeCode(), + Types.SMALLINT).toString(); + } else { return super.getNativeDefaultValue(column); } } - /* - * {@inheritDoc} - */ - public void dropTable(Table table) throws IOException - { + @Override + public void dropTable(Table table) { writeQuotationOnStatement(); print("IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = "); printAlwaysSingleQuotedIdentifier(getTableName(table)); @@ -208,11 +110,9 @@ public void dropTable(Table table) throws IOException printEndOfStatement(); } - /* - * {@inheritDoc} - */ - protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) throws IOException - { + @Override + protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) + { String constraintName = getForeignKeyName(table, foreignKey); print("IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'RI' AND name = "); @@ -226,11 +126,8 @@ protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKe printEndOfStatement(); } - /* - * {@inheritDoc} - */ - public void writeExternalIndexDropStmt(Table table, Index index) throws IOException - { + @Override + public void writeExternalIndexDropStmt(Table table, Index index) { print("DROP INDEX "); printIdentifier(getTableName(table)); print("."); @@ -238,20 +135,14 @@ public void writeExternalIndexDropStmt(Table table, Index index) throws IOExcept printEndOfStatement(); } - /* - * {@inheritDoc} - */ - public void dropExternalForeignKeys(Table table) throws IOException - { + @Override + public void dropExternalForeignKeys(Table table) { writeQuotationOnStatement(); super.dropExternalForeignKeys(table); } - /* - * {@inheritDoc} - */ - public String getSelectLastIdentityValues(Table table) - { + @Override + public String getSelectLastIdentityValues(Table table) { return "SELECT @@IDENTITY"; } @@ -259,10 +150,10 @@ public String getSelectLastIdentityValues(Table table) * Returns the SQL to enable identity override mode. * * @param table The table to enable the mode for + * * @return The SQL */ - protected String getEnableIdentityOverrideSql(Table table) - { + protected String getEnableIdentityOverrideSql(Table table) { StringBuffer result = new StringBuffer(); result.append("SET IDENTITY_INSERT "); @@ -276,10 +167,10 @@ protected String getEnableIdentityOverrideSql(Table table) * Returns the SQL to disable identity override mode. * * @param table The table to disable the mode for + * * @return The SQL */ - protected String getDisableIdentityOverrideSql(Table table) - { + protected String getDisableIdentityOverrideSql(Table table) { StringBuffer result = new StringBuffer(); result.append("SET IDENTITY_INSERT "); @@ -290,39 +181,35 @@ protected String getDisableIdentityOverrideSql(Table table) } /* - * Returns the statement that turns on the ability to write delimited identifiers. + * Returns the statement that turns on the ability to write delimited + * identifiers. * * @return The quotation-on statement */ - protected String getQuotationOnStatement() - { - if (getPlatform().isDelimitedIdentifierModeOn()) - { + protected String getQuotationOnStatement() { + if (platform.isDelimitedIdentifierModeOn()) { return "SET quoted_identifier on"; - } - else - { + } else { return ""; } } /* - * Writes the statement that turns on the ability to write delimited identifiers. + * Writes the statement that turns on the ability to write delimited + * identifiers. */ - private void writeQuotationOnStatement() throws IOException - { + private void writeQuotationOnStatement() { print(getQuotationOnStatement()); printEndOfStatement(); } /* - * Prints the given identifier with enforced single quotes around it regardless of whether - * delimited identifiers are turned on or not. + * Prints the given identifier with enforced single quotes around it + * regardless of whether delimited identifiers are turned on or not. * * @param identifier The identifier */ - private void printAlwaysSingleQuotedIdentifier(String identifier) throws IOException - { + private void printAlwaysSingleQuotedIdentifier(String identifier) { print("'"); print(identifier); print("'"); @@ -331,20 +218,17 @@ private void printAlwaysSingleQuotedIdentifier(String identifier) throws IOExcep /* * {@inheritDoc} */ - public void writeCopyDataStatement(Table sourceTable, Table targetTable) throws IOException - { + public void writeCopyDataStatement(Table sourceTable, Table targetTable) { boolean hasIdentity = targetTable.getAutoIncrementColumns().length > 0; - if (hasIdentity) - { + if (hasIdentity) { print("SET IDENTITY_INSERT "); printIdentifier(getTableName(targetTable)); print(" ON"); printEndOfStatement(); } super.writeCopyDataStatement(sourceTable, targetTable); - if (hasIdentity) - { + if (hasIdentity) { print("SET IDENTITY_INSERT "); printIdentifier(getTableName(targetTable)); print(" OFF"); @@ -355,17 +239,13 @@ public void writeCopyDataStatement(Table sourceTable, Table targetTable) throws /* * {@inheritDoc} */ - protected void writeCastExpression(Column sourceColumn, Column targetColumn) throws IOException - { + protected void writeCastExpression(Column sourceColumn, Column targetColumn) { String sourceNativeType = getBareNativeType(sourceColumn); String targetNativeType = getBareNativeType(targetColumn); - if (sourceNativeType.equals(targetNativeType)) - { + if (sourceNativeType.equals(targetNativeType)) { printIdentifier(getColumnName(sourceColumn)); - } - else - { + } else { print("CONVERT("); print(getNativeType(targetColumn)); print(","); @@ -374,139 +254,113 @@ protected void writeCastExpression(Column sourceColumn, Column targetColumn) thr } } - /* - * {@inheritDoc} - */ - protected void processChanges(Database currentModel, Database desiredModel, List changes, CreationParameters params) throws IOException - { - if (!changes.isEmpty()) - { + @Override + protected void processChanges(Database currentModel, Database desiredModel, + List changes) { + if (!changes.isEmpty()) { writeQuotationOnStatement(); } - super.processChanges(currentModel, desiredModel, changes, params); + super.processChanges(currentModel, desiredModel, changes); } - /* - * {@inheritDoc} - */ - protected void processTableStructureChanges(Database currentModel, - Database desiredModel, - Table sourceTable, - Table targetTable, - Map parameters, - List changes) throws IOException - { + @Override + protected void processTableStructureChanges(Database currentModel, Database desiredModel, + Table sourceTable, Table targetTable, List changes) { // First we drop primary keys as necessary - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = (TableChange) changeIt.next(); - if (change instanceof RemovePrimaryKeyChange) - { - processChange(currentModel, desiredModel, (RemovePrimaryKeyChange)change); + if (change instanceof RemovePrimaryKeyChange) { + processChange(currentModel, desiredModel, (RemovePrimaryKeyChange) change); changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - PrimaryKeyChange pkChange = (PrimaryKeyChange)change; - RemovePrimaryKeyChange removePkChange = new RemovePrimaryKeyChange(pkChange.getChangedTable(), - pkChange.getOldPrimaryKeyColumns()); + } else if (change instanceof PrimaryKeyChange) { + PrimaryKeyChange pkChange = (PrimaryKeyChange) change; + RemovePrimaryKeyChange removePkChange = new RemovePrimaryKeyChange( + pkChange.getChangedTable(), pkChange.getOldPrimaryKeyColumns()); processChange(currentModel, desiredModel, removePkChange); } } - HashMap columnChanges = new HashMap(); // Next we add/remove columns - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = (TableChange) changeIt.next(); - if (change instanceof AddColumnChange) - { - AddColumnChange addColumnChange = (AddColumnChange)change; + if (change instanceof AddColumnChange) { + AddColumnChange addColumnChange = (AddColumnChange) change; // Sybase can only add not insert columns - if (addColumnChange.isAtEnd()) - { + if (addColumnChange.isAtEnd()) { processChange(currentModel, desiredModel, addColumnChange); changeIt.remove(); } - } - else if (change instanceof RemoveColumnChange) - { - processChange(currentModel, desiredModel, (RemoveColumnChange)change); + } else if (change instanceof RemoveColumnChange) { + processChange(currentModel, desiredModel, (RemoveColumnChange) change); changeIt.remove(); - } - else if (change instanceof ColumnAutoIncrementChange) - { - // Sybase has no way of adding or removing an IDENTITY constraint - // Thus we have to rebuild the table anyway and can ignore all the other + } else if (change instanceof ColumnAutoIncrementChange) { + // Sybase has no way of adding or removing an IDENTITY + // constraint + // Thus we have to rebuild the table anyway and can ignore all + // the other // column changes columnChanges = null; - } - else if ((change instanceof ColumnChange) && (columnChanges != null)) - { - // we gather all changed columns because we can use the ALTER TABLE ALTER COLUMN + } else if ((change instanceof ColumnChange) && (columnChanges != null)) { + // we gather all changed columns because we can use the ALTER + // TABLE ALTER COLUMN // statement for them - ColumnChange columnChange = (ColumnChange)change; - ArrayList changesPerColumn = (ArrayList)columnChanges.get(columnChange.getChangedColumn()); + ColumnChange columnChange = (ColumnChange) change; + ArrayList changesPerColumn = (ArrayList) columnChanges.get(columnChange + .getChangedColumn()); - if (changesPerColumn == null) - { + if (changesPerColumn == null) { changesPerColumn = new ArrayList(); columnChanges.put(columnChange.getChangedColumn(), changesPerColumn); } changesPerColumn.add(change); } } - if (columnChanges != null) - { - for (Iterator changesPerColumnIt = columnChanges.entrySet().iterator(); changesPerColumnIt.hasNext();) - { - Map.Entry entry = (Map.Entry)changesPerColumnIt.next(); - Column sourceColumn = (Column)entry.getKey(); - ArrayList changesPerColumn = (ArrayList)entry.getValue(); - - // Sybase does not like us to use the ALTER TABLE ALTER statement if we don't actually - // change the datatype or the required constraint but only the default value - // Thus, if we only have to change the default, we use a different handler - if ((changesPerColumn.size() == 1) && (changesPerColumn.get(0) instanceof ColumnDefaultValueChange)) - { - processChange(currentModel, - desiredModel, - (ColumnDefaultValueChange)changesPerColumn.get(0)); - } - else - { + if (columnChanges != null) { + for (Iterator changesPerColumnIt = columnChanges.entrySet().iterator(); changesPerColumnIt + .hasNext();) { + Map.Entry entry = (Map.Entry) changesPerColumnIt.next(); + Column sourceColumn = (Column) entry.getKey(); + ArrayList changesPerColumn = (ArrayList) entry.getValue(); + + // Sybase does not like us to use the ALTER TABLE ALTER + // statement if we don't actually + // change the datatype or the required constraint but only the + // default value + // Thus, if we only have to change the default, we use a + // different handler + if ((changesPerColumn.size() == 1) + && (changesPerColumn.get(0) instanceof ColumnDefaultValueChange)) { + processChange(currentModel, desiredModel, + (ColumnDefaultValueChange) changesPerColumn.get(0)); + } else { Column targetColumn = targetTable.findColumn(sourceColumn.getName(), - getPlatform().isDelimitedIdentifierModeOn()); + platform.isDelimitedIdentifierModeOn()); processColumnChange(sourceTable, targetTable, sourceColumn, targetColumn); } - for (Iterator changeIt = changesPerColumn.iterator(); changeIt.hasNext();) - { - ((ColumnChange)changeIt.next()).apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + for (Iterator changeIt = changesPerColumn.iterator(); changeIt.hasNext();) { + ((ColumnChange) changeIt.next()).apply(currentModel, + platform.isDelimitedIdentifierModeOn()); } } } // Finally we add primary keys - for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) - { - TableChange change = (TableChange)changeIt.next(); + for (Iterator changeIt = changes.iterator(); changeIt.hasNext();) { + TableChange change = (TableChange) changeIt.next(); - if (change instanceof AddPrimaryKeyChange) - { - processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change); + if (change instanceof AddPrimaryKeyChange) { + processChange(currentModel, desiredModel, (AddPrimaryKeyChange) change); changeIt.remove(); - } - else if (change instanceof PrimaryKeyChange) - { - PrimaryKeyChange pkChange = (PrimaryKeyChange)change; - AddPrimaryKeyChange addPkChange = new AddPrimaryKeyChange(pkChange.getChangedTable(), - pkChange.getNewPrimaryKeyColumns()); + } else if (change instanceof PrimaryKeyChange) { + PrimaryKeyChange pkChange = (PrimaryKeyChange) change; + AddPrimaryKeyChange addPkChange = new AddPrimaryKeyChange( + pkChange.getChangedTable(), pkChange.getNewPrimaryKeyColumns()); processChange(currentModel, desiredModel, addPkChange); changeIt.remove(); @@ -514,146 +368,147 @@ else if (change instanceof PrimaryKeyChange) } } - /* * Processes the addition of a column to a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - AddColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + AddColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("ADD "); writeColumn(change.getChangedTable(), change.getNewColumn()); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a column from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemoveColumnChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + RemoveColumnChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("DROP "); printIdentifier(getColumnName(change.getColumn())); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes the removal of a primary key from a table. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - RemovePrimaryKeyChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + RemovePrimaryKeyChange change) { // TODO: this would be easier when named primary keys are supported - // because then we can use ALTER TABLE DROP - String tableName = getTableName(change.getChangedTable()); - String tableNameVar = "tn" + createUniqueIdentifier(); + // because then we can use ALTER TABLE DROP + String tableName = getTableName(change.getChangedTable()); + String tableNameVar = "tn" + createUniqueIdentifier(); String constraintNameVar = "cn" + createUniqueIdentifier(); println("BEGIN"); - println(" DECLARE @" + tableNameVar + " nvarchar(60), @" + constraintNameVar + " nvarchar(60)"); + println(" DECLARE @" + tableNameVar + " nvarchar(60), @" + constraintNameVar + + " nvarchar(60)"); println(" WHILE EXISTS(SELECT sysindexes.name"); println(" FROM sysindexes, sysobjects"); print(" WHERE sysobjects.name = "); printAlwaysSingleQuotedIdentifier(tableName); println(" AND sysobjects.id = sysindexes.id AND (sysindexes.status & 2048) > 0)"); println(" BEGIN"); - println(" SELECT @" + tableNameVar + " = sysobjects.name, @" + constraintNameVar + " = sysindexes.name"); + println(" SELECT @" + tableNameVar + " = sysobjects.name, @" + constraintNameVar + + " = sysindexes.name"); println(" FROM sysindexes, sysobjects"); print(" WHERE sysobjects.name = "); printAlwaysSingleQuotedIdentifier(tableName); print(" AND sysobjects.id = sysindexes.id AND (sysindexes.status & 2048) > 0"); - println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")"); + println(" EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + + constraintNameVar + ")"); println(" END"); print("END"); printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* - * Processes the change of the default value of a column. Note that this method is only - * used if it is the only change to that column. + * Processes the change of the default value of a column. Note that this + * method is only used if it is the only change to that column. * * @param currentModel The current database schema + * * @param desiredModel The desired database schema - * @param change The change object + * + * @param change The change object */ - protected void processChange(Database currentModel, - Database desiredModel, - ColumnDefaultValueChange change) throws IOException - { + protected void processChange(Database currentModel, Database desiredModel, + ColumnDefaultValueChange change) { print("ALTER TABLE "); printlnIdentifier(getTableName(change.getChangedTable())); printIndent(); print("REPLACE "); printIdentifier(getColumnName(change.getChangedColumn())); - Table curTable = currentModel.findTable(change.getChangedTable().getName(), getPlatform().isDelimitedIdentifierModeOn()); - Column curColumn = curTable.findColumn(change.getChangedColumn().getName(), getPlatform().isDelimitedIdentifierModeOn()); + Table curTable = currentModel.findTable(change.getChangedTable().getName(), + platform.isDelimitedIdentifierModeOn()); + Column curColumn = curTable.findColumn(change.getChangedColumn().getName(), + platform.isDelimitedIdentifierModeOn()); print(" DEFAULT "); - if (isValidDefaultValue(change.getNewDefaultValue(), curColumn.getTypeCode())) - { + if (isValidDefaultValue(change.getNewDefaultValue(), curColumn.getTypeCode())) { printDefaultValue(change.getNewDefaultValue(), curColumn.getTypeCode()); - } - else - { + } else { print("NULL"); } printEndOfStatement(); - change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn()); + change.apply(currentModel, platform.isDelimitedIdentifierModeOn()); } /* * Processes a change to a column. * - * @param sourceTable The current table - * @param targetTable The desired table + * @param sourceTable The current table + * + * @param targetTable The desired table + * * @param sourceColumn The current column + * * @param targetColumn The desired column */ - protected void processColumnChange(Table sourceTable, - Table targetTable, - Column sourceColumn, - Column targetColumn) throws IOException - { + protected void processColumnChange(Table sourceTable, Table targetTable, Column sourceColumn, + Column targetColumn) { Object oldParsedDefault = sourceColumn.getParsedDefaultValue(); Object newParsedDefault = targetColumn.getParsedDefaultValue(); - String newDefault = targetColumn.getDefaultValue(); - boolean defaultChanges = ((oldParsedDefault == null) && (newParsedDefault != null)) || - ((oldParsedDefault != null) && !oldParsedDefault.equals(newParsedDefault)); + String newDefault = targetColumn.getDefaultValue(); + boolean defaultChanges = ((oldParsedDefault == null) && (newParsedDefault != null)) + || ((oldParsedDefault != null) && !oldParsedDefault.equals(newParsedDefault)); - // Sybase does not like it if there is a default spec in the ALTER TABLE ALTER + // Sybase does not like it if there is a default spec in the ALTER TABLE + // ALTER // statement; thus we have to change the default afterwards - if (newDefault != null) - { + if (newDefault != null) { targetColumn.setDefaultValue(null); } - if (defaultChanges) - { - // we're first removing the default as it might make problems when the + if (defaultChanges) { + // we're first removing the default as it might make problems when + // the // datatype changes print("ALTER TABLE "); printlnIdentifier(getTableName(sourceTable)); @@ -669,22 +524,18 @@ protected void processColumnChange(Table sourceTable, print("MODIFY "); writeColumn(sourceTable, targetColumn); printEndOfStatement(); - if (defaultChanges) - { + if (defaultChanges) { print("ALTER TABLE "); printlnIdentifier(getTableName(sourceTable)); printIndent(); print("REPLACE "); printIdentifier(getColumnName(sourceColumn)); - if (newDefault != null) - { + if (newDefault != null) { writeColumnDefaultValueStmt(sourceTable, targetColumn); - } - else - { + } else { print(" DEFAULT NULL"); } printEndOfStatement(); } - } + } } diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseModelReader.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybaseModelReader.java similarity index 91% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseModelReader.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybaseModelReader.java index 33b32654d2..bd7d2a8468 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/SybaseModelReader.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybaseModelReader.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.platform.sybase; +package org.jumpmind.symmetric.db.platform.sybase; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -38,16 +38,16 @@ import org.apache.oro.text.regex.PatternMatcher; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.Reference; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; -import org.jumpmind.symmetric.db.ddl.platform.DatabaseMetaDataWrapper; -import org.jumpmind.symmetric.db.ddl.platform.JdbcModelReader; +import org.jumpmind.symmetric.db.DdlUtilsException; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.ForeignKey; +import org.jumpmind.symmetric.db.model.Index; +import org.jumpmind.symmetric.db.model.Reference; +import org.jumpmind.symmetric.db.model.Table; +import org.jumpmind.symmetric.db.model.TypeMap; +import org.jumpmind.symmetric.db.platform.DatabaseMetaDataWrapper; +import org.jumpmind.symmetric.db.platform.JdbcModelReader; /* * Reads a database model from a Sybase database. @@ -64,7 +64,7 @@ public class SybaseModelReader extends JdbcModelReader * * @param platform The platform that this model reader belongs to */ - public SybaseModelReader(Platform platform) + public SybaseModelReader(IDatabasePlatform platform) { super(platform); setDefaultCatalogPattern(null); diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybasePlatform.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybasePlatform.java new file mode 100644 index 0000000000..9b8ba60bb1 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/SybasePlatform.java @@ -0,0 +1,99 @@ +package org.jumpmind.symmetric.db.platform.sybase; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +import java.io.Writer; +import java.sql.Types; + +import org.jumpmind.symmetric.db.AbstractDatabasePlatform; +import org.jumpmind.symmetric.db.platform.SqlBuilder; + +/* + * The platform implementation for Sybase. + */ +public class SybasePlatform extends AbstractDatabasePlatform { + + /* Database name of this platform. */ + public static final String DATABASENAME = "Sybase"; + + /* The standard Sybase jdbc driver. */ + public static final String JDBC_DRIVER = "com.sybase.jdbc2.jdbc.SybDriver"; + + /* The old Sybase jdbc driver. */ + public static final String JDBC_DRIVER_OLD = "com.sybase.jdbc.SybDriver"; + + /* The subprotocol used by the standard Sybase driver. */ + public static final String JDBC_SUBPROTOCOL = "sybase:Tds"; + + /* The maximum size that text and binary columns can have. */ + public static final long MAX_TEXT_SIZE = 2147483647; + + public SybasePlatform() { + + info.setMaxIdentifierLength(128); + info.setNullAsDefaultValueRequired(true); + info.setCommentPrefix("/*"); + info.setCommentSuffix("*/"); + info.setDelimiterToken("\""); + setDelimitedIdentifierModeOn(true); + + info.addNativeTypeMapping(Types.ARRAY, "IMAGE"); + // BIGINT is mapped back in the model reader + info.addNativeTypeMapping(Types.BIGINT, "DECIMAL(19,0)"); + // we're not using the native BIT type because it is rather limited + // (cannot be NULL, cannot be indexed) + info.addNativeTypeMapping(Types.BIT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping(Types.BLOB, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.CLOB, "TEXT", Types.LONGVARCHAR); + info.addNativeTypeMapping(Types.DATE, "DATETIME", Types.TIMESTAMP); + info.addNativeTypeMapping(Types.DISTINCT, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); + info.addNativeTypeMapping(Types.FLOAT, "DOUBLE PRECISION", Types.DOUBLE); + info.addNativeTypeMapping(Types.INTEGER, "INT"); + info.addNativeTypeMapping(Types.JAVA_OBJECT, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.LONGVARBINARY, "IMAGE"); + info.addNativeTypeMapping(Types.LONGVARCHAR, "TEXT"); + info.addNativeTypeMapping(Types.NULL, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.OTHER, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.REF, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.STRUCT, "IMAGE", Types.LONGVARBINARY); + info.addNativeTypeMapping(Types.TIME, "DATETIME", Types.TIMESTAMP); + info.addNativeTypeMapping(Types.TIMESTAMP, "DATETIME", Types.TIMESTAMP); + info.addNativeTypeMapping(Types.TINYINT, "SMALLINT", Types.SMALLINT); + info.addNativeTypeMapping("BOOLEAN", "SMALLINT", "SMALLINT"); + info.addNativeTypeMapping("DATALINK", "IMAGE", "LONGVARBINARY"); + + info.setDefaultSize(Types.BINARY, 254); + info.setDefaultSize(Types.VARBINARY, 254); + info.setDefaultSize(Types.CHAR, 254); + info.setDefaultSize(Types.VARCHAR, 254); + + modelReader = new SybaseModelReader(this); + } + + public String getName() { + return DATABASENAME; + } + + public SqlBuilder createSqlBuilder(Writer writer) { + return new SybaseBuilder(log, this, writer); + } + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/platform/sybase/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/platform/sybase/package.html diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/AbstractSqlTemplate.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/AbstractSqlTemplate.java index 0a5a594251..bf9e2e65ce 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/AbstractSqlTemplate.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/AbstractSqlTemplate.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; abstract public class AbstractSqlTemplate implements ISqlTemplate { diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/DmlStatement.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/DmlStatement.java index 15406a7648..6ae434beb3 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/DmlStatement.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/DmlStatement.java @@ -21,17 +21,17 @@ package org.jumpmind.symmetric.db.sql; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashSet; +import java.sql.Types; +import java.util.ArrayList; +import java.util.HashSet; import java.util.Map; -import java.util.Set; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.NotImplementedException; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import java.util.Set; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.NotImplementedException; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; /** * Builds a SQL DML statement diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/ISqlTemplate.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/ISqlTemplate.java index 7d60ee95e0..ad0c24304f 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/ISqlTemplate.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/ISqlTemplate.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Map; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; /** diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/Query.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/Query.java index cab9565a5d..2671046cea 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/Query.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/Query.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import java.util.List; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; public class Query { diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/SqlScript.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/SqlScript.java similarity index 76% rename from symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/SqlScript.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/SqlScript.java index f6b7a4f7ee..ff16db2601 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/SqlScript.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/SqlScript.java @@ -18,7 +18,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jumpmind.symmetric.db; +package org.jumpmind.symmetric.db.sql; import java.io.IOException; import java.io.InputStreamReader; @@ -35,13 +35,9 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; -import org.jumpmind.symmetric.common.Message; -import org.jumpmind.symmetric.common.logging.ILog; -import org.jumpmind.symmetric.common.logging.LogFactory; -import org.jumpmind.symmetric.util.AppUtils; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.ConnectionCallback; -import org.springframework.jdbc.core.JdbcTemplate; +import org.jumpmind.symmetric.db.sql.jdbc.IConnectionCallback; +import org.jumpmind.symmetric.db.sql.jdbc.JdbcSqlTemplate; +import org.jumpmind.symmetric.util.FormatUtils; /** * This class is for running SQL scripts against a DataSource. @@ -51,8 +47,6 @@ public class SqlScript { static final String COMMENT_CHARS_1 = "--"; static final String COMMENT_CHARS_2 = "#"; - static final ILog log = LogFactory.getLog(SqlScript.class); - public final static String QUERY_ENDS = ";"; private String delimiter = QUERY_ENDS; @@ -66,13 +60,13 @@ public class SqlScript { private boolean failOnError = true; private Map replacementTokens; - + private final static String MEMORY = "SQL snippet"; private String fileName = MEMORY; private String lineDeliminator; - + private ISqlScriptListener listener; public SqlScript(URL url, DataSource ds) { @@ -92,15 +86,12 @@ public SqlScript(URL url, DataSource ds, boolean failOnError, String delimiter, try { fileName = url.getFile(); fileName = fileName.substring(fileName.lastIndexOf("/") + 1); - log.info("ScriptLoading", fileName); init(IOUtils.readLines(new InputStreamReader(url.openStream(), "UTF-8")), ds, failOnError, delimiter, replacementTokens); } catch (IOException ex) { - log.error(ex); throw new RuntimeException(ex); } } - public SqlScript(String sqlScript, DataSource ds, boolean failOnError) { this(sqlScript, ds, failOnError, QUERY_ENDS, null); @@ -112,15 +103,14 @@ public SqlScript(String sqlScript, DataSource ds, boolean failOnError, String de init(IOUtils.readLines(new StringReader(sqlScript)), ds, failOnError, delimiter, replacementTokens); } catch (IOException ex) { - log.error(ex); throw new RuntimeException(ex); } } - + public void setListener(ISqlScriptListener listener) { this.listener = listener; } - + public ISqlScriptListener getListener() { return listener; } @@ -139,17 +129,15 @@ private void closeQuietly(Statement stmt) { try { stmt.close(); } catch (SQLException e) { - log.error(e); } } } - + private void closeQuietly(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { - log.error(e); } } } @@ -159,20 +147,21 @@ public long execute() { } public long execute(final boolean autoCommit) { - JdbcTemplate template = new JdbcTemplate(this.dataSource); - return template.execute(new ConnectionCallback() { - public Long doInConnection(Connection connection) throws SQLException, - DataAccessException { + JdbcSqlTemplate template = new JdbcSqlTemplate(dataSource); + return template.execute(new IConnectionCallback() { + public Long execute(Connection connection) throws SQLException { Statement st = null; ResultSet rs = null; int lineCount = 0; - long updateCount = 0; + long totalRowsUpdatedCount = 0; + long totalRowsRead = 0; + int errorCount = 0; try { connection.setAutoCommit(autoCommit); st = connection.createStatement(); StringBuilder sql = new StringBuilder(); int count = 0; - int notFoundCount = 0; + int unableToDropCount = 0; for (String line : script) { lineCount++; line = trimComments(line); @@ -187,45 +176,48 @@ public Long doInConnection(Connection connection) throws SQLException, toExecute = toExecute.replaceAll(lineDeliminator, "\n"); } try { - toExecute = AppUtils.replaceTokens(toExecute, + toExecute = FormatUtils.replaceTokens(toExecute, replacementTokens, false); - // Empty SQL only seems to come from - // SybasePlatform + if (StringUtils.isNotBlank(toExecute)) { - if (log.isDebugEnabled()) { - log.debug("Message", toExecute); + if (listener != null) { + listener.sqlToRun(sql.toString()); } - long rowsRetreived = 0; + long rowsRetrieved = 0; long rowsUpdated = 0; + long ts = System.currentTimeMillis(); if (st.execute(toExecute)) { rs = st.getResultSet(); - while(rs.next()) {rowsRetreived++;}; + while (rs.next()) { + rowsRetrieved++; + } + totalRowsRead += rowsRetrieved; } else { rowsUpdated = st.getUpdateCount(); - updateCount+=rowsUpdated; + totalRowsUpdatedCount += rowsUpdated; } - + if (listener != null) { - listener.sqlApplied(toExecute, rowsUpdated, rowsRetreived, lineCount); + listener.sqlApplied(toExecute, rowsUpdated, + rowsRetrieved, lineCount, + System.currentTimeMillis() - ts); } - + count++; if (count % commitRate == 0) { connection.commit(); } } } catch (SQLException e) { + errorCount++; if (listener != null) { listener.sqlErrored(toExecute, e, lineCount); } if (failOnError) { - log.error("SqlError", e, sql.toString()); throw e; } else { - if (e.getErrorCode() != 942 && e.getErrorCode() != 2289) { - log.warn("Sql", e.getMessage() + ": " + sql.toString()); - } else if (sql.toString().toLowerCase().startsWith("drop")) { - notFoundCount++; + if (sql.toString().toLowerCase().startsWith("drop")) { + unableToDropCount++; } } } @@ -241,18 +233,18 @@ public Long doInConnection(Connection connection) throws SQLException, connection.commit(); } - log.info("ScriptCompleted", count, fileName); - if (notFoundCount > 0) { - log.info("ScriptDropError", notFoundCount); + if (listener != null) { + listener.scriptCompleted(lineCount, errorCount, totalRowsUpdatedCount, + totalRowsRead, unableToDropCount); } + } catch (Exception e) { - log.info("ScriptError", lineCount, fileName); - throw new RuntimeException(Message.get("ScriptError", lineCount, fileName), e); + throw new SqlScriptException(e, lineCount); } finally { closeQuietly(rs); closeQuietly(st); } - return updateCount; + return totalRowsUpdatedCount; } }); } @@ -284,10 +276,18 @@ public void setCommitRate(int commitRate) { public void setLineDeliminator(String lineDeliminator) { this.lineDeliminator = lineDeliminator; } - + public static interface ISqlScriptListener { - public void sqlApplied (String sql, long rowsUpdated, long rowsRetreived, int lineNumber); + + public void sqlToRun(String sql); + + public void sqlApplied(String sql, long rowsUpdated, long rowsRetreived, int lineNumber, + long timeToExecute); + public void sqlErrored(String sql, SQLException ex, int lineNumber); + + public void scriptCompleted(int statementCount, int statementsThatErroredCount, + long rowsAffectedCount, long rowsReadCount, int failedDropsCount); } } \ No newline at end of file diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/SqlScriptException.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/SqlScriptException.java new file mode 100644 index 0000000000..da52e322e3 --- /dev/null +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/sql/SqlScriptException.java @@ -0,0 +1,19 @@ +package org.jumpmind.symmetric.db.sql; + +public class SqlScriptException extends SqlException { + + private static final long serialVersionUID = 1L; + + private int lineNumber; + + public SqlScriptException(Throwable cause, int lineNumber) { + super("Script failed at line " + lineNumber, cause); + this.lineNumber = lineNumber; + } + + public int getLineNumber() { + return lineNumber; + } + + +} diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/CallbackClosure.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/CallbackClosure.java similarity index 95% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/CallbackClosure.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/CallbackClosure.java index 429630cc7e..be627a8b57 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/CallbackClosure.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/CallbackClosure.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.util; +package org.jumpmind.symmetric.db.util; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -26,7 +26,7 @@ import java.util.Map; import org.apache.commons.collections.Closure; -import org.jumpmind.symmetric.db.ddl.DdlUtilsException; +import org.jumpmind.symmetric.db.DdlUtilsException; /** * A closure that determines a callback for the type of the object and calls it. diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/Jdbc3Utils.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/Jdbc3Utils.java similarity index 95% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/Jdbc3Utils.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/Jdbc3Utils.java index 63f1df26a8..b8d2e97d99 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/Jdbc3Utils.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/Jdbc3Utils.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.util; +package org.jumpmind.symmetric.db.util; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,7 @@ import java.sql.Statement; import java.sql.Types; -import org.jumpmind.symmetric.db.ddl.model.TypeMap; +import org.jumpmind.symmetric.db.model.TypeMap; /** * Little helper class providing functions for dealing with the newer JDBC functionality diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/MultiInstanceofPredicate.java b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/MultiInstanceofPredicate.java similarity index 94% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/MultiInstanceofPredicate.java rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/MultiInstanceofPredicate.java index a7a228b739..7d638609c8 100644 --- a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/MultiInstanceofPredicate.java +++ b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/MultiInstanceofPredicate.java @@ -1,4 +1,4 @@ -package org.jumpmind.symmetric.db.ddl.util; +package org.jumpmind.symmetric.db.util; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/package.html b/symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/package.html similarity index 100% rename from symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/ddl/util/package.html rename to symmetric/symmetric-db/src/main/java/org/jumpmind/symmetric/db/util/package.html diff --git a/symmetric/symmetric-db/src/main/resources/org/jumpmind/symmetric/db/ddl/io/mapping.xml b/symmetric/symmetric-db/src/main/resources/org/jumpmind/symmetric/db/io/mapping.xml similarity index 83% rename from symmetric/symmetric-db/src/main/resources/org/jumpmind/symmetric/db/ddl/io/mapping.xml rename to symmetric/symmetric-db/src/main/resources/org/jumpmind/symmetric/db/io/mapping.xml index b20d514af3..b90a4a396e 100644 --- a/symmetric/symmetric-db/src/main/resources/org/jumpmind/symmetric/db/ddl/io/mapping.xml +++ b/symmetric/symmetric-db/src/main/resources/org/jumpmind/symmetric/db/io/mapping.xml @@ -18,7 +18,7 @@ specific language governing permissions and limitations under the License. --> - + @@ -28,7 +28,7 @@ under the License. - + @@ -39,7 +39,7 @@ under the License. - + @@ -53,7 +53,7 @@ under the License. - + @@ -62,14 +62,14 @@ under the License. - + - + @@ -77,14 +77,14 @@ under the License. - + - + diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestBase.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestBase.java deleted file mode 100644 index 9859d08d48..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestBase.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.jumpmind.symmetric.ddl; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.StringReader; - -import junit.framework.TestCase; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.io.DatabaseIO; -import org.jumpmind.symmetric.db.ddl.model.Database; - -/* - * Base class for DdlUtils tests. - * - * @version $Revision: $ - */ -public abstract class TestBase extends TestCase -{ - /* The log for the tests. */ - private final Log _log = LogFactory.getLog(getClass()); - - /* - * Returns the log. - * - * @return The log - */ - protected Log getLog() - { - return _log; - } - - /* - * Parses the database defined in the given XML definition. - * - * @param dbDef The database XML definition - * @return The database model - */ - protected Database parseDatabaseFromString(String dbDef) - { - DatabaseIO dbIO = new DatabaseIO(); - - dbIO.setUseInternalDtd(true); - dbIO.setValidateXml(false); - return dbIO.read(new StringReader(dbDef)); - } - - /* - * Compares the two strings but ignores any whitespace differences. It also - * recognizes special delimiter chars. - * - * @param expected The expected string - * @param actual The actual string - */ - protected void assertEqualsIgnoringWhitespaces(String expected, String actual) - { - String processedExpected = compressWhitespaces(expected); - String processedActual = compressWhitespaces(actual); - - assertEquals(processedExpected, processedActual); - } - - /* - * Compresses the whitespaces in the given string to a single space. Also - * recognizes special delimiter chars and removes whitespaces before them. - * - * @param original The original string - * @return The resulting string - */ - private String compressWhitespaces(String original) - { - StringBuffer result = new StringBuffer(); - char oldChar = ' '; - char curChar; - - for (int idx = 0; idx < original.length(); idx++) - { - curChar = original.charAt(idx); - if (Character.isWhitespace(curChar)) - { - if (oldChar != ' ') - { - oldChar = ' '; - result.append(oldChar); - } - } - else - { - if ((curChar == ',') || (curChar == ';') || - (curChar == '(') || (curChar == ')')) - { - if ((oldChar == ' ') && (result.length() > 0)) - { - // we're removing whitespaces before commas/semicolons - result.setLength(result.length() - 1); - } - } - if ((oldChar == ',') || (oldChar == ';')) - { - // we're adding a space after commas/semicolons if necessary - result.append(' '); - } - result.append(curChar); - oldChar = curChar; - } - } - return result.toString(); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestPlatformBase.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestPlatformBase.java deleted file mode 100644 index 5b7d8e5b59..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/TestPlatformBase.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.jumpmind.symmetric.ddl; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.beans.IntrospectionException; -import java.io.IOException; -import java.io.StringWriter; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformFactory; -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.xml.sax.SAXException; - -/* - * Base class for builder tests. - * - * @version $Revision: 463305 $ - */ -public abstract class TestPlatformBase extends TestBase -{ - /* The database schema for testing the column types. */ - public static final String COLUMN_TEST_SCHEMA = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* The database schema for testing column constraints. */ - public static final String COLUMN_CONSTRAINT_TEST_SCHEMA = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* The database schema for testing table constraints, ie. foreign keys and indices. */ - public static final String TABLE_CONSTRAINT_TEST_SCHEMA = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* The tested platform. */ - private Platform _platform; - /* The writer that the builder of the platform writes to. */ - private StringWriter _writer; - - /* - * {@inheritDoc} - */ - protected void setUp() throws Exception - { - _writer = new StringWriter(); - _platform = PlatformFactory.createNewPlatformInstance(getDatabaseName()); - _platform.getSqlBuilder().setWriter(_writer); - if (_platform.getPlatformInfo().isDelimitedIdentifiersSupported()) - { - _platform.setDelimitedIdentifierModeOn(true); - } - } - - /* - * {@inheritDoc} - */ - protected void tearDown() throws Exception - { - _platform = null; - _writer = null; - } - - /* - * Returns the tested platform. - * - * @return The platform - */ - protected Platform getPlatform() - { - return _platform; - } - - /* - * Returns the info object of the tested platform. - * - * @return The platform info object - */ - protected PlatformInfo getPlatformInfo() - { - return getPlatform().getPlatformInfo(); - } - - /* - * Returns the SQL builder of the tested platform. - * - * @return The builder object - */ - protected SqlBuilder getSqlBuilder() - { - return getPlatform().getSqlBuilder(); - } - - /* - * Returns the builder output so far. - * - * @return The output - */ - protected String getBuilderOutput() - { - return _writer.toString(); - } - - /* - * Returns the name of the tested database. - * - * @return The database name - */ - protected abstract String getDatabaseName(); - - /* - * Creates the database creation sql for the given database schema. - * - * @param schema The database schema XML - * @return The sql - */ - protected String createTestDatabase(String schema) throws IntrospectionException, IOException, SAXException - { - Database testDb = parseDatabaseFromString(schema); - - // we're turning the comment creation off to make testing easier - getPlatform().setSqlCommentsOn(false); - getPlatform().getSqlBuilder().createTables(testDb); - return getBuilderOutput(); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestAlterationAlgorithm.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestAlterationAlgorithm.java deleted file mode 100644 index d6d633454a..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestAlterationAlgorithm.java +++ /dev/null @@ -1,2723 +0,0 @@ -package org.jumpmind.symmetric.ddl.alteration; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.IOException; -import java.io.StringWriter; - -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.ddl.TestBase; -import org.jumpmind.symmetric.ddl.platform.TestPlatform; - -/* - * Tests the generation of the alteration statements. - * - * @version $Revision: $ - */ -public class TestAlterationAlgorithm extends TestBase -{ - /* The tested platform. */ - private Platform _platform; - /* The writer that the builder of the platform writes to. */ - private StringWriter _writer; - - /* - * {@inheritDoc} - */ - protected void setUp() throws Exception - { - _writer = new StringWriter(); - _platform = new TestPlatform(); - _platform.getSqlBuilder().setWriter(_writer); - _platform.setSqlCommentsOn(false); - _platform.setDelimitedIdentifierModeOn(true); - } - - /* - * {@inheritDoc} - */ - protected void tearDown() throws Exception - { - _platform = null; - _writer = null; - } - - /* - * Returns the SQL for altering the first into the second database. - * - * @param currentSchema The current schema XML - * @param desiredSchema The desired schema XML - * @return The sql - */ - protected String getAlterDatabaseSQL(String currentSchema, String desiredSchema) throws IOException - { - Database currentModel = parseDatabaseFromString(currentSchema); - Database desiredModel = parseDatabaseFromString(desiredSchema); - - _platform.getSqlBuilder().alterDatabase(currentModel, desiredModel, null); - - return _writer.toString(); - } - - /* - * Test where no change is made to the model. - */ - public void testNoChange() throws IOException - { - final String modelXml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "", - getAlterDatabaseSQL(modelXml, modelXml)); - } - - /* - * Tests the addition of a table. - */ - public void testAddTable() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a table that has an index. - */ - public void testAddTableWithIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COL\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "CREATE INDEX \"TESTINDEX\" ON \"TABLEB\" (\"COL\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a table that has a unique index. - */ - public void testAddTableWithUniqueIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COL\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TABLEB\" (\"COL\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a table that has a foreign key to an existing one. - */ - public void testAddTableWithForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" INTEGER,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of two tables that have foreign key to each other. - */ - public void testAddTablesWithForeignKeys() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - ""; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"ColFK\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" DOUBLE NOT NULL,\n"+ - " \"COLFK\" INTEGER,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "ALTER TABLE \"TableA\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"ColFK\") REFERENCES \"TABLEB\" (\"COLPK\");\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a table. - */ - public void testRemoveTable() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"TableA\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a table with an index. - */ - public void testRemoveTableWithIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"TableA\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a table with a foreign key to an existing table. - */ - public void testRemoveTableWithForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TableA\" DROP CONSTRAINT \"TESTFK\";\n"+ - "DROP TABLE \"TableA\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a table that is referenced by a foreign key of an existing table. - */ - public void testRemoveTableReferencedByForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TableA\" DROP CONSTRAINT \"TESTFK\";\n"+ - "DROP TABLE \"TABLEB\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of two tables that have foreign key to each other. - */ - public void testRemoveTablesWithForeignKeys() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - ""; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TableA\" DROP CONSTRAINT \"TESTFK\";\n"+ - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "DROP TABLE \"TABLEB\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of an index to an existing table. - */ - public void testAddIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of an unique index to an existing table. - */ - public void testAddUniqueIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE UNIQUE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of an index from a table. - */ - public void testRemoveIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TestIndex\" ON \"TableA\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of an unique index from a table. - */ - public void testRemoveUniqueIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TestIndex\" ON \"TableA\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a primary key to an existing table. - */ - public void testAddPrimaryKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TableA\" ADD CONSTRAINT \"TableA_PK\" PRIMARY KEY (\"ColPK1\",\"ColPK2\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a primary key and a column to an existing table. - */ - public void testAddPrimaryKeyAndColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" VARCHAR(64) NOT NULL,\n"+ - " \"Col\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" VARCHAR(64) NOT NULL,\n"+ - " \"Col\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\",\"Col\") SELECT \"ColPK1\",\"ColPK2\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a primary key from an existing table. - */ - public void testRemovePrimaryKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" VARCHAR(64) NOT NULL\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\", \"ColPK2\") SELECT \"ColPK1\", \"ColPK2\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" VARCHAR(64) NOT NULL\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\", \"ColPK2\") SELECT \"ColPK1\", \"ColPK2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a column to an existing table. - */ - public void testAddColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\", \"Col\") SELECT \"ColPK\", \"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a column from an existing table. - */ - public void testRemoveColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a primary key column to an existing table. - */ - public void testAddPrimaryKeyColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\") SELECT \"ColPK1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\", \"ColPK2\") SELECT \"ColPK1\", \"ColPK2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a primary key column from an existing table. - */ - public void testRemovePrimaryKeyColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\") SELECT \"ColPK1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\") SELECT \"ColPK1\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of columns to the primary key of a table and the foreign key - * of another table referencing it. - */ - public void testAddColumnsToPrimaryAndForeignKeys() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\") SELECT \"ColPK1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE TABLE \"TABLEB_\"\n"+ - "(\n"+ - " \"COLPK\" DOUBLE NOT NULL,\n"+ - " \"COLFK1\" INTEGER,\n"+ - " \"COLFK2\" DOUBLE,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK1\") SELECT \"COLPK\",\"COLFK1\" FROM \"TABLEB\";\n"+ - "DROP TABLE \"TABLEB\";\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" DOUBLE NOT NULL,\n"+ - " \"COLFK1\" INTEGER,\n"+ - " \"COLFK2\" DOUBLE,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK1\",\"COLFK2\") SELECT \"COLPK\",\"COLFK1\",\"COLFK2\" FROM \"TABLEB_\";\n"+ - "DROP TABLE \"TABLEB_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK1\",\"COLFK2\") REFERENCES \"TableA\" (\"ColPK1\",\"ColPK2\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of columns from the primary key of a table and the foreign key - * of another table referencing it. - */ - public void testRemoveColumnsFromPrimaryAndForeignKeys() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\") SELECT \"ColPK1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\") SELECT \"ColPK1\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE TABLE \"TABLEB_\"\n"+ - "(\n"+ - " \"COLPK\" DOUBLE NOT NULL,\n"+ - " \"COLFK1\" INTEGER,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK1\") SELECT \"COLPK\",\"COLFK1\" FROM \"TABLEB\";\n"+ - "DROP TABLE \"TABLEB\";\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" DOUBLE NOT NULL,\n"+ - " \"COLFK1\" INTEGER,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK1\") SELECT \"COLPK\",\"COLFK1\" FROM \"TABLEB_\";\n"+ - "DROP TABLE \"TABLEB_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK1\") REFERENCES \"TableA\" (\"ColPK1\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of an index column to an existing table. - */ - public void testAddIndexColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " \"Col2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " \"Col2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\",\"Col2\") SELECT \"ColPK\",\"Col1\",\"Col2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\",\"Col2\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of an index column from an existing table. - */ - public void testRemoveIndexColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of an unique index column to an existing table. - */ - public void testAddUniqueIndexColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " \"Col2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " \"Col2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\",\"Col2\") SELECT \"ColPK\",\"Col1\",\"Col2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\",\"Col2\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of an unique index column from an existing table. - */ - public void testRemoveUniqueIndexColumn() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - - /* - * Tests the addition of a column to a table with an index. - */ - public void testAddColumnToTableWithIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " \"Col2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col1\" DOUBLE,\n"+ - " \"Col2\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\",\"Col2\") SELECT \"ColPK\",\"Col1\",\"Col2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a column to a table that has a foreign key. - */ - public void testAddColumnToTableWithForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TABLEB_\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" INTEGER,\n"+ - " \"COL\" DOUBLE,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB\";\n"+ - "DROP TABLE \"TABLEB\";\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" INTEGER,\n"+ - " \"COL\" DOUBLE,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\",\"COL\") SELECT \"COLPK\",\"COLFK\",\"COL\" FROM \"TABLEB_\";\n"+ - "DROP TABLE \"TABLEB_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of a column to a table that is referenced by a foreign key. - */ - public void testAddColumnToTableReferencedByForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DOUBLE,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of an existing column to a primary key. - */ - public void testAddExistingColumnToPrimaryKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a column from a primary key. - */ - public void testRemoveColumnFromPrimaryKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of existing columns to a primary and the referencing foreign key. - */ - public void testAddExistingColumnsToPrimaryAndForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK2\",\"COLFK1\") REFERENCES \"TableA\" (\"ColPK1\",\"ColPK2\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of existing columns from a primary and the referencing foreign key. - */ - public void testRemoveExistingColumnsFromPrimaryAndForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK1\" INTEGER NOT NULL,\n"+ - " \"ColPK2\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK1\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK2\") REFERENCES \"TableA\" (\"ColPK1\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of an existing column to an index. - */ - public void testAddExistingColumnToIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+ - "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\",\"Col2\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the addition of an existing column from an index. - */ - public void testRemoveExistingColumnFromIndex() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+ - "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the removal of a column from a table referenced by a foreign key. - */ - public void testRemoveColumnFromTableReferencedByForeignKey() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a column's datatype. - */ - public void testChangeColumnDatatype() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a primary key column's datatype. - */ - public void testChangePrimaryKeyColumnDatatype() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" DOUBLE NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" DOUBLE NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a index column's datatype. - */ - public void testChangeIndexColumnDatatype() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of the datatype of the columns of a primary key and the referencing foreign key. - */ - public void testChangePrimaryAndForeignKeyColumnsDatatype() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" DOUBLE NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE TABLE \"TABLEB_\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" DOUBLE,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB\";\n"+ - "DROP TABLE \"TABLEB\";\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" DOUBLE,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+ - "DROP TABLE \"TABLEB_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a column's size. - */ - public void testChangeColumnSize() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" VARCHAR(64) NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" VARCHAR(64) NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a primary key column's size. - */ - public void testChangePrimaryKeyColumnSize() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" DECIMAL(30,4) NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" DECIMAL(30,4) NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a index column's size. - */ - public void testChangeIndexColumnSize() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DECIMAL(15,2) NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DECIMAL(15,2) NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of the size of the columns of a primary key and the referencing foreign key. - */ - public void testChangePrimaryAndForeignKeyColumnsSize() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" VARCHAR(64) NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" VARCHAR(64) NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE TABLE \"TABLEB_\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB\";\n"+ - "DROP TABLE \"TABLEB\";\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" VARCHAR(64),\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+ - "DROP TABLE \"TABLEB_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a column's default value. - */ - public void testChangeColumnDefault() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" VARCHAR(32) DEFAULT 'test 2' NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" VARCHAR(32) DEFAULT 'test 2' NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a primary key column's default value. - */ - public void testChangePrimaryKeyColumnDefault() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" DECIMAL(15,2) DEFAULT 4.0 NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" DECIMAL(15,2) DEFAULT 4.0 NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a index column's default value. - */ - public void testChangeIndexColumnDefault() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DATE DEFAULT '2001-02-03' NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" DATE DEFAULT '2001-02-03' NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of the default value of the columns of a primary key and the referencing foreign key. - */ - public void testChangePrimaryAndForeignKeyColumnsDefault() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER DEFAULT 1 NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER DEFAULT 1 NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE TABLE \"TABLEB_\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" INTEGER DEFAULT 0,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB\";\n"+ - "DROP TABLE \"TABLEB\";\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" INTEGER DEFAULT 0,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+ - "DROP TABLE \"TABLEB_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a column's auto-increment attribute. - */ - public void testChangeColumnAutoIncrement() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a primary key column's auto-increment attribute. - */ - public void testChangePrimaryKeyColumnAutoIncrement() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL IDENTITY,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL IDENTITY,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a index column's auto-increment attribute. - */ - public void testChangeIndexColumnAutoIncrement() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL IDENTITY,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL IDENTITY,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of the auto-increment attribute of the columns of a primary key - * and the referencing foreign key. - */ - public void testChangePrimaryAndForeignKeyColumnsAutoIncrement() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a column's required attribute. - */ - public void testChangeColumnRequired() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a primary key column's required attribute. - */ - public void testChangePrimaryKeyColumnRequired() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of a index column's required attribute. - */ - public void testChangeIndexColumnRequired() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " \"Col\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } - - /* - * Tests the change of the required attribute of the columns of a primary key - * and the referencing foreign key. - */ - public void testChangePrimaryAndForeignKeyColumnsRequired() throws IOException - { - final String model1Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String model2Xml = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+ - "CREATE TABLE \"TableA_\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+ - "DROP TABLE \"TableA\";\n"+ - "CREATE TABLE \"TableA\"\n"+ - "(\n"+ - " \"ColPK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"ColPK\")\n"+ - ");\n"+ - "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+ - "DROP TABLE \"TableA_\";\n"+ - "CREATE TABLE \"TABLEB_\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" INTEGER,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB\";\n"+ - "DROP TABLE \"TABLEB\";\n"+ - "CREATE TABLE \"TABLEB\"\n"+ - "(\n"+ - " \"COLPK\" INTEGER NOT NULL,\n"+ - " \"COLFK\" INTEGER,\n"+ - " PRIMARY KEY (\"COLPK\")\n"+ - ");\n"+ - "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+ - "DROP TABLE \"TABLEB_\";\n"+ - "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n", - getAlterDatabaseSQL(model1Xml, model2Xml)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestModelComparator.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestModelComparator.java deleted file mode 100644 index da8fba2234..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/TestModelComparator.java +++ /dev/null @@ -1,1283 +0,0 @@ -package org.jumpmind.symmetric.ddl.alteration; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.sql.Types; -import java.util.List; - -import org.jumpmind.symmetric.db.ddl.PlatformInfo; -import org.jumpmind.symmetric.db.ddl.alteration.AddColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddForeignKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddIndexChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddPrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.AddTableChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnAutoIncrementChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDataTypeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnDefaultValueChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnRequiredChange; -import org.jumpmind.symmetric.db.ddl.alteration.ColumnSizeChange; -import org.jumpmind.symmetric.db.ddl.alteration.ModelComparator; -import org.jumpmind.symmetric.db.ddl.alteration.PrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveColumnChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveForeignKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveIndexChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemovePrimaryKeyChange; -import org.jumpmind.symmetric.db.ddl.alteration.RemoveTableChange; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.ddl.TestBase; - -/* - * Tests the model comparison. - * - * @version $Revision: $ - */ -public class TestModelComparator extends TestBase -{ - /* - * Creates a new model comparator. - * - * @param caseSensitive Whether the comparison is case sensitive - * @return The model comparator - */ - protected ModelComparator createModelComparator(boolean caseSensitive) - { - PlatformInfo platformInfo = new PlatformInfo(); - - platformInfo.setHasSize(Types.DECIMAL, true); - platformInfo.setHasSize(Types.NUMERIC, true); - platformInfo.setHasSize(Types.CHAR, true); - platformInfo.setHasSize(Types.VARCHAR, true); - return new ModelComparator(platformInfo, caseSensitive); - } - - /* - * Tests the addition of a table. - */ - public void testAddTable() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - AddTableChange change = (AddTableChange)changes.get(0); - - assertEquals("TABLEB", - change.getNewTable().getName()); - } - - /* - * Tests the removal of a table. - */ - public void testRemoveTable() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - RemoveTableChange change = (RemoveTableChange)changes.get(0); - - assertEquals("TableA", - change.getChangedTable().getName()); - } - - /* - * Tests the addition and removal of a table. - */ - public void testAddAndRemoveTable() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(2, - changes.size()); - - AddTableChange change1 = (AddTableChange)changes.get(0); - RemoveTableChange change2 = (RemoveTableChange)changes.get(1); - - assertEquals("TABLEA", - change1.getNewTable().getName()); - assertEquals("TableA", - change2.getChangedTable().getName()); - } - - /* - * Tests the addition of a foreign key. - */ - public void testAddForeignKey() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - AddForeignKeyChange change = (AddForeignKeyChange)changes.get(0); - - assertEquals("TESTFK", - change.getNewForeignKey().getName()); - } - - /* - * Tests the addition of two tables with foreign keys to each other . - */ - public void testAddTablesWithForeignKeys() - { - final String MODEL1 = - "\n" + - "\n" + - ""; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(4, - changes.size()); - - AddTableChange tableChange1 = (AddTableChange)changes.get(0); - AddForeignKeyChange fkChange1 = (AddForeignKeyChange)changes.get(1); - AddTableChange tableChange2 = (AddTableChange)changes.get(2); - AddForeignKeyChange fkChange2 = (AddForeignKeyChange)changes.get(3); - - assertEquals("TABLEA", - tableChange1.getNewTable().getName()); - assertEquals("TABLEB", - tableChange2.getNewTable().getName()); - assertEquals("TESTFKB", - fkChange1.getNewForeignKey().getName()); - assertEquals("TABLEA", - fkChange1.getChangedTable().getName()); - assertEquals("TESTFKA", - fkChange2.getNewForeignKey().getName()); - assertEquals("TABLEB", - fkChange2.getChangedTable().getName()); - } - - /* - * Tests the removal of a foreign key. - */ - public void testRemoveForeignKey() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - RemoveForeignKeyChange change = (RemoveForeignKeyChange)changes.get(0); - - assertEquals("TestFK", - change.getForeignKey().getName()); - } - - /* - * Tests the addition and removal of a foreign key. - */ - public void testAddAndRemoveForeignKey1() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(2, - changes.size()); - - RemoveForeignKeyChange change1 = (RemoveForeignKeyChange)changes.get(0); - AddForeignKeyChange change2 = (AddForeignKeyChange)changes.get(1); - - assertEquals("TestFK", - change1.getForeignKey().getName()); - assertEquals("TESTFK", - change2.getNewForeignKey().getName()); - } - - /* - * Tests the addition and removal of a foreign key because of a change of the references. - */ - public void testAddAndRemoveForeignKey2() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(2, - changes.size()); - - RemoveForeignKeyChange change1 = (RemoveForeignKeyChange)changes.get(0); - AddForeignKeyChange change2 = (AddForeignKeyChange)changes.get(1); - - assertEquals("TestFK", - change1.getForeignKey().getName()); - assertEquals("TestFK", - change2.getNewForeignKey().getName()); - } - - - /* - * Tests that the order of the references in a foreign key is not important. - */ - public void testForeignKeyReferenceOrder() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertTrue(changes.isEmpty()); - } - - /* - * Tests the addition of an index. - */ - public void testAddIndex() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - AddIndexChange change = (AddIndexChange)changes.get(0); - - assertEquals("TESTINDEX", - change.getNewIndex().getName()); - } - - /* - * Tests the removal of an index. - */ - public void testRemoveIndex() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(1, - changes.size()); - - RemoveIndexChange change = (RemoveIndexChange)changes.get(0); - - assertEquals("TestIndex", - change.getIndex().getName()); - } - - /* - * Tests the addition and removal of an index because of the change of type of the index. - */ - public void testAddAndRemoveIndex() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(2, - changes.size()); - - RemoveIndexChange change1 = (RemoveIndexChange)changes.get(0); - AddIndexChange change2 = (AddIndexChange)changes.get(1); - - assertEquals("TestIndex", - change1.getIndex().getName()); - assertEquals("TestIndex", - change2.getNewIndex().getName()); - } - - /* - * Tests the addition and removal of an index because of the change of column order. - */ - public void testChangeIndexColumnOrder() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(2, - changes.size()); - - RemoveIndexChange change1 = (RemoveIndexChange)changes.get(0); - AddIndexChange change2 = (AddIndexChange)changes.get(1); - - assertEquals("TestIndex", - change1.getIndex().getName()); - assertEquals("TestIndex", - change2.getNewIndex().getName()); - } - - /* - * Tests the addition and removal of an index because of the addition of an index column. - */ - public void testAddIndexColumn() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(2, - changes.size()); - - RemoveIndexChange change1 = (RemoveIndexChange)changes.get(0); - AddIndexChange change2 = (AddIndexChange)changes.get(1); - - assertEquals("TestIndex", - change1.getIndex().getName()); - assertEquals("TestIndex", - change2.getNewIndex().getName()); - } - - /* - * Tests the addition and removal of an index because of the removal of an index column. - */ - public void testRemoveIndexColumn() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(2, - changes.size()); - - RemoveIndexChange change1 = (RemoveIndexChange)changes.get(0); - AddIndexChange change2 = (AddIndexChange)changes.get(1); - - assertEquals("TestIndex", - change1.getIndex().getName()); - assertEquals("TestIndex", - change2.getNewIndex().getName()); - } - - /* - * Tests the addition of a primary key. - */ - public void testAddPrimaryKey() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - AddPrimaryKeyChange change = (AddPrimaryKeyChange)changes.get(0); - - assertEquals(1, - change.getPrimaryKeyColumns().length); - assertEquals("ColPK", - change.getPrimaryKeyColumns()[0].getName()); - } - - /* - * Tests the removal of a primary key. - */ - public void testRemovePrimaryKey() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - RemovePrimaryKeyChange change = (RemovePrimaryKeyChange)changes.get(0); - - assertEquals(1, - change.getPrimaryKeyColumns().length); - assertEquals("ColPK", - change.getPrimaryKeyColumns()[0].getName()); - } - - /* - * Tests the addition of a column to the primary key. - */ - public void testAddPrimaryKeyColumn() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(1, - changes.size()); - - PrimaryKeyChange change = (PrimaryKeyChange)changes.get(0); - - assertEquals(1, - change.getOldPrimaryKeyColumns().length); - assertEquals(2, - change.getNewPrimaryKeyColumns().length); - assertEquals("ColPK1", - change.getOldPrimaryKeyColumns()[0].getName()); - assertEquals("ColPK1", - change.getNewPrimaryKeyColumns()[0].getName()); - assertEquals("ColPK2", - change.getNewPrimaryKeyColumns()[1].getName()); - } - - /* - * Tests the removal of a column from the primary key. - */ - public void testRemovePrimaryKeyColumn() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - PrimaryKeyChange change = (PrimaryKeyChange)changes.get(0); - - assertEquals(2, - change.getOldPrimaryKeyColumns().length); - assertEquals(1, - change.getNewPrimaryKeyColumns().length); - assertEquals("ColPK1", - change.getOldPrimaryKeyColumns()[0].getName()); - assertEquals("ColPK2", - change.getOldPrimaryKeyColumns()[1].getName()); - assertEquals("ColPK2", - change.getNewPrimaryKeyColumns()[0].getName()); - } - - /* - * Tests the addition a column. - */ - public void testAddColumn() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - AddColumnChange change = (AddColumnChange)changes.get(0); - - assertEquals("Col1", - change.getNewColumn().getName()); - } - - /* - * Tests the removal of a column. - */ - public void testRemoveColumn() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - RemoveColumnChange change = (RemoveColumnChange)changes.get(0); - - assertEquals("Col1", - change.getColumn().getName()); - } - - /* - * Tests changing the data type of a column. - */ - public void testChangeColumnDataType() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(1, - changes.size()); - - ColumnDataTypeChange change = (ColumnDataTypeChange)changes.get(0); - - assertEquals("Col", - change.getChangedColumn().getName()); - assertEquals(Types.INTEGER, - change.getNewTypeCode()); - } - - /* - * Tests changing the size of a column. - */ - public void testChangeColumnSize() - { - // note that we also have a size for the INTEGER column, but we don't - // expect a change for it because the size is not relevant for this type - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - ColumnSizeChange change = (ColumnSizeChange)changes.get(0); - - assertEquals("Col", - change.getChangedColumn().getName()); - assertEquals(32, - change.getNewSize()); - assertEquals(0, - change.getNewScale()); - } - - /* - * Tests changing the scale of a column. - */ - public void testChangeColumnScale() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(1, - changes.size()); - - ColumnSizeChange change = (ColumnSizeChange)changes.get(0); - - assertEquals("Col", - change.getChangedColumn().getName()); - assertEquals(32, - change.getNewSize()); - assertEquals(5, - change.getNewScale()); - } - - /* - * Tests removing the size of a column. This test shows how the comparator - * reacts in the common case of comparing a model read from a live database - * (which usually returns sizes for every column) and a model from XML. - * The model comparator will filter out these changes depending on the - * platform info with which the comparator was created. - */ - public void testRemoveColumnSize() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertTrue(changes.isEmpty()); - } - - /* - * Tests changing the default value of a column. - */ - public void testChangeDefaultValue() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(1, - changes.size()); - - ColumnDefaultValueChange change = (ColumnDefaultValueChange)changes.get(0); - - assertEquals("Col", - change.getChangedColumn().getName()); - assertEquals("2", - change.getNewDefaultValue()); - } - - /* - * Tests that shows that the same default value expressed differently does not - * result in a change. - */ - public void testSameDefaultValueExpressedDifferently() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertTrue(changes.isEmpty()); - } - - /* - * Tests adding a default value to a column. - */ - public void testAddDefaultValue() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(true).compare(model1, model2); - - assertEquals(1, - changes.size()); - - ColumnDefaultValueChange change = (ColumnDefaultValueChange)changes.get(0); - - assertEquals("Col", - change.getChangedColumn().getName()); - assertEquals("0", - change.getNewDefaultValue()); - } - - /* - * Tests chainging the required-constraint of a column. - */ - public void testChangeColumnRequired() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - ColumnRequiredChange change = (ColumnRequiredChange)changes.get(0); - - assertEquals("Col", - change.getChangedColumn().getName()); - } - - /* - * Tests chainging the auto-increment-constraint of a column. - */ - public void testChangeColumnAutoIncrement() - { - final String MODEL1 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - final String MODEL2 = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - Database model1 = parseDatabaseFromString(MODEL1); - Database model2 = parseDatabaseFromString(MODEL2); - List changes = createModelComparator(false).compare(model1, model2); - - assertEquals(1, - changes.size()); - - ColumnAutoIncrementChange change = (ColumnAutoIncrementChange)changes.get(0); - - assertEquals("Col", - change.getColumn().getName()); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/package.html b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/package.html deleted file mode 100644 index 1c3f81a992..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/alteration/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -

- This package contains the tests for the alteration algorithm. -

- - diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/TestDatabaseIO.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/TestDatabaseIO.java deleted file mode 100644 index e36a512141..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/TestDatabaseIO.java +++ /dev/null @@ -1,1305 +0,0 @@ -package org.jumpmind.symmetric.ddl.io; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.io.StringReader; -import java.io.StringWriter; -import java.sql.Types; -import java.util.Arrays; - -import junit.framework.TestCase; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.io.DatabaseIO; -import org.jumpmind.symmetric.db.ddl.io.LocalEntityResolver; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.ForeignKey; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.IndexColumn; -import org.jumpmind.symmetric.db.ddl.model.ModelException; -import org.jumpmind.symmetric.db.ddl.model.Reference; -import org.jumpmind.symmetric.db.ddl.model.Table; - -/* - * Tests the database reading/writing via the {@link org.jumpmind.symmetric.ddl.io.DatabaseIO} class. - * - * @version $Revision: 289996 $ - */ -public class TestDatabaseIO extends TestCase -{ - /* The log for the tests. */ - private final Log _log = LogFactory.getLog(TestDatabaseIO.class); - - /* - * Reads the database model from the given string. - * - * @param modelAsXml The database model XML - * @return The database model - */ - private Database readModel(String modelAsXml) - { - DatabaseIO dbIO = new DatabaseIO(); - - dbIO.setUseInternalDtd(true); - dbIO.setValidateXml(false); - return dbIO.read(new StringReader(modelAsXml)); - } - - /* - * Writes the given database model to a string. - * - * @param model The database model - * @return The database model XML - */ - private String writeModel(Database model) - { - StringWriter writer = new StringWriter(); - - new DatabaseIO().write(model, writer); - return StringUtils.replace(writer.toString(), "\r\n", "\n"); - } - - /* - * Tests a simple database model. - */ - public void testSimple() throws Exception - { - Database model = readModel( - "\n" + - " \n" + - " \n" + - "
\n" + - "
"); - - assertEquals("test", - model.getName()); - assertEquals(1, - model.getTableCount()); - - Table table = model.getTable(0); - - assertEquals("SomeTable", - table.getName()); - assertEquals("Some table", - table.getDescription()); - assertEquals(0, table.getAutoIncrementColumns().length); - assertEquals(1, - table.getColumnCount()); - assertEquals(0, - table.getForeignKeyCount()); - assertEquals(0, - table.getIndexCount()); - - Column column = table.getColumn(0); - - assertEquals("ID", - column.getName()); - assertEquals("INTEGER", - column.getType()); - assertEquals(Types.INTEGER, - column.getTypeCode()); - assertTrue(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The primary key", - column.getDescription()); - assertEquals("javaId", column.getJavaName()); - assertEquals( - "\n\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
\n", - writeModel(model)); - } - - /* - * Tests a database model containing a foreignkey. - */ - public void testForeignkey() throws Exception - { - Database model = readModel( - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - assertEquals("test", - model.getName()); - assertEquals(2, - model.getTableCount()); - - Table someTable = model.getTable(0); - - assertEquals("SomeTable", - someTable.getName()); - assertEquals("Some table", - someTable.getDescription()); - assertEquals(0, someTable.getAutoIncrementColumns().length); - assertEquals(1, - someTable.getColumnCount()); - assertEquals(0, - someTable.getForeignKeyCount()); - assertEquals(0, - someTable.getIndexCount()); - - Column pkColumn = someTable.getColumn(0); - - assertEquals("ID", - pkColumn.getName()); - assertEquals("VARCHAR", - pkColumn.getType()); - assertEquals(Types.VARCHAR, - pkColumn.getTypeCode()); - assertEquals(16, - pkColumn.getSizeAsInt()); - assertTrue(pkColumn.isPrimaryKey()); - assertTrue(pkColumn.isRequired()); - assertFalse(pkColumn.isAutoIncrement()); - assertNull(pkColumn.getDefaultValue()); - assertEquals("The primary key", - pkColumn.getDescription()); - - Table anotherTable = model.getTable(1); - - assertEquals("AnotherTable", - anotherTable.getName()); - assertEquals("And another table", - anotherTable.getDescription()); - assertEquals(0, anotherTable.getAutoIncrementColumns().length); - assertEquals(1, - anotherTable.getColumnCount()); - assertEquals(1, - anotherTable.getForeignKeyCount()); - assertEquals(0, - anotherTable.getIndexCount()); - - Column fkColumn = anotherTable.getColumn(0); - - assertEquals("Some_ID", - fkColumn.getName()); - assertEquals("VARCHAR", - fkColumn.getType()); - assertEquals(Types.VARCHAR, - fkColumn.getTypeCode()); - assertEquals(16, - fkColumn.getSizeAsInt()); - assertFalse(fkColumn.isPrimaryKey()); - assertFalse(fkColumn.isRequired()); - assertFalse(fkColumn.isAutoIncrement()); - assertEquals("The foreign key", - fkColumn.getDescription()); - - ForeignKey fk = anotherTable.getForeignKey(0); - - assertNull(fk.getName()); - assertEquals(someTable, - fk.getForeignTable()); - assertEquals(someTable.getName(), - fk.getForeignTableName()); - assertEquals(1, - fk.getReferenceCount()); - - Reference ref = fk.getFirstReference(); - - assertEquals(fkColumn, - ref.getLocalColumn()); - assertEquals("Some_ID", - ref.getLocalColumnName()); - assertEquals(pkColumn, - ref.getForeignColumn()); - assertEquals("ID", - ref.getForeignColumnName()); - - assertEquals( - "\n\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
\n", - writeModel(model)); - } - - /* - * Tests a database model with indices. - */ - public void testIndices1() throws Exception - { - Database model = readModel( - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - assertEquals("test", - model.getName()); - assertEquals(1, - model.getTableCount()); - - Table table = model.getTable(0); - - assertEquals("TableWidthIndex", - table.getName()); - assertNull(table.getDescription()); - assertEquals(0, table.getAutoIncrementColumns().length); - assertEquals(3, - table.getColumnCount()); - assertEquals(0, - table.getForeignKeyCount()); - assertEquals(2, - table.getIndexCount()); - - Column column = table.getColumn(0); - - assertEquals("id", - column.getName()); - assertEquals("DOUBLE", - column.getType()); - assertEquals(Types.DOUBLE, - column.getTypeCode()); - assertTrue(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertNull(column.getDefaultValue()); - assertNull(column.getDescription()); - - column = table.getColumn(1); - - assertEquals("when", - column.getName()); - assertEquals("TIMESTAMP", - column.getType()); - assertEquals(Types.TIMESTAMP, - column.getTypeCode()); - assertFalse(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertNull(column.getDescription()); - - column = table.getColumn(2); - - assertEquals("value", - column.getName()); - assertEquals("SMALLINT", - column.getType()); - assertEquals(Types.SMALLINT, - column.getTypeCode()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertEquals("1", - column.getDefaultValue()); - assertNull(column.getDescription()); - - Index index = table.getIndex(0); - - assertEquals("test index", - index.getName()); - assertFalse(index.isUnique()); - assertEquals(1, - index.getColumnCount()); - - IndexColumn indexColumn = index.getColumn(0); - - assertEquals("value", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - index = table.getIndex(1); - - assertNull(index.getName()); - assertFalse(index.isUnique()); - assertEquals(2, - index.getColumnCount()); - - indexColumn = index.getColumn(0); - - assertEquals("when", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - indexColumn = index.getColumn(1); - - assertEquals("id", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - assertEquals( - "\n\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
\n", - writeModel(model)); - } - - /* - * Tests a database model with indices, both uniques and non-uniques. - */ - public void testIndices2() throws Exception - { - Database model = readModel( - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - assertEquals("test", - model.getName()); - assertEquals(1, - model.getTableCount()); - - Table table = model.getTable(0); - - assertEquals("TableWidthIndices", - table.getName()); - assertNull(table.getDescription()); - assertEquals(2, - table.getColumnCount()); - assertEquals(0, - table.getForeignKeyCount()); - assertEquals(2, - table.getIndexCount()); - - Column column = table.getColumn(0); - - assertEquals("id", - column.getName()); - assertEquals("SMALLINT", - column.getType()); - assertEquals(Types.SMALLINT, - column.getTypeCode()); - assertFalse(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertTrue(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertNull(column.getDefaultValue()); - assertNull(column.getDescription()); - - assertEquals(1, table.getAutoIncrementColumns().length); - assertEquals(column, table.getAutoIncrementColumns()[0]); - - column = table.getColumn(1); - - assertEquals("when", - column.getName()); - assertEquals("DATE", - column.getType()); - assertEquals(Types.DATE, - column.getTypeCode()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertNull(column.getDescription()); - - Index index = table.getIndex(0); - - assertEquals("important column", - index.getName()); - assertTrue(index.isUnique()); - assertEquals(1, - index.getColumnCount()); - - IndexColumn indexColumn = index.getColumn(0); - - assertEquals("id", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - index = table.getIndex(1); - - assertNull(index.getName()); - assertFalse(index.isUnique()); - assertEquals(1, - index.getColumnCount()); - - indexColumn = index.getColumn(0); - - assertEquals("when", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - assertEquals( - "\n\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
\n", - writeModel(model)); - } - - /* - * Tests a complex database model with multiple tables, foreign keys, indices and uniques. - */ - public void testComplex() throws Exception - { - // A = id:INTEGER, parentId:INTEGER, name:VARCHAR(32); fk 'parent' -> A (parentId -> id), unique(name) - // B = id:TIMESTAMP, aid:INTEGER, cid:CHAR(32) fk -> A (aid -> id), fk -> C (cid -> id), index(aid,cid) - // C = id:CHAR(32), text:LONGVARCHAR; index 'byText' (text) - - Database model = readModel( - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - assertEquals("test", - model.getName()); - assertEquals(3, - model.getTableCount()); - - // table A - - Table table = model.getTable(0); - - assertEquals("A", - table.getName()); - assertEquals("Table A", - table.getDescription()); - assertEquals(3, - table.getColumnCount()); - assertEquals(1, - table.getForeignKeyCount()); - assertEquals(1, - table.getIndexCount()); - - Column column = table.getColumn(0); - - assertEquals("id", - column.getName()); - assertEquals("INTEGER", - column.getType()); - assertEquals(Types.INTEGER, - column.getTypeCode()); - assertNull(column.getSize()); - assertEquals(0, - column.getSizeAsInt()); - assertTrue(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertTrue(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The primary key of table A", - column.getDescription()); - assertEquals(1, table.getAutoIncrementColumns().length); - assertEquals(column, - table.getAutoIncrementColumns()[0]); - - column = table.getColumn(1); - - assertEquals("parentId", - column.getName()); - assertEquals("INTEGER", - column.getType()); - assertEquals(Types.INTEGER, - column.getTypeCode()); - assertNull(column.getSize()); - assertEquals(0, - column.getSizeAsInt()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The field for the foreign key parent", - column.getDescription()); - - column = table.getColumn(2); - - assertEquals("name", - column.getName()); - assertEquals("VARCHAR", - column.getType()); - assertEquals(Types.VARCHAR, - column.getTypeCode()); - assertEquals("32", - column.getSize()); - assertEquals(32, - column.getSizeAsInt()); - assertFalse(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The name", - column.getDescription()); - - ForeignKey fk = table.getForeignKey(0); - - assertEquals("parent", - fk.getName()); - assertEquals(table, - fk.getForeignTable()); - assertEquals("A", - fk.getForeignTableName()); - assertEquals(1, - fk.getReferenceCount()); - - Reference ref = fk.getFirstReference(); - - assertEquals(table.getColumn(1), - ref.getLocalColumn()); - assertEquals("parentId", - ref.getLocalColumnName()); - assertEquals(table.getColumn(0), - ref.getForeignColumn()); - assertEquals("id", - ref.getForeignColumnName()); - - Index index = table.getIndex(0); - - assertNull(index.getName()); - assertTrue(index.isUnique()); - assertEquals(1, - index.getColumnCount()); - - IndexColumn indexColumn = index.getColumn(0); - - assertEquals("name", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - // table B - - table = model.getTable(1); - - assertEquals("B", - table.getName()); - assertEquals("Table B", - table.getDescription()); - assertEquals(0, table.getAutoIncrementColumns().length); - assertEquals(3, - table.getColumnCount()); - assertEquals(2, - table.getForeignKeyCount()); - assertEquals(1, - table.getIndexCount()); - - column = table.getColumn(0); - - assertEquals("id", - column.getName()); - assertEquals("TIMESTAMP", - column.getType()); - assertEquals(Types.TIMESTAMP, - column.getTypeCode()); - assertNull(column.getSize()); - assertEquals(0, - column.getSizeAsInt()); - assertTrue(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The primary key of table B", - column.getDescription()); - - column = table.getColumn(1); - - assertEquals("aid", - column.getName()); - assertEquals("INTEGER", - column.getType()); - assertEquals(Types.INTEGER, - column.getTypeCode()); - assertNull(column.getSize()); - assertEquals(0, - column.getSizeAsInt()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The field for the foreign key towards A", - column.getDescription()); - - column = table.getColumn(2); - - assertEquals("cid", - column.getName()); - assertEquals("CHAR", - column.getType()); - assertEquals(Types.CHAR, - column.getTypeCode()); - assertEquals("32", - column.getSize()); - assertEquals(32, - column.getSizeAsInt()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The field for the foreign key towards C", - column.getDescription()); - - fk = table.getForeignKey(0); - - assertNull(fk.getName()); - assertEquals(model.getTable(0), - fk.getForeignTable()); - assertEquals("A", - fk.getForeignTableName()); - assertEquals(1, - fk.getReferenceCount()); - - ref = fk.getFirstReference(); - - assertEquals(table.getColumn(1), - ref.getLocalColumn()); - assertEquals("aid", - ref.getLocalColumnName()); - assertEquals(model.getTable(0).getColumn(0), - ref.getForeignColumn()); - assertEquals("id", - ref.getForeignColumnName()); - - fk = table.getForeignKey(1); - - assertNull(fk.getName()); - assertEquals(model.getTable(2), - fk.getForeignTable()); - assertEquals("C", - fk.getForeignTableName()); - assertEquals(1, - fk.getReferenceCount()); - - ref = fk.getFirstReference(); - - assertEquals(table.getColumn(2), - ref.getLocalColumn()); - assertEquals("cid", - ref.getLocalColumnName()); - assertEquals(model.getTable(2).getColumn(0), - ref.getForeignColumn()); - assertEquals("id", - ref.getForeignColumnName()); - - index = table.getIndex(0); - - assertNull(index.getName()); - assertFalse(index.isUnique()); - assertEquals(2, - index.getColumnCount()); - - indexColumn = index.getColumn(0); - - assertEquals("aid", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - indexColumn = index.getColumn(1); - - assertEquals("cid", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - // table C - - table = model.getTable(2); - - assertEquals("C", - table.getName()); - assertEquals("Table C", - table.getDescription()); - assertEquals(0, table.getAutoIncrementColumns().length); - assertEquals(2, - table.getColumnCount()); - assertEquals(0, - table.getForeignKeyCount()); - assertEquals(1, - table.getIndexCount()); - - column = table.getColumn(0); - - assertEquals("id", - column.getName()); - assertEquals("CHAR", - column.getType()); - assertEquals(Types.CHAR, - column.getTypeCode()); - assertEquals("32", - column.getSize()); - assertEquals(32, - column.getSizeAsInt()); - assertTrue(column.isPrimaryKey()); - assertTrue(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The primary key of table C", - column.getDescription()); - - column = table.getColumn(1); - - assertEquals("text", - column.getName()); - assertEquals("LONGVARCHAR", - column.getType()); - assertEquals(Types.LONGVARCHAR, - column.getTypeCode()); - assertNull(column.getSize()); - assertEquals(0, - column.getSizeAsInt()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertEquals("The text", - column.getDescription()); - - index = table.getIndex(0); - - assertEquals("byText", - index.getName()); - assertFalse(index.isUnique()); - assertEquals(1, - index.getColumnCount()); - - indexColumn = index.getColumn(0); - - assertEquals("text", - indexColumn.getName()); - assertNull(indexColumn.getSize()); - - assertEquals( - "\n\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
\n", - writeModel(model)); - } - - /* - * Tests that an exception is generated when the database element has no name attribute. - */ - public void testDatabaseWithoutName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when the table element has no name attribute. - */ - public void testTableWithoutName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when two table elements have the same value in their name attributes. - */ - public void testTwoTablesWithTheSameName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - "
\n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when the column element has no name attribute. - */ - public void testColumnWithoutName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when two column elements within the same table - * element have the same value in their name attributes. - */ - public void testTwoColumnsWithTheSameName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when the column element has no type attribute. - */ - public void testColumnWithoutType() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when two indices have the same value in their name attributes. - */ - public void testTwoIndicesWithTheSameName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when two unique indices have the - * same value in their name attributes. - */ - public void testTwoUniqueIndicesWithTheSameName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Tests that an exception is generated when a unique and a normal index - * have the same value in their name attributes. - */ - public void testUniqueAndNormalIndexWithTheSameName() - { - try - { - readModel( - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - fail(); - } - catch (ModelException ex) - {} - } - - /* - * Regression test ensuring that wrong XML is not read (regarding betwixt issue #37369). - */ - public void testFaultReadOfTable() - { - Database database = readModel( - "\n" + - " \n" + - ""); - - _log.debug("Table : " + Arrays.asList(database.getTables())); - assertEquals(0, database.getTableCount()); - } - - /* - * Tests the Torque/Turbine extensions BOOLEANINT & BOOLEANCHAR. - */ - public void testTurbineExtension() throws Exception - { - Database model = readModel( - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"); - - assertEquals("test", - model.getName()); - assertEquals(1, - model.getTableCount()); - - Table table = model.getTable(0); - - assertEquals("SomeTable", - table.getName()); - assertNull(table.getDescription()); - assertEquals(0, table.getAutoIncrementColumns().length); - assertEquals(2, - table.getColumnCount()); - assertEquals(0, - table.getForeignKeyCount()); - assertEquals(0, - table.getIndexCount()); - - Column column = table.getColumn(0); - - assertEquals("intField", - column.getName()); - assertEquals("TINYINT", - column.getType()); - assertEquals(Types.TINYINT, - column.getTypeCode()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertNull(column.getDescription()); - - column = table.getColumn(1); - - assertEquals("charField", - column.getName()); - assertEquals("CHAR", - column.getType()); - assertEquals(Types.CHAR, - column.getTypeCode()); - assertFalse(column.isPrimaryKey()); - assertFalse(column.isRequired()); - assertFalse(column.isAutoIncrement()); - assertNull(column.getDefaultValue()); - assertNull(column.getDescription()); - - assertEquals( - "\n\n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
\n", - writeModel(model)); - } - - // TODO: Tests that include: - // * foreign key references undefined table - // * foreign key references undefined local column - // * foreign key references undefined foreign column - // * two foreign keys with the same name -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/package.html b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/package.html deleted file mode 100644 index cf944655dd..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/io/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -

- This package contains the tests for the reading and writing of schemas and data files. -

- - diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/TestArrayAccessAtTable.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/TestArrayAccessAtTable.java deleted file mode 100644 index 32e21d23b4..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/TestArrayAccessAtTable.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.jumpmind.symmetric.ddl.model; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Index; -import org.jumpmind.symmetric.db.ddl.model.NonUniqueIndex; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.model.UniqueIndex; - -import junit.framework.TestCase; - -/* - * Test case for DDLUTILS-6. - * - * @version $Revision: 289996 $ - */ -public class TestArrayAccessAtTable extends TestCase -{ - /* The tested table. */ - private Table _testedTable; - /* The first tested column. */ - private Column _column1; - /* The second tested column. */ - private Column _column2; - /* The tested unique index. */ - private UniqueIndex _uniqueIndex; - /* The tested non-unique index. */ - private NonUniqueIndex _nonUniqueIndex; - - /* - * {@inheritDoc} - */ - public void setUp() - { - _testedTable = new Table(); - - _column1 = new Column(); - _column1.setName("column1"); - _column1.setPrimaryKey(true); - - _column2 = new Column(); - _column2.setName("column2"); - - _testedTable.addColumn(_column1); - _testedTable.addColumn(_column2); - - _uniqueIndex = new UniqueIndex(); - _testedTable.addIndex(_uniqueIndex); - - _nonUniqueIndex = new NonUniqueIndex(); - _testedTable.addIndex(_nonUniqueIndex); - } - - /* - * Tests that the primary key columns are correctly extracted. - */ - public void testGetPrimaryKeyColumns() - { - Column[] primaryKeyColumns = _testedTable.getPrimaryKeyColumns(); - - assertEquals(1, - primaryKeyColumns.length); - assertSame(_column1, - primaryKeyColumns[0]); - } - - /* - * Tests that the columns are correctly extracted. - */ - public void testGetColumns() - { - Column[] columns = _testedTable.getColumns(); - - assertEquals(2, - columns.length); - assertSame(_column1, - columns[0]); - assertSame(_column2, - columns[1]); - } - - /* - * Tests that the non-unique indices are correctly extracted. - */ - public void testGetNonUniqueIndices() - { - Index[] nonUniqueIndices = _testedTable.getNonUniqueIndices(); - - assertEquals(1, - nonUniqueIndices.length); - assertSame(_nonUniqueIndex, - nonUniqueIndices[0]); - } - - /* - * Tests that the unique indices are correctly extracted. - */ - public void testGetUniqueIndices() - { - Index[] uniqueIndices = _testedTable.getUniqueIndices(); - - assertEquals(1, - uniqueIndices.length); - assertSame(_uniqueIndex, - uniqueIndices[0]); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/package.html b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/package.html deleted file mode 100644 index 7748d0830b..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/model/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -

- This package contains the tests for the model handling. -

- - diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/package.html b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/package.html deleted file mode 100644 index c579f5e86a..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -

- This package contains the base and the runner classes for the tests. -

- - diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestCloudscapePlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestCloudscapePlatform.java deleted file mode 100644 index c9e36b4c82..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestCloudscapePlatform.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.cloudscape.CloudscapePlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Cloudscape platform. - * - * @version $Revision: 231110 $ - */ -public class TestCloudscapePlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return CloudscapePlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\";\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BLOB,\n"+ - " \"COL_BIGINT\" BIGINT,\n"+ - " \"COL_BINARY\" CHAR(254) FOR BIT DATA,\n"+ - " \"COL_BIT\" SMALLINT,\n"+ - " \"COL_BLOB\" BLOB,\n"+ - " \"COL_BOOLEAN\" SMALLINT,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" CLOB,\n"+ - " \"COL_DATALINK\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0),\n"+ - " \"COL_DISTINCT\" BLOB,\n"+ - " \"COL_DOUBLE\" DOUBLE PRECISION,\n"+ - " \"COL_FLOAT\" DOUBLE PRECISION,\n"+ - " \"COL_INTEGER\" INTEGER,\n"+ - " \"COL_JAVA_OBJECT\" BLOB,\n"+ - " \"COL_LONGVARBINARY\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_LONGVARCHAR\" LONG VARCHAR,\n"+ - " \"COL_NULL\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0),\n"+ - " \"COL_OTHER\" BLOB,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" BLOB,\n"+ - " \"COL_TIME\" TIME,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" VARCHAR(15) FOR BIT DATA,\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"constraints\";\n" + - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INTEGER GENERATED ALWAYS AS IDENTITY,\n"+ - " \"COL_NOT_NULL\" CHAR(100) FOR BIT DATA NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE PRECISION DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" BIGINT GENERATED ALWAYS AS IDENTITY,\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\";\n"+ - "DROP TABLE \"table3\";\n"+ - "DROP TABLE \"table2\";\n"+ - "DROP TABLE \"table1\";\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INTEGER,\n"+ - " \"COL_INDEX_1\" CHAR(100) FOR BIT DATA NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE PRECISION NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_FK_1\" INTEGER,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Cloudscape requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\";\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDB2Platform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDB2Platform.java deleted file mode 100644 index 4719f3b508..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDB2Platform.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.db2.Db2Platform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the DB2 platform. - * - * @version $Revision: 231110 $ - */ -public class TestDB2Platform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return Db2Platform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\";\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BLOB,\n"+ - " \"COL_BIGINT\" BIGINT,\n"+ - " \"COL_BINARY\" CHAR(254) FOR BIT DATA,\n"+ - " \"COL_BIT\" SMALLINT,\n"+ - " \"COL_BLOB\" BLOB,\n"+ - " \"COL_BOOLEAN\" SMALLINT,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" CLOB,\n"+ - " \"COL_DATALINK\" DATALINK,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0),\n"+ // only 18 characters allowed for identifiers - " \"COL_DISTINCT\" DISTINCT,\n"+ - " \"COL_DOUBLE\" DOUBLE,\n"+ - " \"COL_FLOAT\" DOUBLE,\n"+ - " \"COL_INTEGER\" INTEGER,\n"+ - " \"COL_JAVA_OBJECT\" BLOB,\n"+ - " \"COL_LONGVARBINARY\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_LONGVARCHAR\" LONG VARCHAR,\n"+ - " \"COL_NULL\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_NUMERIC\" DECIMAL(15,0),\n"+ - " \"COL_OTHER\" BLOB,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" REF,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" BLOB,\n"+ - " \"COL_TIME\" TIME,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" VARCHAR(15) FOR BIT DATA,\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"constraints\";\n" + - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INTEGER GENERATED BY DEFAULT AS IDENTITY,\n"+ - " \"COL_NOT_NULL\" CHAR(100) FOR BIT DATA NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE DEFAULT -2.0 NOT NULL,\n"+ // only 18 characters allowed for identifiers - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" BIGINT GENERATED BY DEFAULT AS IDENTITY,\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\";\n"+ - "DROP TABLE \"table3\";\n"+ - "DROP TABLE \"table2\";\n"+ - "DROP TABLE \"table1\";\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INTEGER,\n"+ - " \"COL_INDEX_1\" CHAR(100) FOR BIT DATA NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_FK_1\" INTEGER,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Db2 requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\";\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDerbyPlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDerbyPlatform.java deleted file mode 100644 index 4d9150de6e..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestDerbyPlatform.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.derby.DerbyPlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Derby platform. - * - * @version $Revision: 231110 $ - */ -public class TestDerbyPlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return DerbyPlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\";\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BLOB,\n"+ - " \"COL_BIGINT\" BIGINT,\n"+ - " \"COL_BINARY\" CHAR(254) FOR BIT DATA,\n"+ - " \"COL_BIT\" SMALLINT,\n"+ - " \"COL_BLOB\" BLOB,\n"+ - " \"COL_BOOLEAN\" SMALLINT,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" CLOB,\n"+ - " \"COL_DATALINK\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0),\n"+ - " \"COL_DISTINCT\" BLOB,\n"+ - " \"COL_DOUBLE\" DOUBLE,\n"+ - " \"COL_FLOAT\" DOUBLE,\n"+ - " \"COL_INTEGER\" INTEGER,\n"+ - " \"COL_JAVA_OBJECT\" BLOB,\n"+ - " \"COL_LONGVARBINARY\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_LONGVARCHAR\" LONG VARCHAR,\n"+ - " \"COL_NULL\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0),\n"+ - " \"COL_OTHER\" BLOB,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" LONG VARCHAR FOR BIT DATA,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" BLOB,\n"+ - " \"COL_TIME\" TIME,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" VARCHAR(15) FOR BIT DATA,\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"constraints\";\n" + - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INTEGER GENERATED BY DEFAULT AS IDENTITY,\n"+ - " \"COL_NOT_NULL\" CHAR(100) FOR BIT DATA NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" BIGINT GENERATED BY DEFAULT AS IDENTITY,\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\";\n"+ - "DROP TABLE \"table3\";\n"+ - "DROP TABLE \"table2\";\n"+ - "DROP TABLE \"table1\";\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INTEGER,\n"+ - " \"COL_INDEX_1\" CHAR(100) FOR BIT DATA NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_FK_1\" INTEGER,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Derby requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\";\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestFirebirdPlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestFirebirdPlatform.java deleted file mode 100644 index 0317d05dd4..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestFirebirdPlatform.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.firebird.FirebirdPlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Firebird platform. - * - * @version $Revision: 231110 $ - */ -public class TestFirebirdPlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return FirebirdPlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\";\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BLOB ,\n"+ - " \"COL_BIGINT\" BIGINT,\n"+ - " \"COL_BINARY\" BLOB,\n"+ - " \"COL_BIT\" SMALLINT,\n"+ - " \"COL_BLOB\" BLOB ,\n"+ - " \"COL_BOOLEAN\" SMALLINT,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" BLOB SUB_TYPE TEXT,\n"+ - " \"COL_DATALINK\" BLOB,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0),\n"+ - " \"COL_DISTINCT\" BLOB,\n"+ - " \"COL_DOUBLE\" DOUBLE PRECISION,\n"+ - " \"COL_FLOAT\" DOUBLE PRECISION,\n"+ - " \"COL_INTEGER\" INTEGER,\n"+ - " \"COL_JAVA_OBJECT\" BLOB,\n"+ - " \"COL_LONGVARBINARY\" BLOB,\n"+ - " \"COL_LONGVARCHAR\" BLOB SUB_TYPE TEXT,\n"+ - " \"COL_NULL\" BLOB,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0),\n"+ - " \"COL_OTHER\" BLOB,\n"+ - " \"COL_REAL\" FLOAT,\n"+ - " \"COL_REF\" BLOB,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" BLOB,\n"+ - " \"COL_TIME\" TIME,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" BLOB(15),\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TRIGGER \"trg_constraints_OL_PK_AUTO_INCR\";\n" + - "DROP GENERATOR \"gen_constraints_OL_PK_AUTO_INCR\";\n" + - "DROP TRIGGER \"trg_constraints_COL_AUTO_INCR\";\n" + - "DROP GENERATOR \"gen_constraints_COL_AUTO_INCR\";\n" + - "DROP TABLE \"constraints\";\n"+ - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INTEGER,\n"+ - " \"COL_NOT_NULL\" BLOB(100) NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE PRECISION DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" BIGINT,\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n"+ - "CREATE GENERATOR \"gen_constraints_OL_PK_AUTO_INCR\";\n" + - "CREATE TRIGGER \"trg_constraints_OL_PK_AUTO_INCR\" FOR \"constraints\"\n"+ - "ACTIVE BEFORE INSERT POSITION 0 AS\n"+ - "BEGIN IF (NEW.\"COL_PK_AUTO_INCR\" IS NULL) THEN NEW.\"COL_PK_AUTO_INCR\" = GEN_ID(\"gen_constraints_OL_PK_AUTO_INCR\", 1); END;\n"+ - "CREATE GENERATOR \"gen_constraints_COL_AUTO_INCR\";\n" + - "CREATE TRIGGER \"trg_constraints_COL_AUTO_INCR\" FOR \"constraints\"\n"+ - "ACTIVE BEFORE INSERT POSITION 0 AS\n"+ - "BEGIN IF (NEW.\"COL_AUTO_INCR\" IS NULL) THEN NEW.\"COL_AUTO_INCR\" = GEN_ID(\"gen_constraints_COL_AUTO_INCR\", 1); END;\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_F_COL_FK_2_table1\";\n"+ - "DROP TABLE \"table3\";\n"+ - "DROP TABLE \"table2\";\n"+ - "DROP TABLE \"table1\";\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INTEGER,\n"+ - " \"COL_INDEX_1\" BLOB(100) NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE PRECISION NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_FK_1\" INTEGER,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_F_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Firebird requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\";\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestHsqlDbPlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestHsqlDbPlatform.java deleted file mode 100644 index 1aed0f2310..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestHsqlDbPlatform.java +++ /dev/null @@ -1,180 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.hsqldb.HsqlDbPlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Hsqldb platform. - * - * @version $Revision: 231110 $ - */ -public class TestHsqlDbPlatform extends TestPlatformBase -{ - /* The database schema for testing column constraints. This is an version adapted for HsqlDb. */ - public static final String COLUMN_CONSTRAINT_TEST_SCHEMA = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return HsqlDbPlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\" IF EXISTS;\n" + // - "CREATE TABLE \"coltype\"\n" + // - "(\n" + // - " \"COL_ARRAY\" LONGVARBINARY,\n"+ - " \"COL_BIGINT\" BIGINT,\n"+ - " \"COL_BINARY\" BINARY("+Integer.MAX_VALUE+"),\n"+ - " \"COL_BIT\" BOOLEAN,\n"+ - " \"COL_BLOB\" LONGVARBINARY,\n"+ - " \"COL_BOOLEAN\" BOOLEAN,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" LONGVARCHAR,\n"+ - " \"COL_DATALINK\" LONGVARBINARY,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0),\n"+ - " \"COL_DISTINCT\" LONGVARBINARY,\n"+ - " \"COL_DOUBLE\" DOUBLE,\n"+ - " \"COL_FLOAT\" DOUBLE,\n"+ - " \"COL_INTEGER\" INTEGER,\n"+ - " \"COL_JAVA_OBJECT\" OBJECT,\n"+ - " \"COL_LONGVARBINARY\" LONGVARBINARY,\n"+ - " \"COL_LONGVARCHAR\" LONGVARCHAR,\n"+ - " \"COL_NULL\" LONGVARBINARY,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0),\n"+ - " \"COL_OTHER\" OTHER,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" LONGVARBINARY,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" LONGVARBINARY,\n"+ - " \"COL_TIME\" TIME,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" VARBINARY(15),\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"constraints\" IF EXISTS;\n" + - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INTEGER IDENTITY,\n"+ - " \"COL_NOT_NULL\" BINARY(100) NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\";\n"+ - "DROP TABLE \"table3\" IF EXISTS;\n"+ - "DROP TABLE \"table2\" IF EXISTS;\n"+ - "DROP TABLE \"table1\" IF EXISTS;\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INTEGER,\n"+ - " \"COL_INDEX_1\" BINARY(100) NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_FK_1\" INTEGER,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where HsqlDb requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\" IF EXISTS;\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestInterbasePlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestInterbasePlatform.java deleted file mode 100644 index 18fb79edd9..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestInterbasePlatform.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.interbase.InterbasePlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Interbase platform. - * - * @version $Revision: 231110 $ - */ -public class TestInterbasePlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return InterbasePlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\";\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BLOB ,\n"+ - " \"COL_BIGINT\" NUMERIC(18,0),\n"+ - " \"COL_BINARY\" BLOB,\n"+ - " \"COL_BIT\" SMALLINT,\n"+ - " \"COL_BLOB\" BLOB ,\n"+ - " \"COL_BOOLEAN\" SMALLINT,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" BLOB SUB_TYPE TEXT,\n"+ - " \"COL_DATALINK\" BLOB,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0),\n"+ - " \"COL_DISTINCT\" BLOB,\n"+ - " \"COL_DOUBLE\" DOUBLE PRECISION,\n"+ - " \"COL_FLOAT\" DOUBLE PRECISION,\n"+ - " \"COL_INTEGER\" INTEGER,\n"+ - " \"COL_JAVA_OBJECT\" BLOB,\n"+ - " \"COL_LONGVARBINARY\" BLOB,\n"+ - " \"COL_LONGVARCHAR\" VARCHAR("+InterbasePlatform.SWITCH_TO_LONGVARCHAR_SIZE+"),\n"+ - " \"COL_NULL\" BLOB,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0),\n"+ - " \"COL_OTHER\" BLOB,\n"+ - " \"COL_REAL\" FLOAT,\n"+ - " \"COL_REF\" BLOB,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" BLOB,\n"+ - " \"COL_TIME\" TIME,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" BLOB,\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TRIGGER \"trg_constraints_OL_PK_AUTO_INCR\";\n"+ - "DROP GENERATOR \"gen_constraints_OL_PK_AUTO_INCR\";\n" + - "DROP TRIGGER \"trg_constraints_COL_AUTO_INCR\";\n"+ - "DROP GENERATOR \"gen_constraints_COL_AUTO_INCR\";\n" + - "DROP TABLE \"constraints\";\n"+ - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INTEGER,\n"+ - " \"COL_NOT_NULL\" BLOB NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE PRECISION DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" NUMERIC(18,0),\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n"+ - "CREATE GENERATOR \"gen_constraints_OL_PK_AUTO_INCR\";\n" + - "CREATE TRIGGER \"trg_constraints_OL_PK_AUTO_INCR\" FOR \"constraints\"\n"+ - "ACTIVE BEFORE INSERT POSITION 0 AS\n"+ - "BEGIN IF (NEW.\"COL_PK_AUTO_INCR\" IS NULL) THEN NEW.\"COL_PK_AUTO_INCR\" = GEN_ID(\"gen_constraints_OL_PK_AUTO_INCR\", 1); END;\n"+ - "CREATE GENERATOR \"gen_constraints_COL_AUTO_INCR\";\n" + - "CREATE TRIGGER \"trg_constraints_COL_AUTO_INCR\" FOR \"constraints\"\n"+ - "ACTIVE BEFORE INSERT POSITION 0 AS\n"+ - "BEGIN IF (NEW.\"COL_AUTO_INCR\" IS NULL) THEN NEW.\"COL_AUTO_INCR\" = GEN_ID(\"gen_constraints_COL_AUTO_INCR\", 1); END;\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_F_COL_FK_2_table1\";\n"+ - "DROP TABLE \"table3\";\n"+ - "DROP TABLE \"table2\";\n"+ - "DROP TABLE \"table1\";\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INTEGER,\n"+ - " \"COL_INDEX_1\" BLOB NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE PRECISION NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_FK_1\" INTEGER,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_F_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Firebird requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\";\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMSSqlPlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMSSqlPlatform.java deleted file mode 100644 index 75b6d80ebd..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMSSqlPlatform.java +++ /dev/null @@ -1,353 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.apache.oro.text.regex.MatchResult; -import org.apache.oro.text.regex.Pattern; -import org.apache.oro.text.regex.PatternMatcher; -import org.apache.oro.text.regex.PatternMatcherInput; -import org.apache.oro.text.regex.Perl5Compiler; -import org.apache.oro.text.regex.Perl5Matcher; -import org.jumpmind.symmetric.db.ddl.platform.mssql.MSSqlPlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Microsoft SQL Server platform. - * - * @version $Revision: 231110 $ - */ -public class TestMSSqlPlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return MSSqlPlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - String sql = createTestDatabase(COLUMN_TEST_SCHEMA); - - // Since we have no way of knowing the auto-generated variables in the SQL, - // we simply try to extract it from the SQL - Pattern declarePattern = new Perl5Compiler().compile("DECLARE @([\\S]+) [^@]+@([\\S]+)"); - PatternMatcher matcher = new Perl5Matcher(); - String tableNameVar = "tablename"; - String constraintNameVar = "constraintname"; - - if (matcher.contains(sql, declarePattern)) - { - tableNameVar = matcher.getMatch().group(1); - constraintNameVar = matcher.getMatch().group(2); - } - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'coltype')\n"+ - "BEGIN\n"+ - " DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + " nvarchar(256)\n"+ - " DECLARE refcursor CURSOR FOR\n"+ - " SELECT object_name(objs.parent_obj) tablename, objs.name constraintname\n"+ - " FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid\n"+ - " WHERE objs.xtype != 'PK' AND object_name(objs.parent_obj) = 'coltype' OPEN refcursor\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar + "\n"+ - " WHILE @@FETCH_STATUS = 0\n"+ - " BEGIN\n"+ - " EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar + "\n"+ - " END\n"+ - " CLOSE refcursor\n"+ - " DEALLOCATE refcursor\n"+ - " DROP TABLE \"coltype\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" IMAGE,\n"+ - " \"COL_BIGINT\" DECIMAL(19,0),\n"+ - " \"COL_BINARY\" BINARY(254),\n"+ - " \"COL_BIT\" BIT,\n"+ - " \"COL_BLOB\" IMAGE,\n"+ - " \"COL_BOOLEAN\" BIT,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" TEXT,\n"+ - " \"COL_DATALINK\" IMAGE,\n"+ - " \"COL_DATE\" DATETIME,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0),\n"+ - " \"COL_DISTINCT\" IMAGE,\n"+ - " \"COL_DOUBLE\" FLOAT,\n"+ - " \"COL_FLOAT\" FLOAT,\n"+ - " \"COL_INTEGER\" INT,\n"+ - " \"COL_JAVA_OBJECT\" IMAGE,\n"+ - " \"COL_LONGVARBINARY\" IMAGE,\n"+ - " \"COL_LONGVARCHAR\" TEXT,\n"+ - " \"COL_NULL\" IMAGE,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0),\n"+ - " \"COL_OTHER\" IMAGE,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" IMAGE,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" IMAGE,\n"+ - " \"COL_TIME\" DATETIME,\n"+ - " \"COL_TIMESTAMP\" DATETIME,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" VARBINARY(15),\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - sql); - } - - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - String sql = createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA); - - // Since we have no way of knowing the auto-generated variables in the SQL, - // we simply try to extract it from the SQL - Pattern declarePattern = new Perl5Compiler().compile("DECLARE @([\\S]+) [^@]+@([\\S]+)"); - PatternMatcher matcher = new Perl5Matcher(); - String tableNameVar = "tablename"; - String constraintNameVar = "constraintname"; - - if (matcher.contains(sql, declarePattern)) - { - tableNameVar = matcher.getMatch().group(1); - constraintNameVar = matcher.getMatch().group(2); - } - // Note that this is not valid SQL as a table can have only one identity column at most - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'constraints')\n"+ - "BEGIN\n"+ - " DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + " nvarchar(256)\n"+ - " DECLARE refcursor CURSOR FOR\n"+ - " SELECT object_name(objs.parent_obj) tablename, objs.name constraintname\n"+ - " FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid\n"+ - " WHERE objs.xtype != 'PK' AND object_name(objs.parent_obj) = 'constraints' OPEN refcursor\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar + "\n"+ - " WHILE @@FETCH_STATUS = 0\n"+ - " BEGIN\n"+ - " EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar + "\n"+ - " END\n"+ - " CLOSE refcursor\n"+ - " DEALLOCATE refcursor\n"+ - " DROP TABLE \"constraints\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INT IDENTITY(1,1),\n"+ - " \"COL_NOT_NULL\" BINARY(100) NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" FLOAT DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" DECIMAL(19,0) IDENTITY(1,1),\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n", - sql); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - String sql = createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA); - - // Since we have no way of knowing the auto-generated variables in the SQL, - // we simply try to extract it from the SQL - Pattern declarePattern = new Perl5Compiler().compile("DECLARE @([\\S]+) [^@]+@([\\S]+)"); - PatternMatcherInput input = new PatternMatcherInput(sql); - PatternMatcher matcher = new Perl5Matcher(); - String[] tableNameVars = { "tablename", "tablename", "tablename" }; - String[] constraintNameVars = { "constraintname", "constraintname", "constraintname" }; - - for (int idx = 0; (idx < 3) && matcher.contains(input, declarePattern); idx++) - { - MatchResult result = matcher.getMatch(); - - tableNameVars[idx] = result.group(1); - constraintNameVars[idx] = result.group(2); - input.setCurrentOffset(result.endOffset(2)); - } - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'F' AND name = 'testfk')\n"+ - " ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'F' AND name = 'table2_FK_COL_FK_1_COL_FK_2_table1')\n"+ - " ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\";\n"+ - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'table3')\n"+ - "BEGIN\n"+ - " DECLARE @" + tableNameVars[0] + " nvarchar(256), @" + constraintNameVars[0] + " nvarchar(256)\n"+ - " DECLARE refcursor CURSOR FOR\n"+ - " SELECT object_name(objs.parent_obj) tablename, objs.name constraintname\n"+ - " FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid\n"+ - " WHERE objs.xtype != 'PK' AND object_name(objs.parent_obj) = 'table3' OPEN refcursor\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVars[0] + ", @" + constraintNameVars[0] + "\n"+ - " WHILE @@FETCH_STATUS = 0\n"+ - " BEGIN\n"+ - " EXEC ('ALTER TABLE '+@" + tableNameVars[0] + "+' DROP CONSTRAINT '+@" + constraintNameVars[0] + ")\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVars[0] + ", @" + constraintNameVars[0] + "\n"+ - " END\n"+ - " CLOSE refcursor\n"+ - " DEALLOCATE refcursor\n"+ - " DROP TABLE \"table3\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'table2')\n"+ - "BEGIN\n"+ - " DECLARE @" + tableNameVars[1] + " nvarchar(256), @" + constraintNameVars[1] + " nvarchar(256)\n"+ - " DECLARE refcursor CURSOR FOR\n"+ - " SELECT object_name(objs.parent_obj) tablename, objs.name constraintname\n"+ - " FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid\n"+ - " WHERE objs.xtype != 'PK' AND object_name(objs.parent_obj) = 'table2' OPEN refcursor\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVars[1] + ", @" + constraintNameVars[1] + "\n"+ - " WHILE @@FETCH_STATUS = 0\n"+ - " BEGIN\n"+ - " EXEC ('ALTER TABLE '+@" + tableNameVars[1] + "+' DROP CONSTRAINT '+@" + constraintNameVars[1] + ")\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVars[1] + ", @" + constraintNameVars[1] + "\n"+ - " END\n"+ - " CLOSE refcursor\n"+ - " DEALLOCATE refcursor\n"+ - " DROP TABLE \"table2\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'table1')\n"+ - "BEGIN\n"+ - " DECLARE @" + tableNameVars[2] + " nvarchar(256), @" + constraintNameVars[2] + " nvarchar(256)\n"+ - " DECLARE refcursor CURSOR FOR\n"+ - " SELECT object_name(objs.parent_obj) tablename, objs.name constraintname\n"+ - " FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid\n"+ - " WHERE objs.xtype != 'PK' AND object_name(objs.parent_obj) = 'table1' OPEN refcursor\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVars[2] + ", @" + constraintNameVars[2] + "\n"+ - " WHILE @@FETCH_STATUS = 0\n"+ - " BEGIN\n"+ - " EXEC ('ALTER TABLE '+@" + tableNameVars[2] + "+' DROP CONSTRAINT '+@" + constraintNameVars[2] + ")\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVars[2] + ", @" + constraintNameVars[2] + "\n"+ - " END\n"+ - " CLOSE refcursor\n"+ - " DEALLOCATE refcursor\n"+ - " DROP TABLE \"table1\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INT,\n"+ - " \"COL_INDEX_1\" BINARY(100) NOT NULL,\n"+ - " \"COL_INDEX_2\" FLOAT NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INT,\n"+ - " \"COL_FK_1\" INT,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INT NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - sql); - } - - /* - * Tests the proper escaping of character sequences where Cloudscape requires it. - */ - public void testCharacterEscaping() throws Exception - { - String sql = createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE); - - // Since we have no way of knowing the auto-generated variables in the SQL, - // we simply try to extract it from the SQL - Pattern declarePattern = new Perl5Compiler().compile("DECLARE @([\\S]+) [^@]+@([\\S]+)"); - PatternMatcher matcher = new Perl5Matcher(); - String tableNameVar = "tablename"; - String constraintNameVar = "constraintname"; - - if (matcher.contains(sql, declarePattern)) - { - tableNameVar = matcher.getMatch().group(1); - constraintNameVar = matcher.getMatch().group(2); - } - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'escapedcharacters')\n"+ - "BEGIN\n"+ - " DECLARE @" + tableNameVar + " nvarchar(256), @" + constraintNameVar + " nvarchar(256)\n"+ - " DECLARE refcursor CURSOR FOR\n"+ - " SELECT object_name(objs.parent_obj) tablename, objs.name constraintname\n"+ - " FROM sysobjects objs JOIN sysconstraints cons ON objs.id = cons.constid\n"+ - " WHERE objs.xtype != 'PK' AND object_name(objs.parent_obj) = 'escapedcharacters' OPEN refcursor\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar + "\n"+ - " WHILE @@FETCH_STATUS = 0\n"+ - " BEGIN\n"+ - " EXEC ('ALTER TABLE '+@" + tableNameVar + "+' DROP CONSTRAINT '+@" + constraintNameVar + ")\n"+ - " FETCH NEXT FROM refcursor INTO @" + tableNameVar + ", @" + constraintNameVar + "\n"+ - " END\n"+ - " CLOSE refcursor\n"+ - " DEALLOCATE refcursor\n"+ - " DROP TABLE \"escapedcharacters\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INT,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - sql); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySql50Platform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySql50Platform.java deleted file mode 100644 index d161d6e767..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySql50Platform.java +++ /dev/null @@ -1,202 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.platform.CreationParameters; -import org.jumpmind.symmetric.db.ddl.platform.mysql.MySql50Platform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the MySQL platform. - * - * @version $Revision: 231110 $ - */ -public class TestMySql50Platform extends TestPlatformBase -{ - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return MySql50Platform.DATABASENAME; - } - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `coltype`;\n"+ - "CREATE TABLE `coltype`\n"+ - "(\n"+ - " `COL_ARRAY` LONGBLOB,\n"+ - " `COL_BIGINT` BIGINT,\n"+ - " `COL_BINARY` BINARY(254) NULL,\n"+ - " `COL_BIT` TINYINT(1),\n"+ - " `COL_BLOB` LONGBLOB NULL,\n"+ - " `COL_BOOLEAN` TINYINT(1),\n"+ - " `COL_CHAR` CHAR(15) NULL,\n"+ - " `COL_CLOB` LONGTEXT NULL,\n"+ - " `COL_DATALINK` MEDIUMBLOB,\n"+ - " `COL_DATE` DATE,\n"+ - " `COL_DECIMAL` DECIMAL(15,3),\n"+ - " `COL_DECIMAL_NOSCALE` DECIMAL(15,0),\n"+ - " `COL_DISTINCT` LONGBLOB,\n"+ - " `COL_DOUBLE` DOUBLE,\n"+ - " `COL_FLOAT` DOUBLE,\n"+ - " `COL_INTEGER` INTEGER,\n"+ - " `COL_JAVA_OBJECT` LONGBLOB,\n"+ - " `COL_LONGVARBINARY` MEDIUMBLOB NULL,\n"+ - " `COL_LONGVARCHAR` MEDIUMTEXT NULL,\n"+ - " `COL_NULL` MEDIUMBLOB,\n"+ - " `COL_NUMERIC` DECIMAL(15,0),\n"+ - " `COL_OTHER` LONGBLOB,\n"+ - " `COL_REAL` FLOAT,\n"+ - " `COL_REF` MEDIUMBLOB,\n"+ - " `COL_SMALLINT` SMALLINT,\n"+ - " `COL_STRUCT` LONGBLOB,\n"+ - " `COL_TIME` TIME,\n"+ - " `COL_TIMESTAMP` DATETIME,\n"+ - " `COL_TINYINT` SMALLINT,\n"+ - " `COL_VARBINARY` VARBINARY(15) NULL,\n"+ - " `COL_VARCHAR` VARCHAR(15) NULL\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - Database testDb = parseDatabaseFromString(COLUMN_CONSTRAINT_TEST_SCHEMA); - testDb.findTable("constraints").findColumn("COL_AUTO_INCR").setAutoIncrement(false); - testDb.findTable("constraints").findColumn("COL_PK_AUTO_INCR").setAutoIncrement(false); - - getPlatform().setSqlCommentsOn(false); - getPlatform().getSqlBuilder().createTables(testDb, true); - - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `constraints`;\n" + - "CREATE TABLE `constraints`\n"+ - "(\n"+ - " `COL_PK` VARCHAR(32) NULL,\n"+ - " `COL_PK_AUTO_INCR` INTEGER,\n"+ - " `COL_NOT_NULL` BINARY(100) NOT NULL,\n"+ - " `COL_NOT_NULL_DEFAULT` DOUBLE DEFAULT -2.0 NOT NULL,\n"+ - " `COL_DEFAULT` CHAR(4) DEFAULT 'test' NULL,\n"+ - " `COL_AUTO_INCR` BIGINT,\n"+ - " PRIMARY KEY (`COL_PK`, `COL_PK_AUTO_INCR`)\n"+ - ");\n", - getBuilderOutput()); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE `table3` DROP FOREIGN KEY `testfk`;\n"+ - "ALTER TABLE `table2` DROP FOREIGN KEY `table2_FK_COL_FK_1_COL_FK_2_table1`;\n"+ - "DROP TABLE IF EXISTS `table3`;\n"+ - "DROP TABLE IF EXISTS `table2`;\n"+ - "DROP TABLE IF EXISTS `table1`;\n"+ - "CREATE TABLE `table1`\n"+ - "(\n"+ - " `COL_PK_1` VARCHAR(32) NOT NULL,\n"+ - " `COL_PK_2` INTEGER,\n"+ - " `COL_INDEX_1` BINARY(100) NOT NULL,\n"+ - " `COL_INDEX_2` DOUBLE NOT NULL,\n"+ - " `COL_INDEX_3` CHAR(4) NULL,\n"+ - " PRIMARY KEY (`COL_PK_1`, `COL_PK_2`)\n"+ - ");\n"+ - "CREATE INDEX `testindex1` ON `table1` (`COL_INDEX_2`);\n"+ - "CREATE UNIQUE INDEX `testindex2` ON `table1` (`COL_INDEX_3`, `COL_INDEX_1`);\n"+ - "CREATE TABLE `table2`\n"+ - "(\n"+ - " `COL_PK` INTEGER,\n"+ - " `COL_FK_1` INTEGER,\n"+ - " `COL_FK_2` VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (`COL_PK`)\n"+ - ");\n"+ - "CREATE TABLE `table3`\n"+ - "(\n"+ - " `COL_PK` VARCHAR(16) NULL,\n"+ - " `COL_FK` INTEGER NOT NULL,\n"+ - " PRIMARY KEY (`COL_PK`)\n"+ - ");\n"+ - "ALTER TABLE `table2` ADD CONSTRAINT `table2_FK_COL_FK_1_COL_FK_2_table1` FOREIGN KEY (`COL_FK_1`, `COL_FK_2`) REFERENCES `table1` (`COL_PK_2`, `COL_PK_1`);\n"+ - "ALTER TABLE `table3` ADD CONSTRAINT `testfk` FOREIGN KEY (`COL_FK`) REFERENCES `table2` (`COL_PK`);\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the usage of creation parameters. - */ - public void testCreationParameters1() throws Exception - { - Database testDb = parseDatabaseFromString(COLUMN_CONSTRAINT_TEST_SCHEMA); - testDb.findTable("constraints").findColumn("COL_AUTO_INCR").setAutoIncrement(false); - testDb.findTable("constraints").findColumn("COL_PK_AUTO_INCR").setAutoIncrement(false); - CreationParameters params = new CreationParameters(); - - params.addParameter(testDb.getTable(0), - "ROW_FORMAT", - "COMPRESSED"); - params.addParameter(null, - "ENGINE", - "INNODB"); - - getPlatform().setSqlCommentsOn(false); - getPlatform().getSqlBuilder().createTables(testDb, params, true); - - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `constraints`;\n" + - "CREATE TABLE `constraints`\n"+ - "(\n"+ - " `COL_PK` VARCHAR(32) NULL,\n"+ - " `COL_PK_AUTO_INCR` INTEGER,\n"+ - " `COL_NOT_NULL` BINARY(100) NOT NULL,\n"+ - " `COL_NOT_NULL_DEFAULT` DOUBLE DEFAULT -2.0 NOT NULL,\n"+ - " `COL_DEFAULT` CHAR(4) DEFAULT 'test' NULL,\n"+ - " `COL_AUTO_INCR` BIGINT,\n"+ - " PRIMARY KEY (`COL_PK`, `COL_PK_AUTO_INCR`)\n"+ - ") ENGINE=INNODB ROW_FORMAT=COMPRESSED;\n", - getBuilderOutput()); - } - - /* - * Tests the proper escaping of character sequences where MySQL requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `escapedcharacters`;\n"+ - "CREATE TABLE `escapedcharacters`\n"+ - "(\n"+ - " `COL_PK` INTEGER,\n"+ - " `COL_TEXT` VARCHAR(128) DEFAULT '\\_ \\\' \\\" \\n \\r \\t \\\\ \\%' NULL,\n"+ - " PRIMARY KEY (`COL_PK`)\n"+ - ");\n", - createTestDatabase(TestMySqlPlatform.COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySqlPlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySqlPlatform.java deleted file mode 100644 index cd3238174f..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestMySqlPlatform.java +++ /dev/null @@ -1,216 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.platform.CreationParameters; -import org.jumpmind.symmetric.db.ddl.platform.mysql.MySqlPlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the MySQL platform. - * - * @version $Revision: 231110 $ - */ -public class TestMySqlPlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return MySqlPlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `coltype`;\n"+ - "CREATE TABLE `coltype`\n"+ - "(\n"+ - " `COL_ARRAY` LONGBLOB,\n"+ - " `COL_BIGINT` BIGINT,\n"+ - " `COL_BINARY` BINARY(254) NULL,\n"+ - " `COL_BIT` TINYINT(1),\n"+ - " `COL_BLOB` LONGBLOB NULL,\n"+ - " `COL_BOOLEAN` TINYINT(1),\n"+ - " `COL_CHAR` CHAR(15) NULL,\n"+ - " `COL_CLOB` LONGTEXT NULL,\n"+ - " `COL_DATALINK` MEDIUMBLOB,\n"+ - " `COL_DATE` DATE,\n"+ - " `COL_DECIMAL` DECIMAL(15,3),\n"+ - " `COL_DECIMAL_NOSCALE` DECIMAL(15,0),\n"+ - " `COL_DISTINCT` LONGBLOB,\n"+ - " `COL_DOUBLE` DOUBLE,\n"+ - " `COL_FLOAT` DOUBLE,\n"+ - " `COL_INTEGER` INTEGER,\n"+ - " `COL_JAVA_OBJECT` LONGBLOB,\n"+ - " `COL_LONGVARBINARY` MEDIUMBLOB NULL,\n"+ - " `COL_LONGVARCHAR` MEDIUMTEXT NULL,\n"+ - " `COL_NULL` MEDIUMBLOB,\n"+ - " `COL_NUMERIC` DECIMAL(15,0),\n"+ - " `COL_OTHER` LONGBLOB,\n"+ - " `COL_REAL` FLOAT,\n"+ - " `COL_REF` MEDIUMBLOB,\n"+ - " `COL_SMALLINT` SMALLINT,\n"+ - " `COL_STRUCT` LONGBLOB,\n"+ - " `COL_TIME` TIME,\n"+ - " `COL_TIMESTAMP` DATETIME,\n"+ - " `COL_TINYINT` SMALLINT,\n"+ - " `COL_VARBINARY` VARBINARY(15) NULL,\n"+ - " `COL_VARCHAR` VARCHAR(15) NULL\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - Database testDb = parseDatabaseFromString(COLUMN_CONSTRAINT_TEST_SCHEMA); - - testDb.findTable("constraints").findColumn("COL_AUTO_INCR").setAutoIncrement(false); - testDb.findTable("constraints").findColumn("COL_PK_AUTO_INCR").setAutoIncrement(false); - - getPlatform().setSqlCommentsOn(false); - getPlatform().getSqlBuilder().createTables(testDb, true); - - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `constraints`;\n" + - "CREATE TABLE `constraints`\n"+ - "(\n"+ - " `COL_PK` VARCHAR(32) NULL,\n"+ - " `COL_PK_AUTO_INCR` INTEGER,\n"+ - " `COL_NOT_NULL` BINARY(100) NOT NULL,\n"+ - " `COL_NOT_NULL_DEFAULT` DOUBLE DEFAULT -2.0 NOT NULL,\n"+ - " `COL_DEFAULT` CHAR(4) DEFAULT 'test' NULL,\n"+ - " `COL_AUTO_INCR` BIGINT,\n"+ - " PRIMARY KEY (`COL_PK`, `COL_PK_AUTO_INCR`)\n"+ - ");\n", - getBuilderOutput()); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE `table3` DROP FOREIGN KEY `testfk`;\n"+ - "ALTER TABLE `table2` DROP FOREIGN KEY `table2_FK_COL_FK_1_COL_FK_2_table1`;\n"+ - "DROP TABLE IF EXISTS `table3`;\n"+ - "DROP TABLE IF EXISTS `table2`;\n"+ - "DROP TABLE IF EXISTS `table1`;\n"+ - "CREATE TABLE `table1`\n"+ - "(\n"+ - " `COL_PK_1` VARCHAR(32) NOT NULL,\n"+ - " `COL_PK_2` INTEGER,\n"+ - " `COL_INDEX_1` BINARY(100) NOT NULL,\n"+ - " `COL_INDEX_2` DOUBLE NOT NULL,\n"+ - " `COL_INDEX_3` CHAR(4) NULL,\n"+ - " PRIMARY KEY (`COL_PK_1`, `COL_PK_2`)\n"+ - ");\n"+ - "CREATE INDEX `testindex1` ON `table1` (`COL_INDEX_2`);\n"+ - "CREATE UNIQUE INDEX `testindex2` ON `table1` (`COL_INDEX_3`, `COL_INDEX_1`);\n"+ - "CREATE TABLE `table2`\n"+ - "(\n"+ - " `COL_PK` INTEGER,\n"+ - " `COL_FK_1` INTEGER,\n"+ - " `COL_FK_2` VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (`COL_PK`)\n"+ - ");\n"+ - "CREATE TABLE `table3`\n"+ - "(\n"+ - " `COL_PK` VARCHAR(16) NULL,\n"+ - " `COL_FK` INTEGER NOT NULL,\n"+ - " PRIMARY KEY (`COL_PK`)\n"+ - ");\n"+ - "ALTER TABLE `table2` ADD CONSTRAINT `table2_FK_COL_FK_1_COL_FK_2_table1` FOREIGN KEY (`COL_FK_1`, `COL_FK_2`) REFERENCES `table1` (`COL_PK_2`, `COL_PK_1`);\n"+ - "ALTER TABLE `table3` ADD CONSTRAINT `testfk` FOREIGN KEY (`COL_FK`) REFERENCES `table2` (`COL_PK`);\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the usage of creation parameters. - */ - public void testCreationParameters1() throws Exception - { - Database testDb = parseDatabaseFromString(COLUMN_CONSTRAINT_TEST_SCHEMA); - - testDb.findTable("constraints").findColumn("COL_AUTO_INCR").setAutoIncrement(false); - testDb.findTable("constraints").findColumn("COL_PK_AUTO_INCR").setAutoIncrement(false); - - CreationParameters params = new CreationParameters(); - - params.addParameter(testDb.getTable(0), - "ROW_FORMAT", - "COMPRESSED"); - params.addParameter(null, - "ENGINE", - "INNODB"); - - getPlatform().setSqlCommentsOn(false); - getPlatform().getSqlBuilder().createTables(testDb, params, true); - - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `constraints`;\n" + - "CREATE TABLE `constraints`\n"+ - "(\n"+ - " `COL_PK` VARCHAR(32) NULL,\n"+ - " `COL_PK_AUTO_INCR` INTEGER,\n"+ - " `COL_NOT_NULL` BINARY(100) NOT NULL,\n"+ - " `COL_NOT_NULL_DEFAULT` DOUBLE DEFAULT -2.0 NOT NULL,\n"+ - " `COL_DEFAULT` CHAR(4) DEFAULT 'test' NULL,\n"+ - " `COL_AUTO_INCR` BIGINT,\n"+ - " PRIMARY KEY (`COL_PK`, `COL_PK_AUTO_INCR`)\n"+ - ") ENGINE=INNODB ROW_FORMAT=COMPRESSED;\n", - getBuilderOutput()); - } - - /* - * Tests the proper escaping of character sequences where MySQL requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE IF EXISTS `escapedcharacters`;\n"+ - "CREATE TABLE `escapedcharacters`\n"+ - "(\n"+ - " `COL_PK` INTEGER,\n"+ - " `COL_TEXT` VARCHAR(128) DEFAULT '\\_ \\\' \\\" \\n \\r \\t \\\\ \\%' NULL,\n"+ - " PRIMARY KEY (`COL_PK`)\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle8Platform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle8Platform.java deleted file mode 100644 index 01852a3c0f..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle8Platform.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle8Platform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Oracle 8 platform. - * - * @version $Revision: 231110 $ - */ -public class TestOracle8Platform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return Oracle8Platform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\" CASCADE CONSTRAINTS;\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BLOB,\n"+ - " \"COL_BIGINT\" NUMBER(38),\n"+ - " \"COL_BINARY\" RAW(254),\n"+ - " \"COL_BIT\" NUMBER(1),\n"+ - " \"COL_BLOB\" BLOB,\n"+ - " \"COL_BOOLEAN\" NUMBER(1),\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" CLOB,\n"+ - " \"COL_DATALINK\" BLOB,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" NUMBER(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" NUMBER(15,0),\n"+ - " \"COL_DISTINCT\" BLOB,\n"+ - " \"COL_DOUBLE\" DOUBLE PRECISION,\n"+ - " \"COL_FLOAT\" FLOAT,\n"+ - " \"COL_INTEGER\" NUMBER(22),\n"+ - " \"COL_JAVA_OBJECT\" BLOB,\n"+ - " \"COL_LONGVARBINARY\" BLOB,\n"+ - " \"COL_LONGVARCHAR\" CLOB,\n"+ - " \"COL_NULL\" BLOB,\n"+ - " \"COL_NUMERIC\" NUMBER(15,0),\n"+ - " \"COL_OTHER\" BLOB,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" BLOB,\n"+ - " \"COL_SMALLINT\" NUMBER(5),\n"+ - " \"COL_STRUCT\" BLOB,\n"+ - " \"COL_TIME\" DATE,\n"+ - " \"COL_TIMESTAMP\" DATE,\n"+ - " \"COL_TINYINT\" NUMBER(3),\n"+ - " \"COL_VARBINARY\" RAW(15),\n"+ - " \"COL_VARCHAR\" VARCHAR2(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TRIGGER \"trg_constraints_L_PK_AUTO_INCR\";\n"+ - "DROP SEQUENCE \"seq_constraints_L_PK_AUTO_INCR\";\n"+ - "DROP TRIGGER \"trg_constraints_COL_AUTO_INCR\";\n"+ - "DROP SEQUENCE \"seq_constraints_COL_AUTO_INCR\";\n"+ - "DROP TABLE \"constraints\" CASCADE CONSTRAINTS;\n"+ - "CREATE SEQUENCE \"seq_constraints_L_PK_AUTO_INCR\";\n"+ - "CREATE SEQUENCE \"seq_constraints_COL_AUTO_INCR\";\n"+ - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR2(32),\n"+ - " \"COL_PK_AUTO_INCR\" NUMBER(22),\n"+ - " \"COL_NOT_NULL\" RAW(100) NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE PRECISION DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" NUMBER(38),\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n"+ - "CREATE OR REPLACE TRIGGER \"trg_constraints_L_PK_AUTO_INCR\" BEFORE INSERT ON \"constraints\" FOR EACH ROW WHEN (new.\"COL_PK_AUTO_INCR\" IS NULL)\n"+ - "BEGIN SELECT \"seq_constraints_L_PK_AUTO_INCR\".nextval INTO :new.\"COL_PK_AUTO_INCR\" FROM dual; END;;\n"+ - "CREATE OR REPLACE TRIGGER \"trg_constraints_COL_AUTO_INCR\" BEFORE INSERT ON \"constraints\" FOR EACH ROW WHEN (new.\"COL_AUTO_INCR\" IS NULL)\n"+ - "BEGIN SELECT \"seq_constraints_COL_AUTO_INCR\".nextval INTO :new.\"COL_AUTO_INCR\" FROM dual; END;;\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"table3\" CASCADE CONSTRAINTS;\n"+ - "DROP TABLE \"table2\" CASCADE CONSTRAINTS;\n"+ - "DROP TABLE \"table1\" CASCADE CONSTRAINTS;\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR2(32) NOT NULL,\n"+ - " \"COL_PK_2\" NUMBER(22),\n"+ - " \"COL_INDEX_1\" RAW(100) NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE PRECISION NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" NUMBER(22),\n"+ - " \"COL_FK_1\" NUMBER(22),\n"+ - " \"COL_FK_2\" VARCHAR2(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR2(16),\n"+ - " \"COL_FK\" NUMBER(22) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_F_OL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Oracle requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\" CASCADE CONSTRAINTS;\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" NUMBER(22),\n"+ - " \"COL_TEXT\" VARCHAR2(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle9Platform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle9Platform.java deleted file mode 100644 index c90c8468c0..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestOracle9Platform.java +++ /dev/null @@ -1,167 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle9Platform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Oracle 9 platform. - * - * @version $Revision: 231110 $ - */ -public class TestOracle9Platform extends TestPlatformBase -{ - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return Oracle9Platform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\" CASCADE CONSTRAINTS;\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BLOB,\n"+ - " \"COL_BIGINT\" NUMBER(38),\n"+ - " \"COL_BINARY\" RAW(254),\n"+ - " \"COL_BIT\" NUMBER(1),\n"+ - " \"COL_BLOB\" BLOB,\n"+ - " \"COL_BOOLEAN\" NUMBER(1),\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" CLOB,\n"+ - " \"COL_DATALINK\" BLOB,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" NUMBER(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" NUMBER(15,0),\n"+ - " \"COL_DISTINCT\" BLOB,\n"+ - " \"COL_DOUBLE\" DOUBLE PRECISION,\n"+ - " \"COL_FLOAT\" FLOAT,\n"+ - " \"COL_INTEGER\" NUMBER(22),\n"+ - " \"COL_JAVA_OBJECT\" BLOB,\n"+ - " \"COL_LONGVARBINARY\" BLOB,\n"+ - " \"COL_LONGVARCHAR\" CLOB,\n"+ - " \"COL_NULL\" BLOB,\n"+ - " \"COL_NUMERIC\" NUMBER(15,0),\n"+ - " \"COL_OTHER\" BLOB,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" BLOB,\n"+ - " \"COL_SMALLINT\" NUMBER(5),\n"+ - " \"COL_STRUCT\" BLOB,\n"+ - " \"COL_TIME\" DATE,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" NUMBER(3),\n"+ - " \"COL_VARBINARY\" RAW(15),\n"+ - " \"COL_VARCHAR\" VARCHAR2(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TRIGGER \"trg_constraints_L_PK_AUTO_INCR\";\n"+ - "DROP SEQUENCE \"seq_constraints_L_PK_AUTO_INCR\";\n"+ - "DROP TRIGGER \"trg_constraints_COL_AUTO_INCR\";\n"+ - "DROP SEQUENCE \"seq_constraints_COL_AUTO_INCR\";\n"+ - "DROP TABLE \"constraints\" CASCADE CONSTRAINTS;\n"+ - "CREATE SEQUENCE \"seq_constraints_L_PK_AUTO_INCR\";\n"+ - "CREATE SEQUENCE \"seq_constraints_COL_AUTO_INCR\";\n"+ - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR2(32),\n"+ - " \"COL_PK_AUTO_INCR\" NUMBER(22),\n"+ - " \"COL_NOT_NULL\" RAW(100) NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE PRECISION DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" NUMBER(38),\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n"+ - "CREATE OR REPLACE TRIGGER \"trg_constraints_L_PK_AUTO_INCR\" BEFORE INSERT ON \"constraints\" FOR EACH ROW WHEN (new.\"COL_PK_AUTO_INCR\" IS NULL)\n"+ - "BEGIN SELECT \"seq_constraints_L_PK_AUTO_INCR\".nextval INTO :new.\"COL_PK_AUTO_INCR\" FROM dual; END;;\n"+ - "CREATE OR REPLACE TRIGGER \"trg_constraints_COL_AUTO_INCR\" BEFORE INSERT ON \"constraints\" FOR EACH ROW WHEN (new.\"COL_AUTO_INCR\" IS NULL)\n"+ - "BEGIN SELECT \"seq_constraints_COL_AUTO_INCR\".nextval INTO :new.\"COL_AUTO_INCR\" FROM dual; END;;\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"table3\" CASCADE CONSTRAINTS;\n"+ - "DROP TABLE \"table2\" CASCADE CONSTRAINTS;\n"+ - "DROP TABLE \"table1\" CASCADE CONSTRAINTS;\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR2(32) NOT NULL,\n"+ - " \"COL_PK_2\" NUMBER(22),\n"+ - " \"COL_INDEX_1\" RAW(100) NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE PRECISION NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" NUMBER(22),\n"+ - " \"COL_FK_1\" NUMBER(22),\n"+ - " \"COL_FK_2\" VARCHAR2(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR2(16),\n"+ - " \"COL_FK\" NUMBER(22) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_F_OL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Oracle requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\" CASCADE CONSTRAINTS;\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" NUMBER(22),\n"+ - " \"COL_TEXT\" VARCHAR2(128) DEFAULT '\'\'',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(TestOracle8Platform.COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatform.java deleted file mode 100644 index 35567be9a2..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatform.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -import org.jumpmind.symmetric.db.ddl.platform.PlatformImplBase; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; - - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * Platform implementation that makes the base functionality available without - * overriding anything. - * - * @version $Revision: $ - */ -public class TestPlatform extends PlatformImplBase -{ - /* - * Creates a new test platform instance. - */ - public TestPlatform() - { - setSqlBuilder(new SqlBuilder(this) {}); - } - /* - * {@inheritDoc} - */ - public String getName() - { - return "TestPlatform"; - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformImplBase.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformImplBase.java deleted file mode 100644 index 188997ae31..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformImplBase.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the {@link org.jumpmind.symmetric.ddl.PlatformImplBase} (abstract) class. - * - * @version $Revision: 279421 $ - */ -abstract public class TestPlatformImplBase extends TestPlatformBase -{ - /* The tested model. */ - private static final String TESTED_MODEL = - "\n"+ - "\n"+ - " \n"+ - " \n"+ - " \n"+ - "
\n"+ - "
"; - - /* - * {@inheritDoc} - */ - public void setUp() - { - } - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return null; - } - -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformUtils.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformUtils.java deleted file mode 100644 index 20f3086853..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPlatformUtils.java +++ /dev/null @@ -1,363 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import junit.framework.TestCase; - -import org.jumpmind.symmetric.db.ddl.PlatformUtils; -import org.jumpmind.symmetric.db.ddl.platform.cloudscape.CloudscapePlatform; -import org.jumpmind.symmetric.db.ddl.platform.db2.Db2Platform; -import org.jumpmind.symmetric.db.ddl.platform.derby.DerbyPlatform; -import org.jumpmind.symmetric.db.ddl.platform.firebird.FirebirdPlatform; -import org.jumpmind.symmetric.db.ddl.platform.hsqldb.HsqlDbPlatform; -import org.jumpmind.symmetric.db.ddl.platform.interbase.InterbasePlatform; -import org.jumpmind.symmetric.db.ddl.platform.mssql.MSSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.mysql.MySqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.oracle.Oracle8Platform; -import org.jumpmind.symmetric.db.ddl.platform.postgresql.PostgreSqlPlatform; -import org.jumpmind.symmetric.db.ddl.platform.sybase.SybasePlatform; - -/* - * Tests the {@link org.jumpmind.symmetric.ddl.PlatformUtils} class. - */ -public class TestPlatformUtils extends TestCase -{ - - /* - * {@inheritDoc} - */ - protected void setUp() throws Exception - { - } - - /* - * {@inheritDoc} - */ - protected void tearDown() throws Exception - { - } - - /* - * Tests the determination of the Db2 platform via its JDBC drivers. - */ - public void testDb2Driver() - { - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.ibm.db2.jcc.DB2Driver", null)); - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("COM.ibm.db2os390.sqlj.jdbc.DB2SQLJDriver", null)); - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("COM.ibm.db2.jdbc.app.DB2Driver", null)); - // DataDirect Connect - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.ddtek.jdbc.db2.DB2Driver", null)); - // i-net - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.inet.drda.DRDADriver", null)); - } - - /* - * Tests the determination of the Db2 platform via JDBC connection urls. - */ - public void testDb2Url() - { - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:db2://sysmvs1.stl.ibm.com:5021/san_jose")); - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:db2os390://sysmvs1.stl.ibm.com:5021/san_jose")); - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:db2os390sqlj://sysmvs1.stl.ibm.com:5021/san_jose")); - // DataDirect Connect - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:datadirect:db2://server1:50000;DatabaseName=jdbc;User=test;Password=secret")); - // i-net - assertEquals(Db2Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetdb2://server1:50000")); - } - - /* - * Tests the determination of the Cloudscape platform via JDBC connection urls. - */ - public void testCloudscapeUrl() - { - assertEquals(CloudscapePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:db2j:net:database")); - assertEquals(CloudscapePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:cloudscape:net:database")); - } - - /* - * Tests the determination of the Derby platform via its JDBC drivers. - */ - public void testDerbyDriver() - { - assertEquals(DerbyPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("org.apache.derby.jdbc.ClientDriver", null)); - assertEquals(DerbyPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("org.apache.derby.jdbc.EmbeddedDriver", null)); - } - - /* - * Tests the determination of the Derby platform via JDBC connection urls. - */ - public void testDerbyUrl() - { - assertEquals(DerbyPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:derby:sample")); - } - - /* - * Tests the determination of the Firebird platform via its JDBC driver. - */ - public void testFirebirdDriver() - { - assertEquals(FirebirdPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("org.firebirdsql.jdbc.FBDriver", null)); - } - - /* - * Tests the determination of the Firebird platform via JDBC connection urls. - */ - public void testFirebirdUrl() - { - assertEquals(FirebirdPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:firebirdsql://localhost:8080/path/to/db.fdb")); - assertEquals(FirebirdPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:firebirdsql:native:localhost/8080:/path/to/db.fdb")); - assertEquals(FirebirdPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:firebirdsql:local://localhost:8080:/path/to/db.fdb")); - assertEquals(FirebirdPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:firebirdsql:embedded:localhost/8080:/path/to/db.fdb")); - } - - /* - * Tests the determination of the HsqlDb platform via its JDBC driver. - */ - public void testHsqldbDriver() - { - assertEquals(HsqlDbPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("org.hsqldb.jdbcDriver", null)); - } - - /* - * Tests the determination of the HsqlDb platform via JDBC connection urls. - */ - public void testHsqldbUrl() - { - assertEquals(HsqlDbPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:hsqldb:/opt/db/testdb")); - } - - /* - * Tests the determination of the Interbase platform via its JDBC driver. - */ - public void testInterbaseDriver() - { - assertEquals(InterbasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("interbase.interclient.Driver", null)); - } - - /* - * Tests the determination of the Interbase platform via JDBC connection urls. - */ - public void testInterbaseUrl() - { - assertEquals(InterbasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:interbase://localhost/e:/testbed/database/employee.gdb")); - } - - /* - * Tests the determination of the Microsoft Sql Server platform via its JDBC drivers. - */ - public void testMsSqlDriver() - { - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.microsoft.jdbc.sqlserver.SQLServerDriver", null)); - // DataDirect Connect - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.ddtek.jdbc.sqlserver.SQLServerDriver", null)); - // JNetDirect JSQLConnect - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.jnetdirect.jsql.JSQLDriver", null)); - // i-net - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.inet.tds.TdsDriver", null)); - } - - /* - * Tests the determination of the Microsoft Sql Server platform via JDBC connection urls. - */ - public void testMsSqlUrl() - { - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:microsoft:sqlserver://localhost:1433")); - // DataDirect Connect - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:datadirect:sqlserver://server1:1433;User=test;Password=secret")); - // JNetDirect JSQLConnect - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:JSQLConnect://localhost/database=master/user=sa/sqlVersion=6")); - // i-net - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetdae:210.1.164.19:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetdae6:[2002:d201:a413::d201:a413]:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetdae7:localHost:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetdae7a://MyServer/pipe/sql/query")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:inetdae:210.1.164.19:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:inetdae6:[2002:d201:a413::d201:a413]:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:inetdae7:localHost:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:inetdae7a://MyServer/pipe/sql/query")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:jdbc:inetdae:210.1.164.19:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:jdbc:inetdae6:[2002:d201:a413::d201:a413]:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:jdbc:inetdae7:localHost:1433")); - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:jdbc:inetdae7a://MyServer/pipe/sql/query")); - // jTDS - assertEquals(MSSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:jtds:sqlserver://localhost:8080/test")); - } - - /* - * Tests the determination of the MySql platform via its JDBC drivers. - */ - public void testMySqlDriver() - { - assertEquals(MySqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.mysql.jdbc.Driver", null)); - assertEquals(MySqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("org.gjt.mm.mysql.Driver", null)); - } - - /* - * Tests the determination of the MySql platform via JDBC connection urls. - */ - public void testMySqlUrl() - { - assertEquals(MySqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:mysql://localhost:1234/test")); - } - - /* - * Tests the determination of the Oracle 8 platform via its JDBC drivers. - */ - public void testOracleDriver() - { - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("oracle.jdbc.driver.OracleDriver", null)); - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("oracle.jdbc.dnlddriver.OracleDriver", null)); - // DataDirect Connect - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.ddtek.jdbc.oracle.OracleDriver", null)); - // i-net - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.inet.ora.OraDriver", null)); - } - - /* - * Tests the determination of the Oracle 8 platform via JDBC connection urls. - */ - public void testOracleUrl() - { - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:oracle:thin:@myhost:1521:orcl")); - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:oracle:oci8:@(description=(address=(host=myhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl)))")); - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:oracle:dnldthin:@myhost:1521:orcl")); - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:oracle:dnldthin:@myhost:1521:orcl")); - // DataDirect Connect - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:datadirect:oracle://server3:1521;ServiceName=ORCL;User=test;Password=secret")); - // i-net - assertEquals(Oracle8Platform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetora:www.inetsoftware.de:1521:orcl?traceLevel=2")); - } - - /* - * Tests the determination of the PostgreSql platform via its JDBC driver. - */ - public void testPostgreSqlDriver() - { - assertEquals(PostgreSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("org.postgresql.Driver", null)); - } - - /* - * Tests the determination of the PostgreSql platform via JDBC connection urls. - */ - public void testPostgreSqlUrl() - { - assertEquals(PostgreSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:postgresql://localhost:1234/test")); - assertEquals(PostgreSqlPlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:postgresql://[::1]:5740/accounting")); - } - - /* - * Tests the determination of the Sybase platform via its JDBC drivers. - */ - public void testSybaseDriver() - { - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.sybase.jdbc.SybDriver", null)); - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.sybase.jdbc2.jdbc.SybDriver", null)); - // DataDirect Connect - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.ddtek.jdbc.sybase.SybaseDriver", null)); - // i-net - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType("com.inet.syb.SybDriver", null)); - } - - /* - * Tests the determination of the Sybase platform via JDBC connection urls. - */ - public void testSybaseUrl() - { - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:sybase:Tds:xyz:3767orjdbc:sybase:Tds:130.214.90.27:3767")); - // DataDirect Connect - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:datadirect:sybase://server2:5000;User=test;Password=secret")); - // i-net - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetsyb:www.inetsoftware.de:3333")); - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:inetsyb:www.inetsoftware.de:3333")); - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:inetpool:jdbc:inetsyb:www.inetsoftware.de:3333")); - // jTDS - assertEquals(SybasePlatform.DATABASENAME, - PlatformUtils.determineDatabaseType(null, "jdbc:jtds:sybase://localhost:8080/test")); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPostgresqlPlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPostgresqlPlatform.java deleted file mode 100644 index 3a0b14233d..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestPostgresqlPlatform.java +++ /dev/null @@ -1,173 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.postgresql.PostgreSqlPlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the PostgreSQL platform. - * - * @version $Revision: 231110 $ - */ -public class TestPostgresqlPlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return PostgreSqlPlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"coltype\" CASCADE;\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" BYTEA,\n"+ - " \"COL_BIGINT\" BIGINT,\n"+ - " \"COL_BINARY\" BYTEA,\n"+ - " \"COL_BIT\" BOOLEAN,\n"+ - " \"COL_BLOB\" BYTEA,\n"+ - " \"COL_BOOLEAN\" BOOLEAN,\n"+ - " \"COL_CHAR\" CHAR(15),\n"+ - " \"COL_CLOB\" TEXT,\n"+ - " \"COL_DATALINK\" BYTEA,\n"+ - " \"COL_DATE\" DATE,\n"+ - " \"COL_DECIMAL\" NUMERIC(15,3),\n"+ - " \"COL_DECIMAL_NOSCALE\" NUMERIC(15,0),\n"+ - " \"COL_DISTINCT\" BYTEA,\n"+ - " \"COL_DOUBLE\" DOUBLE PRECISION,\n"+ - " \"COL_FLOAT\" DOUBLE PRECISION,\n"+ - " \"COL_INTEGER\" INTEGER,\n"+ - " \"COL_JAVA_OBJECT\" BYTEA,\n"+ - " \"COL_LONGVARBINARY\" BYTEA,\n"+ - " \"COL_LONGVARCHAR\" TEXT,\n"+ - " \"COL_NULL\" BYTEA,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0),\n"+ - " \"COL_OTHER\" BYTEA,\n"+ - " \"COL_REAL\" REAL,\n"+ - " \"COL_REF\" BYTEA,\n"+ - " \"COL_SMALLINT\" SMALLINT,\n"+ - " \"COL_STRUCT\" BYTEA,\n"+ - " \"COL_TIME\" TIME,\n"+ - " \"COL_TIMESTAMP\" TIMESTAMP,\n"+ - " \"COL_TINYINT\" SMALLINT,\n"+ - " \"COL_VARBINARY\" BYTEA,\n"+ - " \"COL_VARCHAR\" VARCHAR(15)\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"constraints\" CASCADE;\n" + - "DROP SEQUENCE \"constraints_COL_K_AUTO_INCR_seq\";\n" + - "DROP SEQUENCE \"constraints_COL_AUTO_INCR_seq\";\n" + - "CREATE SEQUENCE \"constraints_COL_K_AUTO_INCR_seq\";\n" + - "CREATE SEQUENCE \"constraints_COL_AUTO_INCR_seq\";\n" + - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32),\n"+ - " \"COL_PK_AUTO_INCR\" INTEGER DEFAULT nextval('\"constraints_COL_K_AUTO_INCR_seq\"'),\n"+ - " \"COL_NOT_NULL\" BYTEA NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE PRECISION DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test',\n"+ - " \"COL_AUTO_INCR\" BIGINT DEFAULT nextval('\"constraints_COL_AUTO_INCR_seq\"'),\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_F_COL_FK_2_table1\";\n"+ - "DROP TABLE \"table3\" CASCADE;\n"+ - "DROP TABLE \"table2\" CASCADE;\n"+ - "DROP TABLE \"table1\" CASCADE;\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INTEGER,\n"+ - " \"COL_INDEX_1\" BYTEA NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE PRECISION NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4),\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_FK_1\" INTEGER,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16),\n"+ - " \"COL_FK\" INTEGER NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_F_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where PostgreSQL requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "DROP TABLE \"escapedcharacters\" CASCADE;\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INTEGER,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\\\' \\t \\n \\r \\\\',\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSqlBuilder.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSqlBuilder.java deleted file mode 100644 index b71fb55704..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSqlBuilder.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import java.util.HashMap; -import java.util.Map; - -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.SqlBuilder; -import org.jumpmind.symmetric.ddl.TestBase; - -/* - * Test the base SqlBuilder class. - * - * @version $Revision: $ - */ -public class TestSqlBuilder extends TestBase -{ - /* - * Tests the {@link SqlBuilder#getUpdateSql(Table, Map, boolean)} method. - */ - public void testUpdateSql() - { - final String modelXml = - "\n"+ - "\n"+ - " \n"+ - " \n"+ - " \n"+ - "
\n"+ - "
"; - - TestPlatform platform = new TestPlatform(); - SqlBuilder sqlBuilder = platform.getSqlBuilder(); - Database database = parseDatabaseFromString(modelXml); - Map map = new HashMap(); - - map.put("name", "ddlutils"); - map.put("id", new Integer(0)); - - platform.setDelimitedIdentifierModeOn(true); - - String sql = sqlBuilder.getUpdateSql(database.getTable(0), map, false); - - assertEquals("UPDATE \"TestTable\" SET \"name\" = 'ddlutils' WHERE \"id\" = '0'", - sql); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSybasePlatform.java b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSybasePlatform.java deleted file mode 100644 index b5101cc3c9..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/TestSybasePlatform.java +++ /dev/null @@ -1,208 +0,0 @@ -package org.jumpmind.symmetric.ddl.platform; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -import org.jumpmind.symmetric.db.ddl.platform.sybase.SybasePlatform; -import org.jumpmind.symmetric.ddl.TestPlatformBase; - -/* - * Tests the Sybase platform. - * - * @version $Revision: 231110 $ - */ -public class TestSybasePlatform extends TestPlatformBase -{ - /* The database schema for testing escaping of character sequences. */ - public static final String COLUMN_CHAR_SEQUENCES_TO_ESCAPE = - "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - "
\n" + - "
"; - - /* - * {@inheritDoc} - */ - protected String getDatabaseName() - { - return SybasePlatform.DATABASENAME; - } - - /* - * Tests the column types. - */ - public void testColumnTypes() throws Exception - { - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'coltype')\n"+ - "BEGIN\n"+ - " DROP TABLE \"coltype\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"coltype\"\n"+ - "(\n"+ - " \"COL_ARRAY\" IMAGE NULL,\n"+ - " \"COL_BIGINT\" DECIMAL(19,0) NULL,\n"+ - " \"COL_BINARY\" BINARY(254) NULL,\n"+ - " \"COL_BIT\" SMALLINT NULL,\n"+ - " \"COL_BLOB\" IMAGE NULL,\n"+ - " \"COL_BOOLEAN\" SMALLINT NULL,\n"+ - " \"COL_CHAR\" CHAR(15) NULL,\n"+ - " \"COL_CLOB\" TEXT NULL,\n"+ - " \"COL_DATALINK\" IMAGE NULL,\n"+ - " \"COL_DATE\" DATETIME NULL,\n"+ - " \"COL_DECIMAL\" DECIMAL(15,3) NULL,\n"+ - " \"COL_DECIMAL_NOSCALE\" DECIMAL(15,0) NULL,\n"+ - " \"COL_DISTINCT\" IMAGE NULL,\n"+ - " \"COL_DOUBLE\" DOUBLE PRECISION NULL,\n"+ - " \"COL_FLOAT\" DOUBLE PRECISION NULL,\n"+ - " \"COL_INTEGER\" INT NULL,\n"+ - " \"COL_JAVA_OBJECT\" IMAGE NULL,\n"+ - " \"COL_LONGVARBINARY\" IMAGE NULL,\n"+ - " \"COL_LONGVARCHAR\" TEXT NULL,\n"+ - " \"COL_NULL\" IMAGE NULL,\n"+ - " \"COL_NUMERIC\" NUMERIC(15,0) NULL,\n"+ - " \"COL_OTHER\" IMAGE NULL,\n"+ - " \"COL_REAL\" REAL NULL,\n"+ - " \"COL_REF\" IMAGE NULL,\n"+ - " \"COL_SMALLINT\" SMALLINT NULL,\n"+ - " \"COL_STRUCT\" IMAGE NULL,\n"+ - " \"COL_TIME\" DATETIME NULL,\n"+ - " \"COL_TIMESTAMP\" DATETIME NULL,\n"+ - " \"COL_TINYINT\" SMALLINT NULL,\n"+ - " \"COL_VARBINARY\" VARBINARY(15) NULL,\n"+ - " \"COL_VARCHAR\" VARCHAR(15) NULL\n"+ - ");\n", - createTestDatabase(COLUMN_TEST_SCHEMA)); - } - - /* - * Tests the column constraints. - */ - public void testColumnConstraints() throws Exception - { - // this is not valid sql as a table can have only one identity column at most - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'constraints')\n"+ - "BEGIN\n"+ - " DROP TABLE \"constraints\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"constraints\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(32) NULL,\n"+ - " \"COL_PK_AUTO_INCR\" INT IDENTITY,\n"+ - " \"COL_NOT_NULL\" BINARY(100) NOT NULL,\n"+ - " \"COL_NOT_NULL_DEFAULT\" DOUBLE PRECISION DEFAULT -2.0 NOT NULL,\n"+ - " \"COL_DEFAULT\" CHAR(4) DEFAULT 'test' NULL,\n"+ - " \"COL_AUTO_INCR\" DECIMAL(19,0) IDENTITY,\n"+ - " PRIMARY KEY (\"COL_PK\", \"COL_PK_AUTO_INCR\")\n"+ - ");\n", - createTestDatabase(COLUMN_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the table constraints. - */ - public void testTableConstraints() throws Exception - { - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'RI' AND name = 'testfk')\n"+ - " ALTER TABLE \"table3\" DROP CONSTRAINT \"testfk\";\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'RI' AND name = 'table2_FK_COL_FK_1_COL_FK_2_table1')\n"+ - " ALTER TABLE \"table2\" DROP CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\";\n"+ - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'table3')\n"+ - "BEGIN\n"+ - " DROP TABLE \"table3\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'table2')\n"+ - "BEGIN\n"+ - " DROP TABLE \"table2\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'table1')\n"+ - "BEGIN\n"+ - " DROP TABLE \"table1\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"table1\"\n"+ - "(\n"+ - " \"COL_PK_1\" VARCHAR(32) NOT NULL,\n"+ - " \"COL_PK_2\" INT NULL,\n"+ - " \"COL_INDEX_1\" BINARY(100) NOT NULL,\n"+ - " \"COL_INDEX_2\" DOUBLE PRECISION NOT NULL,\n"+ - " \"COL_INDEX_3\" CHAR(4) NULL,\n"+ - " PRIMARY KEY (\"COL_PK_1\", \"COL_PK_2\")\n"+ - ");\n"+ - "CREATE INDEX \"testindex1\" ON \"table1\" (\"COL_INDEX_2\");\n"+ - "CREATE UNIQUE INDEX \"testindex2\" ON \"table1\" (\"COL_INDEX_3\", \"COL_INDEX_1\");\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"table2\"\n"+ - "(\n"+ - " \"COL_PK\" INT NULL,\n"+ - " \"COL_FK_1\" INT NULL,\n"+ - " \"COL_FK_2\" VARCHAR(32) NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"table3\"\n"+ - "(\n"+ - " \"COL_PK\" VARCHAR(16) NULL,\n"+ - " \"COL_FK\" INT NOT NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n"+ - "ALTER TABLE \"table2\" ADD CONSTRAINT \"table2_FK_COL_FK_1_COL_FK_2_table1\" FOREIGN KEY (\"COL_FK_1\", \"COL_FK_2\") REFERENCES \"table1\" (\"COL_PK_2\", \"COL_PK_1\");\n"+ - "ALTER TABLE \"table3\" ADD CONSTRAINT \"testfk\" FOREIGN KEY (\"COL_FK\") REFERENCES \"table2\" (\"COL_PK\");\n", - createTestDatabase(TABLE_CONSTRAINT_TEST_SCHEMA)); - } - - /* - * Tests the proper escaping of character sequences where Cloudscape requires it. - */ - public void testCharacterEscaping() throws Exception - { - assertEqualsIgnoringWhitespaces( - "SET quoted_identifier on;\n"+ - "SET quoted_identifier on;\n"+ - "IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'escapedcharacters')\n"+ - "BEGIN\n"+ - " DROP TABLE \"escapedcharacters\"\n"+ - "END;\n"+ - "SET quoted_identifier on;\n"+ - "CREATE TABLE \"escapedcharacters\"\n"+ - "(\n"+ - " \"COL_PK\" INT NULL,\n"+ - " \"COL_TEXT\" VARCHAR(128) DEFAULT '\'\'' NULL,\n"+ - " PRIMARY KEY (\"COL_PK\")\n"+ - ");\n", - createTestDatabase(COLUMN_CHAR_SEQUENCES_TO_ESCAPE)); - } -} diff --git a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/package.html b/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/package.html deleted file mode 100644 index 15deac9b38..0000000000 --- a/symmetric/symmetric-db/src/test/java/org/jumpmind/symmetric/ddl/platform/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -

- This package contains platform specific tests. -

- - diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.axion b/symmetric/symmetric-db/src/test/resources/jdbc.properties.axion deleted file mode 100644 index 9c55d42627..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.axion +++ /dev/null @@ -1,27 +0,0 @@ -# JDBC properties for Axion - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Axion - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=org.axiondb.jdbc.AxionDriver -datasource.url=jdbc:axiondb:testdb:target/test/axion diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.db2 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.db2 deleted file mode 100644 index 66d93e3133..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.db2 +++ /dev/null @@ -1,31 +0,0 @@ -# JDBC properties for Db2 UDB - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Db2 - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -datasource.class=org.apache.commons.dbcp.BasicDataSource - -datasource.driverClassName=COM.ibm.db2.jdbc.net.DB2Driver -datasource.url=jdbc:db2://localhost:6789/ddlutils -datasource.username=ddlutils -datasource.password=ddlutils diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.derby b/symmetric/symmetric-db/src/test/resources/jdbc.properties.derby deleted file mode 100644 index 69da934bbd..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.derby +++ /dev/null @@ -1,43 +0,0 @@ -# JDBC properties for Derby >= 10.1.1.0 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Derby - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -datasource.class=org.apache.commons.dbcp.BasicDataSource - -# Embedded mode - -#datasource.driverClassName=org.apache.derby.jdbc.EmbeddedDriver -#datasource.url=jdbc:derby:target/database/ddlutils_derby - -# The default username for embedded Derby is app; for every other user the must be a corresponding -# schema defined in the database; see http://db.apache.org/derby/faq.html#schema_exist for details -#datasource.username=app -#datasource.password= - -# Client/server mode - -datasource.driverClassName=org.apache.derby.jdbc.ClientDriver -datasource.url=jdbc:derby://localhost/ddlutils;create=true -datasource.username=ddlutils -datasource.password=ddlutils diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.derby-embedded b/symmetric/symmetric-db/src/test/resources/jdbc.properties.derby-embedded deleted file mode 100644 index 66904822a9..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.derby-embedded +++ /dev/null @@ -1,36 +0,0 @@ -# JDBC properties for Derby >= 10.1.1.0 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Derby - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -datasource.class=org.apache.commons.dbcp.BasicDataSource - -# Embedded mode - -datasource.driverClassName=org.apache.derby.jdbc.EmbeddedDriver -datasource.url=jdbc:derby:target/database/ddlutils_derby;create=true - -# The default username for embedded Derby is app; for every other user the must be a corresponding -# schema defined in the database; see http://db.apache.org/derby/faq.html#schema_exist for details -datasource.username=app -datasource.password= diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.firebird b/symmetric/symmetric-db/src/test/resources/jdbc.properties.firebird deleted file mode 100644 index 93568c2540..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.firebird +++ /dev/null @@ -1,35 +0,0 @@ -# JDBC properties for FireBird - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Firebird - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=org.firebirdsql.jdbc.FBDriver -datasource.url=jdbc:firebirdsql://localhost/C:/Programme/Firebird/Firebird_1_5/data/ddlutils.fdb -datasource.username=SYSDBA -datasource.password=masterkey - diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.hsqldb b/symmetric/symmetric-db/src/test/resources/jdbc.properties.hsqldb deleted file mode 100644 index 1371c294f0..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.hsqldb +++ /dev/null @@ -1,38 +0,0 @@ -# JDBC properties for HsqlDb - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -ddlutils.platform=HsqlDb - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=org.hsqldb.jdbcDriver - -# Embedded mode - -#datasource.url=jdbc:hsqldb:file:target/database/ddlutils_hsqldb -#datasource.username=sa -#datasource.password= - -# Server mode - -datasource.url=jdbc:hsqldb:hsql://localhost -datasource.username=sa -datasource.password= diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase2007 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase2007 deleted file mode 100644 index ec167e8ded..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase2007 +++ /dev/null @@ -1,35 +0,0 @@ -# JDBC properties for Interbase 2007 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Interbase - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=interbase.interclient.Driver -datasource.url=jdbc:interbase://localhost/C:/Borland/InterBase/ddlutils.ib -datasource.username=SYSDBA -datasource.password=masterkey - diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase75 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase75 deleted file mode 100644 index 28a63a30be..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.interbase75 +++ /dev/null @@ -1,35 +0,0 @@ -# JDBC properties for Interbase 7.5 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Interbase - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=interbase.interclient.Driver -datasource.url=jdbc:interbase://localhost/C:/Programme/Borland/InterBase/data/ddlutils.db -datasource.username=SYSDBA -datasource.password=masterkey - diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.maxdb b/symmetric/symmetric-db/src/test/resources/jdbc.properties.maxdb deleted file mode 100644 index 6eb692fa23..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.maxdb +++ /dev/null @@ -1,34 +0,0 @@ -# JDBC properties for MaxDB - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# You need to use this property, otherwise DdlUtils will detect SapDB instead (since the JDBC driver is the same) -ddlutils.platform=MaxDB - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=com.sap.dbtech.jdbc.DriverSapDB -datasource.url=jdbc:sapdb://localhost/ddlutils -datasource.username=ddlutils -datasource.password=ddlutils diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.mckoi b/symmetric/symmetric-db/src/test/resources/jdbc.properties.mckoi deleted file mode 100644 index c3edcee53b..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.mckoi +++ /dev/null @@ -1,37 +0,0 @@ -# JDBC properties for Mckoi 1.0.3 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Mckoi - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=com.mckoi.JDBCDriver -datasource.username=ddlutils -datasource.password=ddlutils - -# Embedded mode - -#datasource.url=jdbc:mckoi:local://./target/database/ddlutils_mckoi - -# Client/server mode - -datasource.url=jdbc:mckoi://localhost diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql b/symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql deleted file mode 100644 index 6f6f14733c..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql +++ /dev/null @@ -1,37 +0,0 @@ -# JDBC properties for MySQL using Connector/J - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=MySql - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=com.mysql.jdbc.Driver -datasource.url=jdbc:mysql://localhost/ddlutils -datasource.username=root -datasource.password= - -# We want to test against InnoDB tables (so that we get e.g. foreign keys) -ddlutils.tableCreation.ENGINE=InnoDB diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql50 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql50 deleted file mode 100644 index a49c41a7a1..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.mysql50 +++ /dev/null @@ -1,37 +0,0 @@ -# JDBC properties for MySQL using Connector/J - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property if ddlutils does not recognize the platform from the settings -ddlutils.platform=MySql5 - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=com.mysql.jdbc.Driver -datasource.url=jdbc:mysql://localhost/ddlutils -datasource.username=root -datasource.password= - -# We want to test against InnoDB tables (so that we get e.g. foreign keys) -ddlutils.tableCreation.ENGINE=InnoDB diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle10 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle10 deleted file mode 100644 index d901d3fe4a..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle10 +++ /dev/null @@ -1,49 +0,0 @@ -# JDBC properties for Oracle10 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property to choose the Oracle10 platform (instead of the Oracle8 default one) -ddlutils.platform=Oracle10 - -# -# Using the plain DBCP datasource -# - -#datasource.class=org.apache.commons.dbcp.BasicDataSource -#datasource.driverClassName=oracle.jdbc.driver.OracleDriver -#datasource.url=jdbc:oracle:thin:@localhost:1521:test -#datasource.username=ddlutils -#datasource.password=ddlutils - -# -# Or the Oracle datasource -# - -datasource.class=oracle.jdbc.pool.OracleDataSource -datasource.URL=jdbc:oracle:thin:@localhost:1521:test -datasource.user=ddlutils -datasource.password=ddlutils -datasource.connectionCachingEnabled=true - - -# For oracle, we should limit the schema to the one of the user -# Note that Oracle requires this to be uppercase, even when using delimited identifiers -ddlutils.schema=DDLUTILS diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle9 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle9 deleted file mode 100644 index c40525b468..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.oracle9 +++ /dev/null @@ -1,49 +0,0 @@ -# JDBC properties for Oracle9 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property to choose the Oracle9 platform (instead of the Oracle8 default one) -ddlutils.platform=Oracle9 - -# -# Using the plain DBCP datasource -# - -#datasource.class=org.apache.commons.dbcp.BasicDataSource -#datasource.driverClassName=oracle.jdbc.driver.OracleDriver -#datasource.url=jdbc:oracle:thin:@localhost:1521:test -#datasource.username=ddlutils -#datasource.password=ddlutils - -# -# Or the Oracle datasource -# - -datasource.class=oracle.jdbc.pool.OracleDataSource -datasource.URL=jdbc:oracle:thin:@localhost:1521:test -datasource.user=ddlutils -datasource.password=ddlutils -datasource.connectionCachingEnabled=true - - -# For oracle, we should limit the schema to the one of the user -# Note that Oracle requires this to be uppercase, even when using delimited identifiers -ddlutils.schema=DDLUTILS diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.postgresql b/symmetric/symmetric-db/src/test/resources/jdbc.properties.postgresql deleted file mode 100644 index 949e18859e..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.postgresql +++ /dev/null @@ -1,52 +0,0 @@ -# JDBC properties for PostgreSQL - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=PostgreSQL - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=org.postgresql.Driver -datasource.url=jdbc:postgresql://localhost/ddlutils -datasource.username=ddlutils -datasource.password=ddlutils - -# -# PostgreSQL comes with its own DataSource implementations which can be configured like this: -# - -#datasource.class=org.postgresql.ds.PGSimpleDataSource -# or this one for pooling: -#datasource.class=org.postgresql.ds.PGPoolingDataSource - -#datasource.serverName=localhost -#datasource.databaseName=ddlutils -#datasource.user= -#datasource.password= - -# additional properties for the pooling datasource: -#datasource.dataSourceName=pooling datasource -#datasource.initialConnections=5 -#datasource.maxConnections=20 \ No newline at end of file diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sapdb b/symmetric/symmetric-db/src/test/resources/jdbc.properties.sapdb deleted file mode 100644 index addff92a5c..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sapdb +++ /dev/null @@ -1,34 +0,0 @@ -# JDBC properties for SapDB - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Note: Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=SapDB - -# -# Using the plain DBCP datasource -# - -datasource.class=org.apache.commons.dbcp.BasicDataSource -datasource.driverClassName=com.sap.dbtech.jdbc.DriverSapDB -datasource.url=jdbc:sapdb://localhost/ddlutils -datasource.username=dba -datasource.password=dba diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2000 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2000 deleted file mode 100644 index 25235018ca..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2000 +++ /dev/null @@ -1,42 +0,0 @@ -# JDBC properties for Microsoft Sql Server 2000 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=MsSql - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -datasource.class=org.apache.commons.dbcp.BasicDataSource - -# This is the Sql Server 2005 driver which is recommended for Sql Server 2000 too -# Note that this new driver supports the new shorter subprotocol -datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver -datasource.url=jdbc:sqlserver://localhost;databaseName=ddlutils;selectMethod=cursor - -# This is the older Sql Server 2000 driver -#datasource.driverClassName=com.microsoft.jdbc.sqlserver.SQLServerDriver -#datasource.url=jdbc:microsoft:sqlserver://localhost;databaseName=ddlutils;selectMethod=cursor - -datasource.username=ddlutils -datasource.password=ddlutils - -# Sql Server supports both catalogs and schemas, so we should define them both -ddlutils.catalog=ddlutils -ddlutils.schema=ddlutils diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2005 b/symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2005 deleted file mode 100644 index 28c145c243..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sqlserver2005 +++ /dev/null @@ -1,36 +0,0 @@ -# JDBC properties for Microsoft Sql Server 2005 - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=MsSql - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -datasource.class=org.apache.commons.dbcp.BasicDataSource - -datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver -datasource.url=jdbc:sqlserver://localhost;databaseName=ddlutils;selectMethod=cursor - -datasource.username=ddlutils -datasource.password=ddlutils - -# Sql Server supports both catalogs and schemas, so we should define them both -ddlutils.catalog=ddlutils -ddlutils.schema=dbo diff --git a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sybaseASE b/symmetric/symmetric-db/src/test/resources/jdbc.properties.sybaseASE deleted file mode 100644 index c5622e0fb3..0000000000 --- a/symmetric/symmetric-db/src/test/resources/jdbc.properties.sybaseASE +++ /dev/null @@ -1,36 +0,0 @@ -# JDBC properties for Sybase 12.5 ASE - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. - -# Use this property if ddlutils does not recognize the platform from the settings -#ddlutils.platform=Sybase - -# Properties starting with "datasource." will be fed into the datasource instance of the -# class configured via the datasource.class property - -datasource.class=org.apache.commons.dbcp.BasicDataSource - -# This is the JConnect 6 driver -datasource.driverClassName=com.sybase.jdbc3.jdbc.SybDriver -datasource.url=jdbc:sybase:Tds:127.0.0.1:5000/ddlutils -datasource.username=ddlutils -datasource.password=ddlutils - -# Sybase supports both catalogs and schemas, so we should define them both -ddlutils.catalog=ddlutils -ddlutils.schema=ddlutils diff --git a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/SymmetricLauncher.java b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/SymmetricLauncher.java index bd01aa27b2..d959dc7b81 100644 --- a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/SymmetricLauncher.java +++ b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/SymmetricLauncher.java @@ -31,6 +31,7 @@ import java.net.URL; import java.nio.charset.Charset; import java.sql.Connection; +import java.sql.SQLException; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; @@ -53,10 +54,10 @@ import org.jumpmind.symmetric.common.SecurityConstants; import org.jumpmind.symmetric.common.logging.LogFactory; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.SqlScript; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.io.DatabaseIO; -import org.jumpmind.symmetric.db.ddl.model.Database; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.io.DatabaseIO; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.sql.SqlScript; import org.jumpmind.symmetric.profile.IProfile; import org.jumpmind.symmetric.service.IDataExtractorService; import org.jumpmind.symmetric.service.IDataLoaderService; @@ -569,10 +570,17 @@ private void encryptText(ISymmetricEngine engine, String plainText) { System.out.println(SecurityConstants.PREFIX_ENC + service.encrypt(plainText)); } - private void exportSchema(ISymmetricEngine engine, String fileName) { - Platform platform = engine.getDbDialect().getPlatform(); - Database db = platform.readModelFromDatabase("model"); - new DatabaseIO().write(db, fileName); + private void exportSchema(ISymmetricEngine engine, String fileName) { + IDatabasePlatform platform = engine.getDbDialect().getPlatform(); + Connection c = null; + try { + c = engine.getDataSource().getConnection(); + Database db = platform.readDatabase(c, "model", null, null, null); + c.close(); + new DatabaseIO().write(db, fileName); + } catch (SQLException ex) { + throw new RuntimeException(ex); + } } private void openRegistration(ISymmetricEngine engine, String argument) { @@ -644,9 +652,9 @@ private void runDdlXml(ISymmetricEngine engine, String fileName) throws FileNotF IDbDialect dialect = (IDbDialect) engine.getApplicationContext().getBean(Constants.DB_DIALECT); File file = new File(fileName); if (file.exists() && file.isFile()) { - Platform pf = dialect.getPlatform(); + IDatabasePlatform pf = dialect.getPlatform(); Database db = new DatabaseIO().read(new File(fileName)); - pf.createTables(db, false, true); + pf.createDatabase(engine.getDataSource(), db, false, true); } else { throw new SymmetricException("FileNotFound", fileName); } @@ -657,7 +665,7 @@ private void runSql(ISymmetricEngine engine, String fileName) throws FileNotFoun IDbDialect dialect = (IDbDialect) engine.getApplicationContext().getBean(Constants.DB_DIALECT); File file = new File(fileName); if (file.exists() && file.isFile()) { - SqlScript script = new SqlScript(file.toURI().toURL(), dialect.getPlatform().getDataSource(), + SqlScript script = new SqlScript(file.toURI().toURL(), engine.getDataSource(), true, SqlScript.QUERY_ENDS, dialect.getSqlScriptReplacementTokens()); script.execute(); } else { diff --git a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/AddColumnsFilter.java b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/AddColumnsFilter.java index 44c44f294b..ada8bb34b5 100644 --- a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/AddColumnsFilter.java +++ b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/AddColumnsFilter.java @@ -27,7 +27,7 @@ import org.jumpmind.symmetric.common.TokenConstants; import org.jumpmind.symmetric.common.logging.ILog; import org.jumpmind.symmetric.common.logging.LogFactory; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.ext.INodeGroupExtensionPoint; import org.jumpmind.symmetric.load.IDataLoaderContext; diff --git a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/ChangeColumnsNamesFilter.java b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/ChangeColumnsNamesFilter.java index e865dae5a1..a302c4d4d5 100644 --- a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/ChangeColumnsNamesFilter.java +++ b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/ChangeColumnsNamesFilter.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.TreeMap; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.ext.INodeGroupExtensionPoint; import org.jumpmind.symmetric.load.IDataLoaderContext; diff --git a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/RemoveColumnsFilter.java b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/RemoveColumnsFilter.java index c4a29b3921..b5ee103487 100644 --- a/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/RemoveColumnsFilter.java +++ b/symmetric/symmetric-server/src/main/java/org/jumpmind/symmetric/map/RemoveColumnsFilter.java @@ -26,7 +26,7 @@ import java.util.Map; import org.apache.commons.lang.ArrayUtils; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.sql.DmlStatement.DmlType; import org.jumpmind.symmetric.ext.INodeGroupExtensionPoint; import org.jumpmind.symmetric.load.IDataLoaderContext; diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/AbstractDbDialectUnitTest.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/AbstractDbDialectUnitTest.java index 9329edde33..15781d9e95 100644 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/AbstractDbDialectUnitTest.java +++ b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/AbstractDbDialectUnitTest.java @@ -21,8 +21,8 @@ import junit.framework.Assert; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Table; +import org.jumpmind.symmetric.db.model.Column; +import org.jumpmind.symmetric.db.model.Table; import org.junit.Test; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/SqlScriptUnitTest.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/SqlScriptUnitTest.java index 7185ab78b7..aa096d20a1 100644 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/SqlScriptUnitTest.java +++ b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/db/SqlScriptUnitTest.java @@ -24,6 +24,7 @@ import junit.framework.Assert; +import org.jumpmind.symmetric.db.sql.SqlScript; import org.junit.Test; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SingleConnectionDataSource; diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/ddl/platform/h2/H2PlatformUnitTest.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/ddl/platform/h2/H2PlatformUnitTest.java deleted file mode 100644 index 75e0b7fafd..0000000000 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/ddl/platform/h2/H2PlatformUnitTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed to JumpMind Inc under one or more contributor - * license agreements. See the NOTICE file distributed - * with this work for additional information regarding - * copyright ownership. JumpMind Inc licenses this file - * to you under the GNU Lesser General Public License (the - * "License"); you may not use this file except in compliance - * with the License. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see - * . - * - * 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.jumpmind.symmetric.ddl.platform.h2; - -import java.sql.Connection; -import java.sql.DriverManager; - -import junit.framework.Assert; - -import org.h2.Driver; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.PlatformFactory; -import org.jumpmind.symmetric.db.ddl.model.Column; -import org.jumpmind.symmetric.db.ddl.model.Database; -import org.jumpmind.symmetric.db.ddl.model.Table; -import org.jumpmind.symmetric.db.ddl.platform.h2.H2Platform; -import org.junit.Test; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; -import org.springframework.jdbc.datasource.SingleConnectionDataSource; - -public class H2PlatformUnitTest { - - private static final String H2 = "H2"; - - - @Test - public void testColumnSizeChangeToVarchar() throws Exception { - Platform pf = getPlatform(); - Database db = new Database(); - Table table = new Table(); - table.setName("TEST_TABLE_VARCHAR"); - Column column1 = new Column(); - column1.setName("COLUMN_1"); - column1.setType("VARCHAR"); - column1.setSize("20"); - table.addColumn(column1); - db.addTable(table); - pf.createTables(db, false, false); - - SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(pf.getDataSource()); - Assert.assertEquals(0, jdbcTemplate.queryForInt("select count(*) from TEST_TABLE_VARCHAR")); - Assert.assertEquals(20, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_VARCHAR' and COLUMN_NAME='COLUMN_1'")); - - Database readDb = pf.readModelFromDatabase(null); - Table[] tables = readDb.getTables(); - for (Table t : tables) { - if (t.getName().equals("TEST_TABLE_VARCHAR")) { - Assert.assertEquals(20, t.getColumn(0).getSizeAsInt()); - } - } - - column1.setSize("50"); - pf.alterTables(null, null, null, db, false); - Assert.assertEquals(50, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_VARCHAR' and COLUMN_NAME='COLUMN_1'")); - } - - @Test - public void testColumnSizeChangeToNumeric() throws Exception { - Platform pf = getPlatform(); - Database db = new Database(); - Table table = new Table(); - table.setName("TEST_TABLE_NUMERIC"); - Column column1 = new Column(); - column1.setName("COLUMN_1"); - column1.setType("NUMERIC"); - column1.setSize("15"); - table.addColumn(column1); - db.addTable(table); - pf.createTables(db, false, false); - - SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(pf.getDataSource()); - Assert.assertEquals(0, jdbcTemplate.queryForInt("select count(*) from TEST_TABLE_NUMERIC")); - Assert.assertEquals(15, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_NUMERIC' and COLUMN_NAME='COLUMN_1'")); - - column1.setSize("200"); - pf.alterTables(null, null, null, db, false); - Assert.assertEquals(200, jdbcTemplate.queryForInt("select NUMERIC_PRECISION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_NUMERIC' and COLUMN_NAME='COLUMN_1'")); - } - - @Test - public void testChangeDefaultValue() throws Exception { - Platform pf = getPlatform(); - Database db = new Database(); - Table table = new Table(); - table.setName("TEST_TABLE_DEFAULTS"); - Column column1 = new Column(); - column1.setName("COLUMN_1"); - column1.setType("NUMERIC"); - column1.setSize("15"); - column1.setDefaultValue("1"); - Column column2 = new Column(); - column2.setName("COLUMN_2"); - column2.setType("VARCHAR"); - column2.setSize("50"); - column2.setDefaultValue("test"); - table.addColumn(column1); - table.addColumn(column2); - db.addTable(table); - pf.createTables(db, false, false); - - SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(pf.getDataSource()); - Assert.assertEquals(0, jdbcTemplate.queryForInt("select count(*) from TEST_TABLE_DEFAULTS")); - Assert.assertEquals("1", jdbcTemplate.queryForObject("select COLUMN_DEFAULT from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_DEFAULTS' and COLUMN_NAME='COLUMN_1'", String.class)); - Assert.assertEquals("'test'", jdbcTemplate.queryForObject("select COLUMN_DEFAULT from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_DEFAULTS' and COLUMN_NAME='COLUMN_2'", String.class)); - - column1.setDefaultValue("2"); - column2.setDefaultValue(null); - pf.alterTables(null, null, null, db, false); - Assert.assertEquals("2", jdbcTemplate.queryForObject("select COLUMN_DEFAULT from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_DEFAULTS' and COLUMN_NAME='COLUMN_1'", String.class)); - Assert.assertEquals(null, jdbcTemplate.queryForObject("select COLUMN_DEFAULT from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='TEST_TABLE_DEFAULTS' and COLUMN_NAME='COLUMN_2'", String.class)); - } - - protected Platform getPlatform() throws Exception { - PlatformFactory.registerPlatform(H2, H2Platform.class); - Platform pf = PlatformFactory.createNewPlatformInstance(H2); - Class.forName(Driver.class.getName()); - Connection c = DriverManager.getConnection("jdbc:h2:mem:test", "test", "test"); - pf.setDataSource(new SingleConnectionDataSource(c, true)); - return pf; - } -} \ No newline at end of file diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/extract/DataExtractorTest.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/extract/DataExtractorTest.java index 70043f8e6f..7017a46bd9 100644 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/extract/DataExtractorTest.java +++ b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/extract/DataExtractorTest.java @@ -19,31 +19,31 @@ * under the License. */ package org.jumpmind.symmetric.extract; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.StringWriter; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Date; - -import org.jumpmind.symmetric.common.Constants; -import org.jumpmind.symmetric.common.csv.CsvConstants; -import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.SequenceIdentifier; -import org.jumpmind.symmetric.model.Data; -import org.jumpmind.symmetric.model.DataEventType; -import org.jumpmind.symmetric.model.OutgoingBatch; -import org.jumpmind.symmetric.model.TriggerHistory; -import org.jumpmind.symmetric.service.IParameterService; -import org.jumpmind.symmetric.test.AbstractDatabaseTest; -import org.jumpmind.symmetric.test.TestConstants; -import org.jumpmind.symmetric.util.AppUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.ConnectionCallback; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Date; + +import org.jumpmind.symmetric.common.Constants; +import org.jumpmind.symmetric.common.csv.CsvConstants; +import org.jumpmind.symmetric.db.IDbDialect; +import org.jumpmind.symmetric.db.SequenceIdentifier; +import org.jumpmind.symmetric.model.Data; +import org.jumpmind.symmetric.model.DataEventType; +import org.jumpmind.symmetric.model.OutgoingBatch; +import org.jumpmind.symmetric.model.TriggerHistory; +import org.jumpmind.symmetric.service.IParameterService; +import org.jumpmind.symmetric.test.AbstractDatabaseTest; +import org.jumpmind.symmetric.test.TestConstants; +import org.jumpmind.symmetric.util.FormatUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ConnectionCallback; public class DataExtractorTest extends AbstractDatabaseTest { @@ -261,7 +261,7 @@ private TriggerHistory makeTableSyncHistoryId(String tableName, final String pk, String sql = "insert into sym_trigger_hist (trigger_hist_id, source_table_name, source_schema_name, trigger_id, column_names, pk_column_names,name_for_update_trigger,name_for_delete_trigger, name_for_insert_trigger,table_hash,trigger_row_hash,last_trigger_build_reason,create_time) " + " values (null, '" + tableName + "','symmetric','1','" + col + "' , '" + pk + "','a','b','c',1,1,'T',current_timestamp)"; - sql = AppUtils.replaceTokens(sql, dbDialect.getSqlScriptReplacementTokens(), false); + sql = FormatUtils.replaceTokens(sql, dbDialect.getSqlScriptReplacementTokens(), false); long key = dbDialect.insertWithGeneratedKey(sql, SequenceIdentifier.TRIGGER_HIST); TriggerHistory history = new TriggerHistory(tableName, pk, col); history.setTriggerHistoryId((int) key); diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/service/impl/TriggerRouterServiceTest.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/service/impl/TriggerRouterServiceTest.java index c523dfcaf7..35e4493a36 100644 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/service/impl/TriggerRouterServiceTest.java +++ b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/service/impl/TriggerRouterServiceTest.java @@ -35,8 +35,8 @@ import org.jumpmind.symmetric.common.ParameterConstants; import org.jumpmind.symmetric.db.IDbDialect; import org.jumpmind.symmetric.db.db2.Db2DbDialect; -import org.jumpmind.symmetric.db.ddl.model.Table; import org.jumpmind.symmetric.db.derby.DerbyDbDialect; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.oracle.OracleDbDialect; import org.jumpmind.symmetric.db.postgresql.PostgreSqlDbDialect; import org.jumpmind.symmetric.model.Node; diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java index c102bf914e..6d534bf3b6 100644 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java +++ b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/SimpleIntegrationTest.java @@ -40,10 +40,10 @@ import org.jumpmind.symmetric.common.ParameterConstants; import org.jumpmind.symmetric.db.IDbDialect; import org.jumpmind.symmetric.db.db2.Db2DbDialect; -import org.jumpmind.symmetric.db.ddl.model.Table; import org.jumpmind.symmetric.db.firebird.FirebirdDbDialect; import org.jumpmind.symmetric.db.informix.InformixDbDialect; import org.jumpmind.symmetric.db.interbase.InterbaseDbDialect; +import org.jumpmind.symmetric.db.model.Table; import org.jumpmind.symmetric.db.oracle.OracleDbDialect; import org.jumpmind.symmetric.db.postgresql.PostgreSqlDbDialect; import org.jumpmind.symmetric.model.Node; diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/TestSetupUtil.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/TestSetupUtil.java index 3903e11704..b36093bada 100644 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/TestSetupUtil.java +++ b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/test/TestSetupUtil.java @@ -26,6 +26,7 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.StringWriter; import java.net.URL; import java.sql.Connection; import java.sql.DriverManager; @@ -53,16 +54,14 @@ import org.jumpmind.symmetric.common.Constants; import org.jumpmind.symmetric.common.ParameterConstants; import org.jumpmind.symmetric.db.IDbDialect; -import org.jumpmind.symmetric.db.SqlScript; -import org.jumpmind.symmetric.db.ddl.Platform; -import org.jumpmind.symmetric.db.ddl.io.DatabaseIO; -import org.jumpmind.symmetric.db.ddl.model.Database; +import org.jumpmind.symmetric.db.IDatabasePlatform; +import org.jumpmind.symmetric.db.io.DatabaseIO; +import org.jumpmind.symmetric.db.model.Database; +import org.jumpmind.symmetric.db.platform.SqlBuilder; +import org.jumpmind.symmetric.db.sql.SqlScript; import org.junit.Assert; import org.springframework.mock.web.MockHttpServletRequest; - -/** - * - */ + public class TestSetupUtil { private static final String CLIENT = ".client"; @@ -239,7 +238,7 @@ protected static void dropAndCreateDatabaseTables(String databaseType, ISymmetri DataSource ds = (DataSource) engine.getApplicationContext().getBean(Constants.DATA_SOURCE); try { IDbDialect dialect = (IDbDialect) engine.getApplicationContext().getBean(Constants.DB_DIALECT); - Platform platform = dialect.getPlatform(); + IDatabasePlatform platform = dialect.getPlatform(); dialect.cleanupTriggers(); @@ -249,8 +248,11 @@ protected static void dropAndCreateDatabaseTables(String databaseType, ISymmetri new SqlScript(url, ds, false).execute(true); } - Database testDb = getTestDatabase(); - new SqlScript(platform.getDropTablesSql(testDb, true), ds, false).execute(true); + Database testDb = getTestDatabase(); + StringWriter writer = new StringWriter(); + SqlBuilder builder = platform.createSqlBuilder(writer); + builder.dropTables(testDb); + new SqlScript(writer.toString(), ds, false).execute(true); new SqlScript(getResource(TestConstants.TEST_DROP_ALL_SCRIPT), ds, false).execute(true); @@ -262,8 +264,8 @@ protected static void dropAndCreateDatabaseTables(String databaseType, ISymmetri dialect.purge(); - platform.createTables(testDb, false, true); - platform.createTables(getPreviousSymmetricVersionTables(), false, true); + platform.createDatabase(engine.getDataSource(), testDb, false, true); + platform.createDatabase(engine.getDataSource(), getPreviousSymmetricVersionTables(), false, true); } catch (Exception e) { throw new RuntimeException(e); diff --git a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/util/AppUtilsUnitTest.java b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/util/AppUtilsUnitTest.java index 12acc21cf3..7f1f1dd17f 100644 --- a/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/util/AppUtilsUnitTest.java +++ b/symmetric/symmetric-server/src/test/java/org/jumpmind/symmetric/util/AppUtilsUnitTest.java @@ -21,8 +21,6 @@ package org.jumpmind.symmetric.util; import java.util.Date; -import java.util.HashMap; -import java.util.Map; import org.apache.commons.lang.time.DateUtils; import org.junit.Assert; @@ -42,26 +40,6 @@ public void testGetLocalDateForOffset() { Assert.assertTrue(nearZero + " was the left over ms", Math.abs(nearZero) < 1000); nearZero = plusFour.getTime() - minusFour.getTime() - DateUtils.MILLIS_PER_HOUR * 8; Assert.assertTrue(nearZero + " was the left over ms", Math.abs(nearZero) < 1000); - } - - @Test - public void testReplaceTokens() { - Assert.assertEquals("test", AppUtils.replaceTokens("test", null, true)); - Assert.assertEquals("test", AppUtils.replaceTokens("test", new HashMap(), true)); - Map params = new HashMap(); - params.put("test", "1"); - Assert.assertEquals("test1", AppUtils.replaceTokens("test$(test)", params, true)); - Assert.assertEquals("test0001", AppUtils.replaceTokens("test$(test|%04d)", params, true)); - } - - @Test - public void testReplaceCurrentTimestamp() { - String beforeSql = "insert into sym_node values ('00000', 'test-root-group', '00000', 1, null, null, '2.0', null, null, current_timestamp, null, 0, 0, '00000', 'engine')"; - String afterSql = "insert into sym_node values ('00000', 'test-root-group', '00000', 1, null, null, '2.0', null, null, XXXX, null, 0, 0, '00000', 'engine')"; - Map replacementTokens = new HashMap(); - replacementTokens.put("current_timestamp", "XXXX"); - Assert.assertEquals(afterSql, AppUtils.replaceTokens(beforeSql, replacementTokens, false)); - - } + } } \ No newline at end of file diff --git a/symmetric/symmetric-util/src/main/java/org/jumpmind/symmetric/util/FormatUtils.java b/symmetric/symmetric-util/src/main/java/org/jumpmind/symmetric/util/FormatUtils.java new file mode 100644 index 0000000000..9b67745000 --- /dev/null +++ b/symmetric/symmetric-util/src/main/java/org/jumpmind/symmetric/util/FormatUtils.java @@ -0,0 +1,60 @@ +package org.jumpmind.symmetric.util; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +public final class FormatUtils { + + private static Pattern pattern = Pattern.compile("\\$\\((.+?)\\)"); + + private FormatUtils() { + } + + public static String replace(String prop, String replaceWith, String sourceString) { + return StringUtils.replace(sourceString, "$(" + prop + ")", replaceWith); + } + + public static String replaceTokens(String text, Map replacements, + boolean matchUsingPrefixSuffix) { + if (replacements != null && replacements.size() > 0) { + if (matchUsingPrefixSuffix) { + Matcher matcher = pattern.matcher(text); + StringBuffer buffer = new StringBuffer(); + while (matcher.find()) { + String[] match = matcher.group(1).split("\\|"); + String replacement = replacements.get(match[0]); + if (replacement != null) { + matcher.appendReplacement(buffer, ""); + if (match.length == 2) { + replacement = formatString(match[1], replacement); + } + buffer.append(replacement); + } + } + matcher.appendTail(buffer); + text = buffer.toString(); + } else { + for (Object key : replacements.keySet()) { + text = text.replaceAll(key.toString(), replacements.get(key)); + } + } + } + return text; + + } + + public static String formatString(String format, String arg) { + if (format.indexOf("d") >= 0 || format.indexOf("u") >= 0 || format.indexOf("i") >= 0) { + return String.format(format, Long.parseLong(arg)); + } else if (format.indexOf("e") >= 0 || format.indexOf("f") >= 0) { + return String.format(format, Double.valueOf(arg)); + } else { + return String.format(format, arg); + } + } + + +} diff --git a/symmetric/symmetric-util/src/test/java/org/jumpmind/symmetric/util/FormatUtilsTest.java b/symmetric/symmetric-util/src/test/java/org/jumpmind/symmetric/util/FormatUtilsTest.java new file mode 100644 index 0000000000..f7f3cc83a5 --- /dev/null +++ b/symmetric/symmetric-util/src/test/java/org/jumpmind/symmetric/util/FormatUtilsTest.java @@ -0,0 +1,30 @@ +package org.jumpmind.symmetric.util; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class FormatUtilsTest { + + @Test + public void testReplaceTokens() { + Assert.assertEquals("test", FormatUtils.replaceTokens("test", null, true)); + Assert.assertEquals("test", FormatUtils.replaceTokens("test", new HashMap(), true)); + Map params = new HashMap(); + params.put("test", "1"); + Assert.assertEquals("test1", FormatUtils.replaceTokens("test$(test)", params, true)); + Assert.assertEquals("test0001", FormatUtils.replaceTokens("test$(test|%04d)", params, true)); + } + + @Test + public void testReplaceCurrentTimestamp() { + String beforeSql = "insert into sym_node values ('00000', 'test-root-group', '00000', 1, null, null, '2.0', null, null, current_timestamp, null, 0, 0, '00000', 'engine')"; + String afterSql = "insert into sym_node values ('00000', 'test-root-group', '00000', 1, null, null, '2.0', null, null, XXXX, null, 0, 0, '00000', 'engine')"; + Map replacementTokens = new HashMap(); + replacementTokens.put("current_timestamp", "XXXX"); + Assert.assertEquals(afterSql, FormatUtils.replaceTokens(beforeSql, replacementTokens, false)); + + } +}