Skip to content

Commit

Permalink
0005481: mssql text for symmetric tables to varchar (#185)
Browse files Browse the repository at this point in the history
* Add support for translate sym columns from text to varchar(max)

* When nvarchar has more than 8000 bytes, use max size

* Add lob to varchar default value with comments

* Fix naming convention
  • Loading branch information
scornelissen85 committed Sep 30, 2022
1 parent b13979c commit d1c0489
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 4 deletions.
Expand Up @@ -25,6 +25,7 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;

import org.apache.commons.lang3.StringUtils;
import org.jumpmind.db.model.Column;
Expand Down Expand Up @@ -73,11 +74,20 @@ public MsSqlSymmetricDialect(IParameterService parameterService, IDatabasePlatfo
public Database readSymmetricSchemaFromXml() {
Database db = super.readSymmetricSchemaFromXml();
if (parameterService.is(ParameterConstants.MSSQL_USE_NTYPES_FOR_SYNC)) {
Table table = db.findTable(TableConstants.getTableName(getTablePrefix(),
Table symTable = db.findTable(TableConstants.getTableName(getTablePrefix(),
TableConstants.SYM_DATA));
setColumnToNtext(table.getColumnWithName("row_data"));
setColumnToNtext(table.getColumnWithName("old_data"));
setColumnToNtext(table.getColumnWithName("pk_data"));
setColumnToNtext(symTable.getColumnWithName("row_data"));
setColumnToNtext(symTable.getColumnWithName("old_data"));
setColumnToNtext(symTable.getColumnWithName("pk_data"));
}
if (parameterService.is(ParameterConstants.MSSQL_USE_VARCHAR_FOR_LOB_IN_SYNC)) {
for (Table table : db.getTables()) {
for (Column column : table.getColumns()) {
if (column.getMappedTypeCode() == Types.LONGNVARCHAR || column.getMappedTypeCode() == Types.LONGVARCHAR) {
setColumnToVarChar(column, parameterService.is(ParameterConstants.MSSQL_USE_NTYPES_FOR_SYNC));
}
}
}
}
return db;
}
Expand All @@ -86,6 +96,15 @@ protected void setColumnToNtext(Column column) {
column.setMappedType(TypeMap.LONGNVARCHAR);
}

protected void setColumnToVarChar(Column column, boolean forceNtype) {
if (column.getMappedTypeCode() == Types.LONGNVARCHAR || (forceNtype && column.getMappedTypeCode() == Types.LONGVARCHAR)) {
column.setMappedType(TypeMap.NVARCHAR);
} else if (column.getMappedTypeCode() == Types.LONGVARCHAR) {
column.setMappedType(TypeMap.VARCHAR);
}
column.setSize("100000"); // This will ensure the size is converted to "max"
}

@Override
public boolean createOrAlterTablesIfNecessary(String... tableNames) {
boolean altered = super.createOrAlterTablesIfNecessary(tableNames);
Expand Down
Expand Up @@ -360,6 +360,7 @@ private ParameterConstants() {
public final static String BSH_EXTENSION_GLOBAL_SCRIPT = "bsh.extension.global.script";
public final static String MSSQL_ROW_LEVEL_LOCKS_ONLY = "mssql.allow.only.row.level.locks.on.runtime.tables";
public final static String MSSQL_USE_NTYPES_FOR_SYNC = "mssql.use.ntypes.for.sync";
public final static String MSSQL_USE_VARCHAR_FOR_LOB_IN_SYNC = "mssql.use.varchar.for.lob.in.sync";
public final static String MSSQL_LOCK_ESCALATION_DISABLED = "mssql.lock.escalation.disabled";
public final static String MSSQL_INCLUDE_CATALOG_IN_TRIGGERS = "mssql.include.catalog.in.triggers";
public final static String MSSQL_TRIGGER_EXECUTE_AS = "mssql.trigger.execute.as";
Expand Down
Expand Up @@ -2612,6 +2612,14 @@ mssql.allow.only.row.level.locks.on.runtime.tables=true
# Type: boolean
mssql.use.ntypes.for.sync=false

# Use varchar(max) or nvarchar(max) when a column in SymmetricDS tables is set to long
# or nlong. This is for example necessary when using a _UTF8 of _SC collation.
#
# DatabaseOverridable: true
# Tags: trigger, mssql
# Type: boolean
mssql.use.varchar.for.lob.in.sync=false

# Specify the user the SymmetricDS triggers should execute as. Possible values are
# { CALLER | SELF | OWNER | 'user_name' }
# DatabaseOverridable: true
Expand Down
Expand Up @@ -92,6 +92,8 @@ public String getSqlType(Column column) {
sqlType = "VARBINARY(MAX)";
} else if (column.getMappedTypeCode() == Types.VARCHAR && column.getSizeAsInt() > 8000) {
sqlType = "VARCHAR(MAX)";
} else if (column.getMappedTypeCode() == Types.NVARCHAR && column.getSizeAsInt() > 8000) {
sqlType = "NVARCHAR(MAX)";
} else if (column.getMappedTypeCode() == Types.DECIMAL && column.getSizeAsInt() > 38) {
sqlType = String.format("DECIMAL(38,%d)", column.getScale());
}
Expand Down

0 comments on commit d1c0489

Please sign in to comment.