diff --git a/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java b/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java index b55bc9b8a8..7b9edd7b7b 100644 --- a/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java +++ b/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java @@ -208,4 +208,11 @@ protected String getDbSpecificDataHasChangedCondition(Trigger trigger) { } } + @Override + protected String getDropTriggerSql(StringBuilder sqlBuffer, String catalogName, + String schemaName, String triggerName, String tableName, TriggerHistory oldHistory) { + return "drop trigger " + triggerName; + } + + } diff --git a/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlSymmetricDialect.java b/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlSymmetricDialect.java index 2e6a45d98e..2ddefa56b2 100644 --- a/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlSymmetricDialect.java +++ b/symmetric/symmetric-client/src/main/java/org/jumpmind/symmetric/db/postgresql/PostgreSqlSymmetricDialect.java @@ -110,11 +110,14 @@ public void removeTrigger(StringBuilder sqlBuffer, String catalogName, String sc final String dropFunction = "drop function " + schemaName + "f" + triggerName + "()"; logSql(dropFunction, sqlBuffer); if (parameterService.is(ParameterConstants.AUTO_SYNC_TRIGGERS)) { + String sql = null; try { + sql = dropSql; platform.getSqlTemplate().update(dropSql); + sql = dropFunction; platform.getSqlTemplate().update(dropFunction); } catch (Exception e) { - log.warn("Trigger does not exist"); + log.warn("Tried to remove trigger using: {} and failed because: {}", sql, e.getMessage()); } } } diff --git a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java index e6666d9295..9140e76899 100644 --- a/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java +++ b/symmetric/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java @@ -211,17 +211,22 @@ public Set getSqlKeywords() { } return sqlKeywords; } + + protected String getDropTriggerSql(StringBuilder sqlBuffer, String catalogName, String schemaName, + String triggerName, String tableName, TriggerHistory oldHistory) { + schemaName = schemaName == null ? "" : (schemaName + "."); + return "drop trigger " + schemaName + triggerName; + } public void removeTrigger(StringBuilder sqlBuffer, String catalogName, String schemaName, String triggerName, String tableName, TriggerHistory oldHistory) { - schemaName = schemaName == null ? "" : (schemaName + "."); - final String sql = "drop trigger " + schemaName + triggerName; + String sql = getDropTriggerSql(sqlBuffer, catalogName, schemaName, triggerName, tableName, oldHistory); logSql(sql, sqlBuffer); if (parameterService.is(ParameterConstants.AUTO_SYNC_TRIGGERS)) { try { this.platform.getSqlTemplate().update(sql); } catch (Exception e) { - log.warn("Trigger does not exist"); + log.warn("Tried to remove trigger using: {} and failed because: {}", sql, e.getMessage()); } } } 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 f452529324..3e105eb8a2 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 @@ -157,6 +157,10 @@ public int getTableHash() { public void setTableHash(int tableHash) { this.tableHash = tableHash; } + + public String getFullyQualifiedSourceTableName() { + return Table.getFullyQualifiedTableName(sourceCatalogName, sourceSchemaName, sourceTableName); + } public String getSourceTableName() { return sourceTableName; 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 e244d3043d..25b1f9e67a 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 @@ -794,12 +794,41 @@ protected Set getTriggerIdsFrom(List triggersThatShouldBeActive protected void inactivateTriggers(List triggersThatShouldBeActive, StringBuilder sqlBuffer) { + boolean ignoreCase = this.parameterService + .is(ParameterConstants.DB_METADATA_IGNORE_CASE); List activeHistories = getActiveTriggerHistories(); - Set triggerIdsThatShouldBeActive = getTriggerIdsFrom(triggersThatShouldBeActive); + Map> tablesByTriggerId = new HashMap>(); for (TriggerHistory history : activeHistories) { - if (!triggerIdsThatShouldBeActive.contains(history.getTriggerId())) { + boolean removeTrigger = false; + Set tables = tablesByTriggerId.get(history.getTriggerId()); + Trigger trigger = getTriggerById(history.getTriggerId(), false); + if (tables == null) { + tables = getTablesForTrigger(trigger, triggersThatShouldBeActive); + tablesByTriggerId.put(trigger.getTriggerId(), tables); + } + + if (tables == null || trigger == null) { + removeTrigger = true; + } else { + if (!StringUtils.equals(trigger.getSourceCatalogName(), + history.getSourceCatalogName()) + || !StringUtils.equals(trigger.getSourceSchemaName(), + history.getSourceSchemaName())) { + removeTrigger = true; + } else { + if (trigger.isSourceTableNameWildcarded()) { + boolean foundMatch = false; + for (Table table : tables) { + foundMatch |= ignoreCase ? StringUtils.equalsIgnoreCase(table.getName(), history.getSourceTableName()) : StringUtils.equals(table.getName(), history.getSourceTableName()); + } + removeTrigger = !foundMatch; + } + } + } + + if (removeTrigger) { log.info("About to remove triggers for inactivated table: {}", - history.getSourceTableName()); + history.getFullyQualifiedSourceTableName()); symmetricDialect.removeTrigger(sqlBuffer, history.getSourceCatalogName(), history.getSourceSchemaName(), history.getNameForInsertTrigger(), history.getSourceTableName(), history); @@ -858,7 +887,7 @@ protected Set
getTablesForTrigger(Trigger trigger, List triggers if (trigger.isSourceTableNameWildcarded()) { boolean ignoreCase = this.parameterService .is(ParameterConstants.DB_METADATA_IGNORE_CASE); - + Database database = symmetricDialect.getPlatform().readDatabase( trigger.getSourceCatalogName(), trigger.getSourceSchemaName(), new String[] { "TABLE" }); @@ -868,7 +897,8 @@ protected Set
getTablesForTrigger(Trigger trigger, List triggers for (String wildcardToken : wildcardTokens) { for (Table table : tableArray) { if (FormatUtils.isWildCardMatch(table.getName(), wildcardToken, ignoreCase) - && !containsExactMatchForSourceTableName(table.getName(), triggers, ignoreCase) + && !containsExactMatchForSourceTableName(table.getName(), triggers, + ignoreCase) && !table.getName().toLowerCase().startsWith(tablePrefix)) { tables.add(table); } else { @@ -887,7 +917,8 @@ protected Set
getTablesForTrigger(Trigger trigger, List triggers return tables; } - private boolean containsExactMatchForSourceTableName(String tableName, List triggers, boolean ignoreCase) { + private boolean containsExactMatchForSourceTableName(String tableName, List triggers, + boolean ignoreCase) { for (Trigger trigger : triggers) { if (trigger.getSourceTableName().equals(tableName)) { return true; @@ -903,23 +934,24 @@ protected void updateOrCreateDatabaseTriggers(List triggers, StringBuil for (Trigger trigger : triggers) { TriggerHistory newestHistory = null; - try { - TriggerReBuildReason reason = TriggerReBuildReason.NEW_TRIGGERS; - - String errorMessage = null; - Channel channel = configurationService.getChannel(trigger.getChannelId()); - if (channel == null) { - errorMessage = String - .format("Trigger %s had an unrecognized channel_id of '%s'. Please check to make sure the channel exists. Creating trigger on the '%s' channel", - trigger.getTriggerId(), trigger.getChannelId(), - Constants.CHANNEL_DEFAULT); - log.error(errorMessage); - trigger.setChannelId(Constants.CHANNEL_DEFAULT); - } + TriggerReBuildReason reason = TriggerReBuildReason.NEW_TRIGGERS; + + String errorMessage = null; + Channel channel = configurationService.getChannel(trigger.getChannelId()); + if (channel == null) { + errorMessage = String + .format("Trigger %s had an unrecognized channel_id of '%s'. Please check to make sure the channel exists. Creating trigger on the '%s' channel", + trigger.getTriggerId(), trigger.getChannelId(), + Constants.CHANNEL_DEFAULT); + log.error(errorMessage); + trigger.setChannelId(Constants.CHANNEL_DEFAULT); + } + + Set
tables = getTablesForTrigger(trigger, triggers); + if (tables.size() > 0) { + for (Table table : tables) { + try { - Set
tables = getTablesForTrigger(trigger, triggers); - if (tables.size() > 0) { - for (Table table : tables) { if (table.getPrimaryKeyColumnCount() == 0) { table = table.copy(); table.makeAllColumnsPrimaryKeys(); @@ -986,44 +1018,48 @@ protected void updateOrCreateDatabaseTriggers(List triggers, StringBuil } } } - } - } else { - log.error( - "Could not find any database tables matching '{}' in the datasource that is configured", - trigger.qualifiedSourceTableName()); + } catch (Exception ex) { + log.error( + String.format("Failed to create triggers for %s", + trigger.qualifiedSourceTableName()), ex); - if (this.triggerCreationListeners != null) { - for (ITriggerCreationListener l : this.triggerCreationListeners) { - l.tableDoesNotExist(trigger); + if (newestHistory != null) { + // Make sure all the triggers are removed from the + // table + symmetricDialect.removeTrigger(null, trigger.getSourceCatalogName(), + trigger.getSourceSchemaName(), + newestHistory.getNameForInsertTrigger(), + trigger.getSourceTableName(), newestHistory); + symmetricDialect.removeTrigger(null, trigger.getSourceCatalogName(), + trigger.getSourceSchemaName(), + newestHistory.getNameForUpdateTrigger(), + trigger.getSourceTableName(), newestHistory); + symmetricDialect.removeTrigger(null, trigger.getSourceCatalogName(), + trigger.getSourceSchemaName(), + newestHistory.getNameForDeleteTrigger(), + trigger.getSourceTableName(), newestHistory); + } + + if (this.triggerCreationListeners != null) { + for (ITriggerCreationListener l : this.triggerCreationListeners) { + l.triggerFailed(trigger, ex); + } } } } - } catch (Exception ex) { + + } else { log.error( - String.format("Failed to create triggers for %s", - trigger.qualifiedSourceTableName()), ex); - - if (newestHistory != null) { - // Make sure all the triggers are removed from the table - symmetricDialect.removeTrigger(null, trigger.getSourceCatalogName(), - trigger.getSourceSchemaName(), newestHistory.getNameForInsertTrigger(), - trigger.getSourceTableName(), newestHistory); - symmetricDialect.removeTrigger(null, trigger.getSourceCatalogName(), - trigger.getSourceSchemaName(), newestHistory.getNameForUpdateTrigger(), - trigger.getSourceTableName(), newestHistory); - symmetricDialect.removeTrigger(null, trigger.getSourceCatalogName(), - trigger.getSourceSchemaName(), newestHistory.getNameForDeleteTrigger(), - trigger.getSourceTableName(), newestHistory); - } + "Could not find any database tables matching '{}' in the datasource that is configured", + trigger.qualifiedSourceTableName()); if (this.triggerCreationListeners != null) { for (ITriggerCreationListener l : this.triggerCreationListeners) { - l.triggerFailed(trigger, ex); + l.tableDoesNotExist(trigger); } } } - } } @@ -1070,7 +1106,8 @@ protected TriggerHistory rebuildTriggerIfNecessary(StringBuilder sqlBuffer, if ((forceRebuild || !triggerIsActive) && triggerExists) { symmetricDialect.removeTrigger(sqlBuffer, oldCatalogName, oldSourceSchema, - oldTriggerName, trigger.getSourceTableName(), oldhist); + oldTriggerName, trigger.isSourceTableNameWildcarded() ? table.getName() : trigger + .getSourceTableName(), oldhist); triggerExists = false; triggerRemoved = true; }