From cc253684db39c096c187f19d2d16583c15a7b2de Mon Sep 17 00:00:00 2001 From: joshahicks Date: Tue, 13 Dec 2022 14:45:04 -0500 Subject: [PATCH] 0005610: SqlAnywhere support for v. 12 and higher --- .../db/JdbcSymmetricDialectFactory.java | 4 + .../SqlAnywhere12SymmetricDialect.java | 13 ++ .../SqlAnywhere12TriggerTemplate.java | 187 ++++++++++++++++++ .../SqlAnywhereSymmetricDialect.java | 4 +- .../SqlAnywhereTriggerTemplate.java | 1 + .../db/platform/DatabaseNamesConstants.java | 1 + .../platform/JdbcDatabasePlatformFactory.java | 7 +- .../SqlAnywhere12DatabasePlatform.java | 15 ++ .../SqlAnywhereDatabasePlatform.java | 1 + 9 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12SymmetricDialect.java create mode 100644 symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12TriggerTemplate.java create mode 100644 symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhere12DatabasePlatform.java diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/JdbcSymmetricDialectFactory.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/JdbcSymmetricDialectFactory.java index af19cbee2f..e1d9f6f3a4 100644 --- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/JdbcSymmetricDialectFactory.java +++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/JdbcSymmetricDialectFactory.java @@ -44,6 +44,7 @@ import org.jumpmind.db.platform.postgresql.PostgreSqlDatabasePlatform; import org.jumpmind.db.platform.raima.RaimaDatabasePlatform; import org.jumpmind.db.platform.redshift.RedshiftDatabasePlatform; +import org.jumpmind.db.platform.sqlanywhere.SqlAnywhere12DatabasePlatform; import org.jumpmind.db.platform.sqlanywhere.SqlAnywhereDatabasePlatform; import org.jumpmind.db.platform.sqlite.SqliteDatabasePlatform; import org.jumpmind.db.platform.tibero.TiberoDatabasePlatform; @@ -75,6 +76,7 @@ import org.jumpmind.symmetric.db.postgresql.PostgreSqlSymmetricDialect; import org.jumpmind.symmetric.db.raima.RaimaSymmetricDialect; import org.jumpmind.symmetric.db.redshift.RedshiftSymmetricDialect; +import org.jumpmind.symmetric.db.sqlanywhere.SqlAnywhere12SymmetricDialect; import org.jumpmind.symmetric.db.sqlanywhere.SqlAnywhereSymmetricDialect; import org.jumpmind.symmetric.db.sqlite.SqliteJdbcSymmetricDialect; import org.jumpmind.symmetric.db.tibero.TiberoSymmetricDialect; @@ -150,6 +152,8 @@ public ISymmetricDialect create(IParameterService parameterService, IDatabasePla } } else if (platform instanceof AseDatabasePlatform) { dialect = new AseSymmetricDialect(parameterService, platform); + } else if (platform instanceof SqlAnywhere12DatabasePlatform) { + dialect = new SqlAnywhere12SymmetricDialect(parameterService, platform); } else if (platform instanceof SqlAnywhereDatabasePlatform) { dialect = new SqlAnywhereSymmetricDialect(parameterService, platform); } else if (platform instanceof InterbaseDatabasePlatform) { diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12SymmetricDialect.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12SymmetricDialect.java new file mode 100644 index 0000000000..ffa8c719c0 --- /dev/null +++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12SymmetricDialect.java @@ -0,0 +1,13 @@ +package org.jumpmind.symmetric.db.sqlanywhere; + +import org.jumpmind.db.platform.IDatabasePlatform; +import org.jumpmind.symmetric.db.mssql.MsSql2008TriggerTemplate; +import org.jumpmind.symmetric.service.IParameterService; + +public class SqlAnywhere12SymmetricDialect extends SqlAnywhereSymmetricDialect { + + public SqlAnywhere12SymmetricDialect(IParameterService parameterService, IDatabasePlatform platform) { + super(parameterService, platform); + this.triggerTemplate = new SqlAnywhere12TriggerTemplate(this); + } +} diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12TriggerTemplate.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12TriggerTemplate.java new file mode 100644 index 0000000000..9174d62763 --- /dev/null +++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhere12TriggerTemplate.java @@ -0,0 +1,187 @@ +package org.jumpmind.symmetric.db.sqlanywhere; + +import org.jumpmind.symmetric.db.ISymmetricDialect; + +public class SqlAnywhere12TriggerTemplate extends SqlAnywhereTriggerTemplate { + + public SqlAnywhere12TriggerTemplate(ISymmetricDialect symmetricDialect) { + super(symmetricDialect); + sqlTemplates.put("insertTriggerTemplate", + "create or replace trigger $(triggerName) after insert order 10000 " + + "on $(schemaName)$(tableName) referencing new as inserted " + + + " begin " + + + " declare @DataRow varchar(16384); " + + + " $(declareNewKeyVariables) " + + + " declare @ChannelId varchar(20); " + + + " declare @err_notfound EXCEPTION FOR SQLSTATE VALUE '02000'; " + + + " $(custom_before_insert_text) \n" + + " if ($(syncOnIncomingBatchCondition)) then begin " + + + " declare DataCursor cursor for " + + + " $(if:containsBlobClobColumns) " + + + " select $(columns) $(newKeyNames), $(channelExpression) from inserted inner join $(schemaName)$(tableName) $(origTableAlias) on $(tableNewPrimaryKeyJoin) where $(syncOnInsertCondition);" + + + " $(else:containsBlobClobColumns) " + + + " select $(columns) $(newKeyNames), $(channelExpression) from inserted where $(syncOnInsertCondition); " + + + " $(end:containsBlobClobColumns) " + + + " open DataCursor;" + + + " LoopGetRow:" + + + " loop " + + + " fetch next DataCursor into @DataRow $(newKeyVariables), @ChannelId; " + + + " if SQLSTATE = @err_notfound then" + + + " leave LoopGetRow" + + + " end if; " + + + " insert into $(defaultCatalog)$(defaultSchema)$(prefixName)_data (table_name, event_type, trigger_hist_id, row_data, channel_id, transaction_id, source_node_id, external_data, create_time) " + + + " values('$(targetTableName)','I', $(triggerHistoryId), @DataRow, @ChannelId, $(txIdExpression), $(defaultCatalog)$(defaultSchema)$(prefixName)_node_disabled(0), $(externalSelect), getdate()); " + + + " end loop LoopGetRow; " + + + " close DataCursor; " + + + " end; " + + + " $(custom_on_insert_text) " + + + " end if; " + + + " end; "); + sqlTemplates.put("updateTriggerTemplate", + "create or replace trigger $(triggerName) after update order 10000 on $(schemaName)$(tableName) " + + + " referencing old as deleted new as inserted " + + + " begin " + + + " declare @DataRow varchar(16384); " + + + " declare @OldPk varchar(2000); " + + + " declare @OldDataRow varchar(16384); " + + + " declare @ChannelId varchar(20);" + + + " declare @err_notfound EXCEPTION FOR SQLSTATE VALUE '02000'; " + + + " $(declareOldKeyVariables) " + + + " $(declareNewKeyVariables) " + + + " $(custom_before_update_text) " + + " if ($(syncOnIncomingBatchCondition)) then begin " + + + " declare DataCursor cursor for " + + + " $(if:containsBlobClobColumns) " + + + " select $(columns), $(oldKeys), $(oldColumns) $(oldKeyNames) $(newKeyNames), $(channelExpression) from inserted inner join $(schemaName)$(tableName) $(origTableAlias) on $(tableNewPrimaryKeyJoin) inner join deleted on $(oldNewPrimaryKeyJoin) where $(syncOnUpdateCondition);" + + + " $(else:containsBlobClobColumns) " + + + " select $(columns), $(oldKeys), $(oldColumns) $(oldKeyNames) $(newKeyNames), $(channelExpression) from inserted inner join deleted on $(oldNewPrimaryKeyJoin) where $(syncOnUpdateCondition); " + + + " $(end:containsBlobClobColumns) " + + + " open DataCursor; " + + + " LoopGetRow:" + + + " loop " + + + " fetch next DataCursor into @DataRow, @OldPk, @OldDataRow $(oldKeyVariables) $(newKeyVariables), @ChannelId; " + + + " if SQLSTATE = @err_notfound then" + + + " leave LoopGetRow" + + + " end if; " + + + " insert into $(defaultCatalog)$(defaultSchema)$(prefixName)_data (table_name, event_type, trigger_hist_id, row_data, pk_data, old_data, channel_id, transaction_id, source_node_id, external_data, create_time) " + + + " values('$(targetTableName)','U', $(triggerHistoryId), @DataRow, @OldPk, @OldDataRow, @ChannelId, $(txIdExpression), $(defaultCatalog)$(defaultSchema)$(prefixName)_node_disabled(0), $(externalSelect), getdate());" + + + " end loop LoopGetRow; " + + + " close DataCursor; " + + + " end; " + + + " $(custom_on_update_text) " + + + " end if;" + + + "end; "); + sqlTemplates.put("deleteTriggerTemplate", + "create or replace trigger $(triggerName) after delete order 10000 on $(schemaName)$(tableName) referencing old as deleted " + + + " begin " + + + " declare @OldPk varchar(2000); " + + + " declare @OldDataRow varchar(16384); " + + + " declare @ChannelId varchar(20); " + + + " declare @err_notfound EXCEPTION FOR SQLSTATE VALUE '02000'; " + + + " $(declareOldKeyVariables) " + + + " $(custom_before_delete_text) " + + " if ($(syncOnIncomingBatchCondition)) then begin " + + + " declare DataCursor cursor for " + + + " select $(oldKeys), $(oldColumns) $(oldKeyNames), $(channelExpression) from deleted where $(syncOnDeleteCondition); " + + + " open DataCursor; " + + + " LoopGetRow:" + + + " loop " + + + " fetch next DataCursor into @OldPk,@OldDataRow $(oldKeyVariables), @ChannelId; " + + + " if SQLSTATE = @err_notfound then" + + + " leave LoopGetRow" + + + " end if; " + + + " insert into $(defaultCatalog)$(defaultSchema)$(prefixName)_data (table_name, event_type, trigger_hist_id, pk_data, old_data, channel_id, transaction_id, source_node_id, external_data, create_time) " + + + " values('$(targetTableName)','D', $(triggerHistoryId), @OldPk, @OldDataRow, @ChannelId, $(txIdExpression), $(defaultCatalog)$(defaultSchema)$(prefixName)_node_disabled(0), $(externalSelect), getdate());" + + + " end loop LoopGetRow; " + + + " close DataCursor " + + + " end; " + + + " $(custom_on_delete_text) " + + + " end if;" + + + " end; "); + sqlTemplates.put("initialLoadSqlTemplate", + "select $(columns) from $(schemaName)$(tableName) t where $(whereClause) "); + } + +} diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereSymmetricDialect.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereSymmetricDialect.java index 4c4a498008..8682a2deb5 100644 --- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereSymmetricDialect.java +++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereSymmetricDialect.java @@ -136,10 +136,10 @@ public void dropRequiredDatabaseObjects() { @Override public void removeTrigger(StringBuilder sqlBuffer, final String catalogName, String schemaName, final String triggerName, String tableName, ISqlTransaction transaction) { - final String sql = "drop trigger " + Table.getFullyQualifiedTableName(catalogName, schemaName, tableName) + "." + triggerName; + final String sql = "drop trigger " + schemaName + "." + tableName + "." + triggerName; logSql(sql, sqlBuffer); if (parameterService.is(ParameterConstants.AUTO_SYNC_TRIGGERS)) { - log.info("Dropping {} trigger for {}", triggerName, Table.getFullyQualifiedTableName(catalogName, schemaName, tableName)); + log.info("Dropping {} trigger for {}", triggerName, schemaName + "." + tableName + "." + triggerName); ((JdbcSqlTransaction) transaction) .executeCallback(new IConnectionCallback() { public Boolean execute(Connection con) throws SQLException { diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereTriggerTemplate.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereTriggerTemplate.java index fb9507ea04..b90cce739c 100644 --- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereTriggerTemplate.java +++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/sqlanywhere/SqlAnywhereTriggerTemplate.java @@ -280,6 +280,7 @@ protected String buildKeyVariablesDeclare(Column[] columns, String prefix) { throw new NotImplementedException(columns[i] + " is of type " + columns[i].getMappedType()); } + text+=";"; } return text; } diff --git a/symmetric-db/src/main/java/org/jumpmind/db/platform/DatabaseNamesConstants.java b/symmetric-db/src/main/java/org/jumpmind/db/platform/DatabaseNamesConstants.java index 71a101c98d..188106b32d 100644 --- a/symmetric-db/src/main/java/org/jumpmind/db/platform/DatabaseNamesConstants.java +++ b/symmetric-db/src/main/java/org/jumpmind/db/platform/DatabaseNamesConstants.java @@ -51,6 +51,7 @@ private DatabaseNamesConstants() { public final static String POSTGRESQL95 = "postgres95"; public final static String ASE = "ase"; public final static String SQLANYWHERE = "sqlanywhere"; + public final static String SQLANYWHERE12 = "sqlanywhere12"; public final static String MARIADB = "mariadb"; public final static String REDSHIFT = "redshift"; public final static String VOLTDB = "voltdb"; diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/JdbcDatabasePlatformFactory.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/JdbcDatabasePlatformFactory.java index 5c54ff5724..f3e81c1f24 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/JdbcDatabasePlatformFactory.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/JdbcDatabasePlatformFactory.java @@ -84,6 +84,7 @@ import org.jumpmind.db.platform.postgresql.PostgreSqlDatabasePlatform; import org.jumpmind.db.platform.raima.RaimaDatabasePlatform; import org.jumpmind.db.platform.redshift.RedshiftDatabasePlatform; +import org.jumpmind.db.platform.sqlanywhere.SqlAnywhere12DatabasePlatform; import org.jumpmind.db.platform.sqlanywhere.SqlAnywhereDatabasePlatform; import org.jumpmind.db.platform.sqlite.SqliteDatabasePlatform; import org.jumpmind.db.platform.tibero.TiberoDatabasePlatform; @@ -144,7 +145,8 @@ protected JdbcDatabasePlatformFactory() { addPlatform(platforms, DatabaseNamesConstants.POSTGRESQL, PostgreSqlDatabasePlatform.class); addPlatform(platforms, DatabaseNamesConstants.POSTGRESQL95, PostgreSql95DatabasePlatform.class); addPlatform(platforms, DatabaseNamesConstants.SQLITE, SqliteDatabasePlatform.class); - addPlatform(platforms, DatabaseNamesConstants.SQLANYWHERE, SqliteDatabasePlatform.class); + addPlatform(platforms, DatabaseNamesConstants.SQLANYWHERE, SqlAnywhere12DatabasePlatform.class); + addPlatform(platforms, DatabaseNamesConstants.SQLANYWHERE12, SqlAnywhere12DatabasePlatform.class); addPlatform(platforms, DatabaseNamesConstants.RAIMA, RaimaDatabasePlatform.class); addPlatform(platforms, DatabaseNamesConstants.REDSHIFT, RedshiftDatabasePlatform.class); addPlatform(platforms, DatabaseNamesConstants.TIBERO, TiberoDatabasePlatform.class); @@ -316,6 +318,9 @@ protected void determineDatabaseNameVersionSubprotocol(DataSource dataSource, Co nameVersion.setName(DatabaseNamesConstants.MSSQLAZURE); } } + if (nameVersion.getProtocol().equalsIgnoreCase(SqlAnywhereDatabasePlatform.JDBC_SUBPROTOCOL_SHORT) && nameVersion.getVersion() >= 12) { + nameVersion.setName(DatabaseNamesConstants.SQLANYWHERE12); + } } private boolean isGreenplumDatabase(Connection connection) { diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhere12DatabasePlatform.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhere12DatabasePlatform.java new file mode 100644 index 0000000000..b8bf706266 --- /dev/null +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhere12DatabasePlatform.java @@ -0,0 +1,15 @@ +package org.jumpmind.db.platform.sqlanywhere; + +import javax.sql.DataSource; + +import org.jumpmind.db.platform.DatabaseNamesConstants; +import org.jumpmind.db.sql.SqlTemplateSettings; + +public class SqlAnywhere12DatabasePlatform extends SqlAnywhereDatabasePlatform { + + public SqlAnywhere12DatabasePlatform(DataSource dataSource, SqlTemplateSettings settings) { + super(dataSource, settings); + } + + +} diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java index a4bb536530..a6abc1edab 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java @@ -63,6 +63,7 @@ public class SqlAnywhereDatabasePlatform extends AbstractJdbcDatabasePlatform { public static final String JDBC_DRIVER_OLD = "com.sybase.jdbc4.jdbc.SybDriver"; /* The subprotocol used by the standard Sybase driver. */ public static final String JDBC_SUBPROTOCOL = "sybase:Tds"; + public static final String JDBC_SUBPROTOCOL_SHORT = "sybase"; /* The maximum size that text and binary columns can have. */ public static final long MAX_TEXT_SIZE = 2147483647; private Map sqlScriptReplacementTokens;