diff --git a/symmetric-assemble/common.gradle b/symmetric-assemble/common.gradle index 7c57b0616a..7c257773a1 100644 --- a/symmetric-assemble/common.gradle +++ b/symmetric-assemble/common.gradle @@ -180,6 +180,7 @@ subprojects { subproject -> jnaVersion = '4.1.0' jettyVersion = '9.2.18.v20160721' nuodbVersion = '2.6.1' + tiberoVersion = '6' env = System.getenv() } @@ -208,6 +209,7 @@ subprojects { subproject -> } provided ("net.sf.jt400:jt400:$jt400Version") provided "com.nuodb.jdbc:nuodb-jdbc:$nuodbVersion" + provided "jdbc.tibero:tibero:$tiberoVersion" // javax.resource needed by jaybird provided "org.apache.geronimo.specs:geronimo-j2ee-connector_1.6_spec:1.0" diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/tibero/TiberoTriggerTemplate.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/tibero/TiberoTriggerTemplate.java index 65d3cef9c5..12d9a4f181 100644 --- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/tibero/TiberoTriggerTemplate.java +++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/tibero/TiberoTriggerTemplate.java @@ -20,8 +20,8 @@ public TiberoTriggerTemplate(ISymmetricDialect symmetricDialect) { datetimeColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', concat(concat('\"',to_char($(tableAlias).\"$(columnName)\", 'YYYY-MM-DD HH24:MI:SS.FF9')),'\"'))" ; dateTimeWithTimeZoneColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', concat(concat('\"',to_char($(tableAlias).\"$(columnName)\", 'YYYY-MM-DD HH24:MI:SS.FF9 TZH:TZM')),'\"'))" ; dateTimeWithLocalTimeZoneColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', concat(concat('\"',to_char(cast($(tableAlias).\"$(columnName)\" as timestamp), 'YYYY-MM-DD HH24:MI:SS.FF9')),'\"'))" ; - timeColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', concat(concat('\"',to_char($(tableAlias).\"$(columnName)\", 'YYYY-MM-DD HH24:MI:SS','NLS_CALENDAR=''GREGORIAN''')),'\"'))" ; - dateColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', concat(concat('\"',to_char($(tableAlias).\"$(columnName)\", 'YYYY-MM-DD HH24:MI:SS','NLS_CALENDAR=''GREGORIAN''')),'\"'))" ; + timeColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', concat(concat('\"',to_char($(tableAlias).\"$(columnName)\", 'YYYY-MM-DD HH24:MI:SS')),'\"'))" ; + dateColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', concat(concat('\"',to_char($(tableAlias).\"$(columnName)\", 'YYYY-MM-DD HH24:MI:SS')),'\"'))" ; clobColumnTemplate = "decode(dbms_lob.getlength(to_clob($(tableAlias).\"$(columnName)\")), null, to_clob(''), '\"'||replace(replace($(tableAlias).\"$(columnName)\",'\\','\\\\'),'\"','\\\"')||'\"')" ; blobColumnTemplate = "decode(dbms_lob.getlength($(tableAlias).\"$(columnName)\"), null, to_clob(''), '\"'||$(prefixName)_blob2clob($(tableAlias).\"$(columnName)\")||'\"')" ; booleanColumnTemplate = "decode($(tableAlias).\"$(columnName)\", null, '', '\"'||cast($(tableAlias).\"$(columnName)\" as number("+symmetricDialect.getTemplateNumberPrecisionSpec()+"))||'\"')" ; diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java index 3cb40c52d5..63d383616f 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java @@ -1158,7 +1158,14 @@ public void batchInError(DataContext context, Throwable ex) { this.currentBatch.setSqlState(ErrorConstants.CONFLICT_STATE); this.currentBatch.setSqlCode(ErrorConstants.CONFLICT_CODE); } else if (se != null) { - this.currentBatch.setSqlState(se.getSQLState()); + String sqlState = se.getSQLState(); + if (sqlState != null && sqlState.length() > 10) { + sqlState = sqlState.replace("JDBC-", ""); + if (sqlState.length() > 10) { + sqlState = sqlState.substring(0, 10); + } + } + this.currentBatch.setSqlState(sqlState); this.currentBatch.setSqlCode(se.getErrorCode()); this.currentBatch.setSqlMessage(se.getMessage()); if (sqlTemplate.isForeignKeyViolation(se)) { diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/transport/AbstractTransportManager.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/transport/AbstractTransportManager.java index c3c4d2f7bd..c5a838a604 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/transport/AbstractTransportManager.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/transport/AbstractTransportManager.java @@ -106,8 +106,15 @@ protected String getAcknowledgementData(boolean requires13Format, String nodeId, append(builder, WebConstants.ACK_IGNORE_COUNT + batchId, batch.getIgnoreCount()); } - if (batch.getStatus() == Status.ER) { - append(builder, WebConstants.ACK_SQL_STATE + batchId, batch.getSqlState()); + if (batch.getStatus() == Status.ER) { + String sqlState = batch.getSqlState(); + if (sqlState != null && sqlState.length() > 10) { + sqlState = sqlState.replace("JDBC-", ""); + if (sqlState.length() > 10) { + sqlState = sqlState.substring(0, 10); + } + } + append(builder, WebConstants.ACK_SQL_STATE + batchId, sqlState); append(builder, WebConstants.ACK_SQL_CODE + batchId, batch.getSqlCode()); append(builder, WebConstants.ACK_SQL_MESSAGE + batchId, batch.getSqlMessage()); } diff --git a/symmetric-db/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlBuilder.java b/symmetric-db/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlBuilder.java index 483ea5c703..0874177502 100644 --- a/symmetric-db/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlBuilder.java +++ b/symmetric-db/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlBuilder.java @@ -44,9 +44,9 @@ public TiberoDdlBuilder() { databaseInfo.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); databaseInfo.addNativeTypeMapping(Types.BIGINT, "NUMBER(38)"); databaseInfo.addNativeTypeMapping(Types.BINARY, "RAW", Types.VARBINARY); - databaseInfo.addNativeTypeMapping(Types.BIT, "NUMBER(1)", Types.DECIMAL); + databaseInfo.addNativeTypeMapping(Types.BIT, "NUMBER(1)", Types.NUMERIC); databaseInfo.addNativeTypeMapping(Types.DATE, "DATE", Types.TIMESTAMP); - databaseInfo.addNativeTypeMapping(Types.DECIMAL, "NUMBER"); + databaseInfo.addNativeTypeMapping(Types.NUMERIC, "NUMBER"); databaseInfo.addNativeTypeMapping(Types.DISTINCT, "BLOB", Types.BLOB); databaseInfo.addNativeTypeMapping(Types.DOUBLE, "DOUBLE PRECISION"); databaseInfo.addNativeTypeMapping(Types.FLOAT, "FLOAT", Types.DOUBLE); @@ -54,15 +54,15 @@ public TiberoDdlBuilder() { databaseInfo.addNativeTypeMapping(Types.LONGVARBINARY, "BLOB", Types.BLOB); databaseInfo.addNativeTypeMapping(Types.LONGVARCHAR, "CLOB", Types.CLOB); databaseInfo.addNativeTypeMapping(Types.NULL, "BLOB", Types.BLOB); - databaseInfo.addNativeTypeMapping(Types.NUMERIC, "NUMBER", Types.DECIMAL); - databaseInfo.addNativeTypeMapping(Types.INTEGER, "NUMBER(22)", Types.DECIMAL); + databaseInfo.addNativeTypeMapping(Types.DECIMAL, "NUMBER", Types.NUMERIC); + databaseInfo.addNativeTypeMapping(Types.INTEGER, "NUMBER(22)", Types.NUMERIC); databaseInfo.addNativeTypeMapping(Types.OTHER, "BLOB", Types.BLOB); databaseInfo.addNativeTypeMapping(Types.REF, "BLOB", Types.BLOB); databaseInfo.addNativeTypeMapping(Types.SMALLINT, "NUMBER(5)"); databaseInfo.addNativeTypeMapping(Types.STRUCT, "BLOB", Types.BLOB); databaseInfo.addNativeTypeMapping(Types.TIME, "DATE", Types.DATE); databaseInfo.addNativeTypeMapping(Types.TIMESTAMP, "TIMESTAMP"); - databaseInfo.addNativeTypeMapping(Types.TINYINT, "NUMBER(3)", Types.DECIMAL); + databaseInfo.addNativeTypeMapping(Types.TINYINT, "NUMBER(3)", Types.NUMERIC); databaseInfo.addNativeTypeMapping(Types.VARBINARY, "RAW"); databaseInfo.addNativeTypeMapping(Types.VARCHAR, "VARCHAR2"); databaseInfo.addNativeTypeMapping("BOOLEAN", "NUMBER(1)", "BIT"); diff --git a/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/DbExport.java b/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/DbExport.java index 69eda300ae..709350b583 100644 --- a/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/DbExport.java +++ b/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/DbExport.java @@ -65,7 +65,7 @@ public enum Format { }; public enum Compatible { - DB2, DERBY, FIREBIRD, FIREBIRD_DIALECT1, GREENPLUM, H2, HSQLDB, HSQLDB2, INFORMIX, INTERBASE, MSSQL, MSSQL2000, MSSQL2005, MSSQL2008, MYSQL, ORACLE, POSTGRES, SYBASE, SQLITE, MARIADB, ASE, SQLANYWHERE, REDSHIFT, VOLTDB, NUODB, GENERIC + DB2, DERBY, FIREBIRD, FIREBIRD_DIALECT1, GREENPLUM, H2, HSQLDB, HSQLDB2, INFORMIX, INTERBASE, MSSQL, MSSQL2000, MSSQL2005, MSSQL2008, MYSQL, ORACLE, POSTGRES, SYBASE, SQLITE, MARIADB, ASE, SQLANYWHERE, REDSHIFT, VOLTDB, NUODB, TIBERO, GENERIC }; private Format format = Format.SQL; diff --git a/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java b/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java index 50ee95575e..3a747fb795 100644 --- a/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java +++ b/symmetric-io/src/test/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterTest.java @@ -42,6 +42,7 @@ import org.jumpmind.db.platform.oracle.OracleDatabasePlatform; import org.jumpmind.db.platform.postgresql.PostgreSqlDatabasePlatform; import org.jumpmind.db.platform.sqlanywhere.SqlAnywhereDatabasePlatform; +import org.jumpmind.db.platform.tibero.TiberoDatabasePlatform; import org.jumpmind.symmetric.io.AbstractWriterTest; import org.jumpmind.symmetric.io.data.CsvData; import org.jumpmind.symmetric.io.data.DataEventType; @@ -623,6 +624,7 @@ private String[] massageExpectectedResultsForDialect(String[] values) { if (values[5] != null && (!(platform instanceof OracleDatabasePlatform + || platform instanceof TiberoDatabasePlatform || platform instanceof MsSql2000DatabasePlatform || platform instanceof MsSql2005DatabasePlatform || platform instanceof MsSql2008DatabasePlatform @@ -633,7 +635,8 @@ private String[] massageExpectectedResultsForDialect(String[] values) { if (values[10] != null) { values[10] = values[10].replace(',', '.'); } - if (values[10] != null && !(platform instanceof OracleDatabasePlatform)) { + if (values[10] != null && !(platform instanceof OracleDatabasePlatform) + && !(platform instanceof TiberoDatabasePlatform)) { int scale = 17; if (platform instanceof MySqlDatabasePlatform) { scale = 16; diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlReader.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlReader.java index 8aab85c603..55709c7528 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlReader.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoDdlReader.java @@ -24,6 +24,7 @@ import org.jumpmind.db.model.Column; import org.jumpmind.db.model.ColumnTypes; import org.jumpmind.db.model.IIndex; +import org.jumpmind.db.model.PlatformColumn; import org.jumpmind.db.model.Table; import org.jumpmind.db.model.Trigger; import org.jumpmind.db.model.Trigger.TriggerType; @@ -32,7 +33,6 @@ import org.jumpmind.db.platform.DatabaseMetaDataWrapper; import org.jumpmind.db.platform.IDatabasePlatform; import org.jumpmind.db.platform.IDdlBuilder; -import org.jumpmind.db.platform.tibero.TiberoDdlBuilder; import org.jumpmind.db.sql.ISqlRowMapper; import org.jumpmind.db.sql.JdbcSqlTemplate; import org.jumpmind.db.sql.Row; @@ -141,24 +141,20 @@ protected Integer mapUnknownJdbcTypeForColumn(Map values) { protected Column readColumn(DatabaseMetaDataWrapper metaData, Map values) throws SQLException { Column column = super.readColumn(metaData, values); - if (column.getMappedTypeCode() == Types.DECIMAL) { - // We're back-mapping the NUMBER columns returned by Tibero - // Note that the JDBC driver returns DECIMAL for these NUMBER - // columns - if (column.getScale() <= -127 || column.getScale() >= 127) { - if (column.getSizeAsInt() == 0) { - /* - * Latest Tibero jdbc drivers for 11g return (0,-127) for - * types defined as integer resulting in bad mappings. - * NUMBER without scale or precision looks the same as - * INTEGER in the jdbc driver. We must check the Tibero - * meta data to see if type is an INTEGER. - */ - if (isColumnInteger((String)values.get("TABLE_NAME"), - (String)values.get("COLUMN_NAME"))) { - column.setMappedTypeCode(Types.BIGINT); - } - } else if (column.getSizeAsInt() <= 63) { + if (column.getMappedTypeCode() == Types.NUMERIC) { + PlatformColumn platformColumn = column.getPlatformColumns().get(platform.getName()); + if (platformColumn.getDecimalDigits() == 0 && column.getSizeAsInt() == 15) { + column.setSize("15"); + } + if (column.getScale() == 0) { + + if (column.getSizeAsInt() == 3) { + column.setMappedTypeCode(Types.TINYINT); + } else if (column.getSizeAsInt() <= 22) { + column.setMappedTypeCode(Types.INTEGER); + } else if (column.getSizeAsInt() == 38) { + column.setMappedTypeCode(Types.BIGINT); + } else if (column.getSizeAsInt() <= 63) { column.setMappedTypeCode(Types.REAL); } else { column.setMappedTypeCode(Types.DOUBLE); diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoJdbcSqlTemplate.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoJdbcSqlTemplate.java index 1e8b1897d8..6a7f5636ec 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoJdbcSqlTemplate.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoJdbcSqlTemplate.java @@ -15,7 +15,7 @@ public TiberoJdbcSqlTemplate(DataSource dataSource, SqlTemplateSettings settings SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo) { super(dataSource, settings, lobHandler, databaseInfo); primaryKeyViolationCodes = new int[] {1}; - foreignKeyViolationCodes = new int[] {2291}; + foreignKeyViolationCodes = new int[] {-10008}; } @Override diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoLobHandler.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoLobHandler.java index a46fcfeeda..111a171eba 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoLobHandler.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/tibero/TiberoLobHandler.java @@ -3,7 +3,6 @@ import java.sql.ResultSet; import java.sql.SQLException; -import org.jumpmind.db.sql.JdbcUtils; import org.jumpmind.db.sql.SymmetricLobHandler; import org.springframework.jdbc.support.lob.DefaultLobHandler; @@ -13,9 +12,7 @@ public class TiberoLobHandler extends SymmetricLobHandler { DefaultLobHandler longHandler = new DefaultLobHandler(); public TiberoLobHandler() { - super(new org.springframework.jdbc.support.lob.OracleLobHandler()); - ((org.springframework.jdbc.support.lob.OracleLobHandler) lobHandler) - .setNativeJdbcExtractor(JdbcUtils.getNativeJdbcExtractory()); + super(); } @Override diff --git a/symmetric-jdbc/src/test/resources/db-test.properties b/symmetric-jdbc/src/test/resources/db-test.properties index e05a0478bb..a018b5b539 100644 --- a/symmetric-jdbc/src/test/resources/db-test.properties +++ b/symmetric-jdbc/src/test/resources/db-test.properties @@ -173,3 +173,12 @@ azure.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver azure.db.user=symmetricds azure.db.password=P@ssword azure.db.url=jdbc:sqlserver://p98nzw4n8u.database.windows.net:1433;database=TEST;user=symmetricds@p98nzw4n8u;password={your_password_here};encrypt=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30; + +tibero.db.driver=com.tmax.tibero.jdbc.TbDriver +tibero.server.db.user=SymmetricRoot +tibero.server.db.password=admin +tibero.root.db.user=SymmetricRoot +tibero.root.db.password=admin +tibero.client.db.user=SymmetricClient +tibero.client.db.password=admin +tibero.db.url=jdbc:tibero:thin:@192.168.42.110:8629:tibero6 \ No newline at end of file