Skip to content

Commit

Permalink
0001249: move replaceSql to DmlStatement. Use DmlStatementFactory fro…
Browse files Browse the repository at this point in the history
…m AbstractDatabasePlatform for consistency

0001273: Add new parameter to dbexport to request that dates and time NOT be in JDBC format
  • Loading branch information
chenson42 committed Jun 12, 2013
1 parent 7c44ac7 commit 4522154
Show file tree
Hide file tree
Showing 20 changed files with 208 additions and 179 deletions.
Expand Up @@ -52,6 +52,8 @@ public class DbExportCommand extends AbstractCommandLauncher {
private static final String OPTION_USE_VARIABLE_DATES = "use-variable-dates";

private static final String OPTION_NO_QUALIFIERS = "no-qualifiers";

private static final String OPTION_USE_JDBC_TIMESTAMP_FORMAT = "use-jdbc-timestamp-format";

private static final String OPTION_SQL = "sql";

Expand Down Expand Up @@ -102,6 +104,7 @@ protected void buildOptions(Options options) {
addOption(options, null, OPTION_NO_FOREIGN_KEYS, false);
addOption(options, null, OPTION_NO_DATA, false);
addOption(options, null, OPTION_USE_VARIABLE_DATES, false);
addOption(options, null, OPTION_USE_JDBC_TIMESTAMP_FORMAT, true);
addOption(options, null, OPTION_NO_QUALIFIERS, false);
addOption(options, null, OPTION_SQL, true);
addOption(options, "i", OPTION_COMMENTS, false);
Expand Down Expand Up @@ -154,6 +157,9 @@ protected boolean executeWithOptions(CommandLine line) throws Exception {
if (line.hasOption(OPTION_USE_VARIABLE_DATES)) {
dbExport.setUseVariableForDates(true);
}
if (line.hasOption(OPTION_USE_JDBC_TIMESTAMP_FORMAT)) {
dbExport.setUseJdbcTimestampFormat("true".equalsIgnoreCase(line.getOptionValue(OPTION_USE_JDBC_TIMESTAMP_FORMAT)));
}
if (line.hasOption(OPTION_NO_QUALIFIERS)) {
dbExport.setUseQuotedIdentifiers(false);
}
Expand Down
Expand Up @@ -111,6 +111,7 @@ DbExport.Option.no-indices=Do not write statements to create indices.
DbExport.Option.no-foreign-keys=Do not write statements to create foreign keys.
DbExport.Option.no-data=Do not write statements to insert into tables.
DbExport.Option.use-variable-dates=Substitute dates as ${curdate+-millis}.
DbExport.Option.use-jdbc-timestamp-format=When true db export uses {ts 'yyyy-MM-dd hh:mm:ss.SSS'} format for exported dates and times. Defaults to true.
DbExport.Option.no-qualifiers=Do not qualify table and columns names with quoted identifiers.
DbExport.Option.comments=Write informational comments.
DbExport.Option.format=Output format: SQL, CSV, XML, or SYM_XML.
Expand Down
Expand Up @@ -248,9 +248,7 @@ protected void assertCountDbImportTableRecords(int expected) {
IDatabasePlatform platform = engine.getSymmetricDialect().getPlatform();
Database testTables = platform.readDatabaseFromXml("/test-dbimport.xml", true);
Table table = testTables.findTable("test_db_import_1", false);
DmlStatement dml = new DmlStatement(DmlType.COUNT, table.getCatalog(), table.getSchema(),
table.getName(), null, table.getColumns(), false, null, null);
Assert.assertEquals(expected, platform.getSqlTemplate().queryForInt(dml.getSql()));
Assert.assertEquals(expected, platform.getSqlTemplate().queryForInt("select count(*) from " + table.getName()));
}

@Test
Expand Down Expand Up @@ -372,9 +370,7 @@ public void exportThenImportCsv() throws Exception {
importCsv.setFormat(DbImport.Format.CSV);
importCsv.importTables(csvOutput, table.getName());

DmlStatement dml = new DmlStatement(DmlType.COUNT, table.getCatalog(), table.getSchema(),
table.getName(), null, table.getColumns(), false, null, null);
Assert.assertEquals(RECORD_COUNT, sqlTemplate.queryForInt(dml.getSql()));
Assert.assertEquals(RECORD_COUNT, sqlTemplate.queryForInt("select count(*) from " + table.getName()));

compareRows(table, rowsBeforeImport, sqlTemplate.query(SELECT_FROM_TEST_DB_IMPORT_1_ORDER_BY_ID));

Expand Down
Expand Up @@ -42,7 +42,7 @@ public interface IDataExtractorService {

public void extractConfigurationStandalone(Node node, Writer out, String... tablesToIgnore);

public List<OutgoingBatchWithPayload> extractToPayload(ProcessInfo processInfo, Node targetNode, PayloadType payloadType);
public List<OutgoingBatchWithPayload> extractToPayload(ProcessInfo processInfo, Node targetNode, PayloadType payloadType, boolean useJdbcTimestampFormat);

/**
* @return a list of batches that were extracted
Expand Down
Expand Up @@ -310,7 +310,7 @@ private List<OutgoingBatch> filterBatchesForExtraction(OutgoingBatches batches,
}

public List<OutgoingBatchWithPayload> extractToPayload(ProcessInfo processInfo,
Node targetNode, PayloadType payloadType) {
Node targetNode, PayloadType payloadType, boolean useJdbcTimestampFormat) {

OutgoingBatches batches = outgoingBatchService.getOutgoingBatches(targetNode.getNodeId(),
false);
Expand All @@ -325,7 +325,7 @@ public List<OutgoingBatchWithPayload> extractToPayload(ProcessInfo processInfo,
if (activeBatches.size() > 0) {
StructureDataWriter writer = new StructureDataWriter(symmetricDialect.getPlatform(), targetNode.getDatabaseType(), payloadType,
// TODO might want to pass this into the rest call as an optional parameter
parameterService.is(ParameterConstants.DB_DELIMITED_IDENTIFIER_MODE), symmetricDialect.getBinaryEncoding());
parameterService.is(ParameterConstants.DB_DELIMITED_IDENTIFIER_MODE), symmetricDialect.getBinaryEncoding(), useJdbcTimestampFormat);
List<OutgoingBatch> extractedBatches = extract(processInfo, targetNode,
activeBatches, writer, false);

Expand Down
Expand Up @@ -111,9 +111,8 @@ public DmlStatement createDmlStatement(DmlType dmlType, Table table) {

public DmlStatement createDmlStatement(DmlType dmlType, String catalogName, String schemaName,
String tableName, Column[] keys, Column[] columns, boolean[] nullKeyValues) {
return new DmlStatement(dmlType, catalogName, schemaName, tableName, keys, columns,
getDdlBuilder().getDatabaseInfo().isDateOverridesToTimestamp(), getDdlBuilder()
.getDatabaseInfo().getDelimiterToken(), nullKeyValues);
return DmlStatementFactory.createDmlStatement(getName(), dmlType, catalogName, schemaName,
tableName, keys, columns, nullKeyValues, getDdlBuilder());
}

public IDdlReader getDdlReader() {
Expand Down Expand Up @@ -459,73 +458,6 @@ protected String getDateTimeStringValue(String name, int type, Row row,
}
}

public String replaceSql(String sql, BinaryEncoding encoding, Table table, Row row,
boolean useVariableDates) {
final String QUESTION_MARK = "<!QUESTION_MARK!>";
String newSql = sql;
String quote = getDatabaseInfo().getValueQuoteToken();
String regex = "\\?";

List<Column> columnsToProcess = new ArrayList<Column>();
columnsToProcess.addAll(table.getColumnsAsList());
columnsToProcess.addAll(table.getPrimaryKeyColumnsAsList());

for (int i = 0; i < columnsToProcess.size(); i++) {
Column column = columnsToProcess.get(i);
String name = column.getName();
int type = column.getJdbcTypeCode();

if (row.get(name) != null) {
if (column.isOfTextType()) {
try {
String value = row.getString(name);
value = value.replace("\\", "\\\\");
value = value.replace("$", "\\$");
value = value.replace("'", "''");
value = value.replace("?", QUESTION_MARK);
newSql = newSql.replaceFirst(regex, quote + value + quote);
} catch (RuntimeException ex) {
log.error("Failed to replace ? in {" + sql + "} with " + name + "="
+ row.getString(name));
throw ex;
}
} else if (column.isTimestampWithTimezone()) {
newSql = newSql.replaceFirst(regex, quote + row.getString(name) + quote);
} else if (type == Types.DATE || type == Types.TIMESTAMP || type == Types.TIME) {
Date date = row.getDateTime(name);
if (useVariableDates) {
long diff = date.getTime() - System.currentTimeMillis();
newSql = newSql.replaceFirst(regex, "${curdate" + diff + "}");
} else if (type == Types.TIME) {
newSql = newSql.replaceFirst(regex,
"{ts " + quote + FormatUtils.TIME_FORMATTER.format(date) + quote + "}");
} else {
newSql = newSql.replaceFirst(regex,
"{ts " + quote + FormatUtils.TIMESTAMP_FORMATTER.format(date) + quote + "}");
}
} else if (column.isOfBinaryType()) {
byte[] bytes = row.getBytes(name);
if (encoding == BinaryEncoding.NONE) {
newSql = newSql.replaceFirst(regex, quote + row.getString(name));
} else if (encoding == BinaryEncoding.BASE64) {
newSql = newSql.replaceFirst(regex,
quote + new String(Base64.encodeBase64(bytes)) + quote);
} else if (encoding == BinaryEncoding.HEX) {
newSql = newSql.replaceFirst(regex, quote
+ new String(Hex.encodeHex(bytes)) + quote);
}
} else {
newSql = newSql.replaceFirst(regex, row.getString(name));
}
} else {
newSql = newSql.replaceFirst(regex, "null");
}
}

newSql = newSql.replace(QUESTION_MARK, "?");
return newSql + getDatabaseInfo().getSqlCommandDelimiter();
}

public Map<String, String> getSqlScriptReplacementTokens() {
return null;
}
Expand Down
Expand Up @@ -22,6 +22,7 @@

import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.platform.mysql.MySqlDmlStatement;
import org.jumpmind.db.platform.oracle.OracleDmlStatement;
import org.jumpmind.db.platform.postgresql.PostgreSqlDmlStatement;
import org.jumpmind.db.sql.DmlStatement;
Expand All @@ -32,27 +33,41 @@ final public class DmlStatementFactory {
private DmlStatementFactory() {
}

public static DmlStatement createDmlStatement(String databaseName, DmlType dmlType, Table table, boolean useQuotedIdentifiers) {
public static DmlStatement createDmlStatement(String databaseName, DmlType dmlType,
Table table, boolean useQuotedIdentifiers) {
return createDmlStatement(databaseName, dmlType, table.getCatalog(), table.getSchema(),
table.getName(), table.getPrimaryKeyColumns(), table.getColumns(), null, useQuotedIdentifiers);
table.getName(), table.getPrimaryKeyColumns(), table.getColumns(), null,
useQuotedIdentifiers);
}

public static DmlStatement createDmlStatement(String databaseName, DmlType dmlType,
String catalogName, String schemaName, String tableName, Column[] keys,
Column[] columns, boolean[] nullKeyValues, boolean useQuotedIdentifiers) {
IDdlBuilder ddlBuilder = DdlBuilderFactory.createDdlBuilder(databaseName);
ddlBuilder.setDelimitedIdentifierModeOn(useQuotedIdentifiers);
return createDmlStatement(databaseName, dmlType, catalogName, schemaName, tableName, keys,
columns, nullKeyValues, ddlBuilder);
}

public static DmlStatement createDmlStatement(String databaseName, DmlType dmlType,
String catalogName, String schemaName, String tableName, Column[] keys,
Column[] columns, boolean[] nullKeyValues, IDdlBuilder ddlBuilder) {
if (DatabaseNamesConstants.ORACLE.equals(databaseName)) {
return new OracleDmlStatement(dmlType, catalogName, schemaName, tableName, keys,
columns, ddlBuilder.getDatabaseInfo().isDateOverridesToTimestamp(), useQuotedIdentifiers ? ddlBuilder
.getDatabaseInfo().getDelimiterToken() : "", nullKeyValues);
columns, nullKeyValues, ddlBuilder.getDatabaseInfo(),
ddlBuilder.isDelimitedIdentifierModeOn());
} else if (DatabaseNamesConstants.POSTGRESQL.equals(databaseName)) {
return new PostgreSqlDmlStatement(dmlType, catalogName, schemaName, tableName, keys,
columns, ddlBuilder.getDatabaseInfo().isDateOverridesToTimestamp(), useQuotedIdentifiers ? ddlBuilder
.getDatabaseInfo().getDelimiterToken() : "", nullKeyValues);
columns, nullKeyValues, ddlBuilder.getDatabaseInfo(),
ddlBuilder.isDelimitedIdentifierModeOn());
} else if (DatabaseNamesConstants.MYSQL.equals(databaseName)) {
return new MySqlDmlStatement(dmlType, catalogName, schemaName, tableName, keys,
columns, nullKeyValues, ddlBuilder.getDatabaseInfo(),
ddlBuilder.isDelimitedIdentifierModeOn());
} else {
return new DmlStatement(dmlType, catalogName, schemaName, tableName, keys, columns,
ddlBuilder.getDatabaseInfo().isDateOverridesToTimestamp(), useQuotedIdentifiers ? ddlBuilder
.getDatabaseInfo().getDelimiterToken() : "", nullKeyValues);
nullKeyValues, ddlBuilder.getDatabaseInfo(),
ddlBuilder.isDelimitedIdentifierModeOn());
}

}
Expand Down
Expand Up @@ -125,8 +125,6 @@ public Object[] getObjectValues(BinaryEncoding encoding, String[] values,

public String[] getStringValues(BinaryEncoding encoding, Column[] metaData, Row row, boolean useVariableDates);

public String replaceSql(String sql, BinaryEncoding encoding, Table table, Row row, boolean useVariableDates);

public Database readDatabaseFromXml(String filePath, boolean alterCaseToMatchDatabaseDefaultCase);

public Database readDatabaseFromXml(InputStream in, boolean alterCaseToMatchDatabaseDefaultCase);
Expand Down
Expand Up @@ -22,15 +22,16 @@

import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.TypeMap;
import org.jumpmind.db.platform.DatabaseInfo;
import org.jumpmind.db.sql.DmlStatement;

public class MySqlDmlStatement extends DmlStatement {

public MySqlDmlStatement(DmlType type, String catalogName, String schemaName,
String tableName, Column[] keys, Column[] columns, boolean isDateOverrideToTimestamp,
String identifierQuoteString, boolean[] nullKeyValues) {
super(type, catalogName, schemaName, tableName, keys, columns, isDateOverrideToTimestamp,
identifierQuoteString, nullKeyValues);
public MySqlDmlStatement(DmlType type, String catalogName, String schemaName, String tableName,
Column[] keysColumns, Column[] columns, boolean[] nullKeyValues,
DatabaseInfo databaseInfo, boolean useQuotedIdentifiers) {
super(type, catalogName, schemaName, tableName, keysColumns, columns,
nullKeyValues, databaseInfo, useQuotedIdentifiers);
}

@Override
Expand Down
Expand Up @@ -24,15 +24,16 @@

import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.TypeMap;
import org.jumpmind.db.platform.DatabaseInfo;
import org.jumpmind.db.sql.DmlStatement;

public class OracleDmlStatement extends DmlStatement {

public OracleDmlStatement(DmlType type, String catalogName, String schemaName,
String tableName, Column[] keys, Column[] columns, boolean isDateOverrideToTimestamp,
String identifierQuoteString, boolean[] nullKeyValues) {
super(type, catalogName, schemaName, tableName, keys, columns, isDateOverrideToTimestamp,
identifierQuoteString, nullKeyValues);
public OracleDmlStatement(DmlType type, String catalogName, String schemaName, String tableName,
Column[] keysColumns, Column[] columns, boolean[] nullKeyValues,
DatabaseInfo databaseInfo, boolean useQuotedIdentifiers) {
super(type, catalogName, schemaName, tableName, keysColumns, columns,
nullKeyValues, databaseInfo, useQuotedIdentifiers);
}

@Override
Expand Down
Expand Up @@ -25,15 +25,16 @@
import org.apache.commons.lang.ArrayUtils;
import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.TypeMap;
import org.jumpmind.db.platform.DatabaseInfo;
import org.jumpmind.db.sql.DmlStatement;

public class PostgreSqlDmlStatement extends DmlStatement {

public PostgreSqlDmlStatement(DmlType type, String catalogName, String schemaName,
String tableName, Column[] keys, Column[] columns, boolean isDateOverrideToTimestamp,
String identifierQuoteString, boolean[] nullKeyValues) {
super(type, catalogName, schemaName, tableName, keys, columns, isDateOverrideToTimestamp,
identifierQuoteString, nullKeyValues);
public PostgreSqlDmlStatement(DmlType type, String catalogName, String schemaName, String tableName,
Column[] keysColumns, Column[] columns, boolean[] nullKeyValues,
DatabaseInfo databaseInfo, boolean useQuotedIdentifiers) {
super(type, catalogName, schemaName, tableName, keysColumns, columns,
nullKeyValues, databaseInfo, useQuotedIdentifiers);
}

@Override
Expand Down

0 comments on commit 4522154

Please sign in to comment.