Skip to content

Commit

Permalink
0005558: Create table without defaults if in error
Browse files Browse the repository at this point in the history
  • Loading branch information
erilong committed Oct 27, 2022
1 parent f064089 commit c491e0b
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 16 deletions.
Expand Up @@ -218,6 +218,7 @@ private ParameterConstants() {
public final static String DATA_LOADER_TIME_BETWEEN_ACK_RETRIES = "time.between.ack.retries.ms";
public final static String DATA_LOADER_MAX_ROWS_BEFORE_COMMIT = "dataloader.max.rows.before.commit";
public final static String DATA_LOADER_CREATE_TABLE_ALTER_TO_MATCH_DB_CASE = "dataloader.create.table.alter.to.match.db.case";
public final static String DATA_LOADER_CREATE_TABLE_WITHOUT_DEFAULTS_ON_ERROR = "dataloader.create.table.without.defaults.on.error";
public final static String DATA_LOADER_TEXT_COLUMN_EXPRESSION = "dataloader.text.column.expression";
public final static String DATA_LOADER_SLEEP_TIME_AFTER_EARLY_COMMIT = "dataloader.sleep.time.after.early.commit";
public final static String DATA_LOADER_TREAT_DATETIME_AS_VARCHAR = "db.treat.date.time.as.varchar.enabled";
Expand Down
Expand Up @@ -21,15 +21,13 @@
package org.jumpmind.symmetric.extract;

import java.sql.Types;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.jumpmind.db.io.DatabaseXmlUtil;
import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.Database;
import org.jumpmind.db.model.PlatformColumn;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.platform.DatabaseNamesConstants;
import org.jumpmind.db.sql.DmlStatement;
Expand Down Expand Up @@ -263,17 +261,7 @@ protected boolean processCreateEvent(TriggerHistory triggerHistory, String route
db.setSchema(copyTargetTable.getSchema());
db.addTable(copyTargetTable);
if (excludeDefaults) {
Column[] columns = copyTargetTable.getColumns();
for (Column column : columns) {
column.setDefaultValue(null);
Map<String, PlatformColumn> platformColumns = column.getPlatformColumns();
if (platformColumns != null) {
Collection<PlatformColumn> cols = platformColumns.values();
for (PlatformColumn platformColumn : cols) {
platformColumn.setDefaultValue(null);
}
}
}
copyTargetTable.removeAllColumnDefaults();
}
if (excludeForeignKeys || deferConstraints) {
copyTargetTable.removeAllForeignKeys();
Expand Down
Expand Up @@ -42,6 +42,8 @@ public DatabaseWriterSettings buildParameterDatabaseWriterSettings(List<? extend
DatabaseWriterSettings settings = new DatabaseWriterSettings();
settings.setCreateTableAlterCaseToMatchDatabaseDefault(
parameterService.is(ParameterConstants.DATA_LOADER_CREATE_TABLE_ALTER_TO_MATCH_DB_CASE, true));
settings.setCreateTableWithoutDefaultsOnError(
parameterService.is(ParameterConstants.DATA_LOADER_CREATE_TABLE_WITHOUT_DEFAULTS_ON_ERROR, false));
settings.setMaxRowsBeforeCommit(
parameterService.getLong(ParameterConstants.DATA_LOADER_MAX_ROWS_BEFORE_COMMIT));
settings.setCommitSleepInterval(
Expand Down
Expand Up @@ -1787,6 +1787,13 @@ dataloader.sleep.time.after.early.commit=5
# Tags: load
dataloader.create.table.alter.to.match.db.case=true

# If set to true, when a table creation fails on a database platform that is different than
# the source database, try to create the table without default values.
#
# DatabaseOverridable: true
# Type: boolean
dataloader.create.table.without.defaults.on.error=true

# Indicate that the data loader should ignore errors while loading a SQL event and the execution of the statement fails.
# DatabaseOverridable: true
# Tags: load
Expand Down
Expand Up @@ -1000,6 +1000,18 @@ public void makePlatformSpecific(Database database) {
}
}

@Override
public boolean hasMatchingPlatform(Database db) {
boolean matches = true;
for (Table table : db.getTables()) {
for (Column column : table.getColumns()) {
matches &= column.getPlatformColumns() != null && column.getPlatformColumns().get(getName()) != null;
break;
}
}
return matches;
}

public List<PermissionResult> checkSymTablePermissions(PermissionType... permissionTypes) {
List<PermissionResult> results = new ArrayList<PermissionResult>();
Database database = new Database();
Expand Down
Expand Up @@ -213,6 +213,8 @@ public Object[] getObjectValues(BinaryEncoding encoding, String[] values,

public void makePlatformSpecific(Database database);

public boolean hasMatchingPlatform(Database database);

public List<PermissionResult> checkSymTablePermissions(PermissionType... permissionTypes);

public PermissionResult getLogMinePermission();
Expand Down
Expand Up @@ -42,6 +42,7 @@ public class DatabaseWriterSettings {
protected boolean createTableDropFirst = false;
protected boolean applyChangesOnly = true;
protected boolean createTableAlterCaseToMatchDatabaseDefault = false;
protected boolean createTableWithoutDefaultsOnError = false;
protected boolean ignoreMissingTables = true;
protected boolean saveCurrentValueOnError = false;
protected boolean fitToColumn = false;
Expand Down Expand Up @@ -131,6 +132,14 @@ public void setCreateTableAlterCaseToMatchDatabaseDefault(
this.createTableAlterCaseToMatchDatabaseDefault = createTableAlterCaseToMatchDatabaseDefault;
}

public boolean isCreateTableWithoutDefaultsOnError() {
return createTableWithoutDefaultsOnError;
}

public void setCreateTableWithoutDefaultsOnError(boolean createTableWithoutDefaultsOnError) {
this.createTableWithoutDefaultsOnError = createTableWithoutDefaultsOnError;
}

public Map<String, Conflict> getConflictSettingsByChannel() {
return conflictSettingsByChannel;
}
Expand Down
Expand Up @@ -602,18 +602,30 @@ protected LoadStatus update(CsvData data, boolean applyChangesOnly, boolean useC

@Override
protected boolean create(CsvData data) {
return create(data, false);
}

protected boolean create(CsvData data, boolean withoutDefaults) {
String xml = null;
Database db = null;
boolean hasMatchingPlatform = false;
try {
getTargetTransaction().commit();
statistics.get(batch).startTimer(DataWriterStatisticConstants.LOADMILLIS);
xml = data.getParsedData(CsvData.ROW_DATA)[0];
log.info("About to create table using the following definition: {}", xml);
StringReader reader = new StringReader(xml);
Database db = DatabaseXmlUtil.read(reader, false);
db = DatabaseXmlUtil.read(reader, false);
hasMatchingPlatform = getTargetPlatform().hasMatchingPlatform(db);
if (writerSettings.isCreateTableAlterCaseToMatchDatabaseDefault()) {
getTargetPlatform().alterCaseToMatchDatabaseDefaultCase(db);
}
getTargetPlatform().makePlatformSpecific(db);
if (withoutDefaults) {
for (Table table : db.getTables()) {
table.removeAllColumnDefaults();
}
}
if (writerSettings.isAlterTable()) {
getTargetPlatform().alterDatabase(db, !writerSettings.isCreateTableFailOnError(), writerSettings.getAlterDatabaseInterceptors());
} else {
Expand All @@ -623,8 +635,12 @@ protected boolean create(CsvData data) {
statistics.get(batch).increment(DataWriterStatisticConstants.CREATECOUNT);
return true;
} catch (RuntimeException ex) {
log.error("Failed to alter table using the following xml: " + xml, ex); // This is not logged upstream
throw ex;
if (!withoutDefaults && writerSettings.isCreateTableWithoutDefaultsOnError() && !hasMatchingPlatform) {
log.info("Attempting to create table again without defaults");
return create(data, true);
} else {
throw ex;
}
} finally {
statistics.get(batch).stopTimer(DataWriterStatisticConstants.LOADMILLIS);
}
Expand Down

0 comments on commit c491e0b

Please sign in to comment.