From a858aa40bd161eebb8ab9da2a3018cb81d326d58 Mon Sep 17 00:00:00 2001 From: alexeykap Date: Fri, 22 Mar 2019 10:01:49 +0400 Subject: [PATCH] issue #14 Could not make dml migration from MSSQL type UNIQUEIDENTIFIER to uuid postrges type Add to dml config "postgres_type_casting" parameter. It is array of type's names which must be casted by postgress implictly. --- README.md | 2 ++ .../java/net/twentyonesolutions/m2pg/Config.java | 6 ++++-- .../java/net/twentyonesolutions/m2pg/Schema.java | 16 +++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9861793..3e32260 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,8 @@ Values that are wrapped in `%` symbols are treated as varaibles and evaluated at +-- after_all array of SQL commands to run after data copy | +-- recomended ([""], "all") - specifying "all" will execute recommendations + | + +-- implicitConversionTypes array of source column types that should be cast implicitly with postgres (for example "UNIQUEIDENTIFIER") | +-- threads (["cores", integer]) - number of concurrent connections | diff --git a/src/main/java/net/twentyonesolutions/m2pg/Config.java b/src/main/java/net/twentyonesolutions/m2pg/Config.java index 9140b98..87c6760 100644 --- a/src/main/java/net/twentyonesolutions/m2pg/Config.java +++ b/src/main/java/net/twentyonesolutions/m2pg/Config.java @@ -42,6 +42,7 @@ public class Config { Map dml, ddl; Map schemaMapping, tableMapping, columnMapping; Map columnDefaultReplace; + Map postgresTypeCasting; String name, source, target; @@ -87,6 +88,7 @@ private void parseDml(){ ,"source_column_quote_prefix" ,"source_column_quote_suffix" ,"threads" + ,"implicit_conversion_types" }; // populate result with config value or default of empty string @@ -95,7 +97,7 @@ private void parseDml(){ } // wrap single item String in List - for (String k : new String[]{ "execute.before_all", "execute.after_all" }){ + for (String k : new String[]{ "execute.before_all", "execute.after_all", "implicit_conversion_types"}){ Object v = result.get(k); if (v instanceof String){ result.put(k, new ArrayList(){{ add((String)v); }}); @@ -104,7 +106,7 @@ private void parseDml(){ mapSrc = (Map)config.get(prefix + "jdbc_type_mapping"); result.put("jdbc_type_mapping", getCaseInsensitiveMap(mapSrc, uppercaseValue)); - + this.dml = result; } diff --git a/src/main/java/net/twentyonesolutions/m2pg/Schema.java b/src/main/java/net/twentyonesolutions/m2pg/Schema.java index 9d13845..8767ad1 100644 --- a/src/main/java/net/twentyonesolutions/m2pg/Schema.java +++ b/src/main/java/net/twentyonesolutions/m2pg/Schema.java @@ -147,8 +147,7 @@ public String copyTable(String tableName, IProgress progress) throws IOException statSrc = conSrc.createStatement(); - PreparedStatement statInsert = conTgt.prepareStatement(qInsert); - + PreparedStatement statInsert = conTgt.prepareStatement(qInsert); statSrc.setFetchSize(1000); rs = statSrc.executeQuery(qSelect); @@ -156,7 +155,8 @@ public String copyTable(String tableName, IProgress progress) throws IOException ResultSetMetaData rsMetaData = rs.getMetaData(); Map jdbcTypeMapping = (Map) config.dml.get("jdbc_type_mapping"); - + List implicitConversionTypes = (List) config.dml.getOrDefault("implicit_conversion_types", Collections.EMPTY_LIST); + int columnCount = rsMetaData.getColumnCount(); int[] columnTypes = new int[columnCount]; @@ -172,6 +172,7 @@ public String copyTable(String tableName, IProgress progress) throws IOException // tgtType = Integer.parseInt(jdbcTypeMapping.getOrDefault(String.valueOf(srcType), String.valueOf(tgtType))); String srcTypeName = JDBCType.valueOf(srcType).getName(); // WARN: rsMetaData.getColumnTypeName(i) returns the vendor's name instead of JDBC name, e.g. ntext instead of longnvarchar for MSSQL + if (jdbcTypeMapping.containsKey(srcTypeName)) { String tgtTypeName = jdbcTypeMapping.get(srcTypeName); tgtType = JDBCType.valueOf(tgtTypeName).getVendorTypeNumber(); @@ -190,8 +191,13 @@ public String copyTable(String tableName, IProgress progress) throws IOException for (int i = 1; i <= columnCount; i++) { Object value = rs.getObject(i); values[i - 1] = value; - statInsert.setObject(i, value, columnTypes[i - 1]); - // statInsert.setObject(i, value, sqlTypes[i - 1]); // throws java.sql.SQLFeatureNotSupportedException: Method org.postgresql.jdbc.PgPreparedStatement.setObject is not yet implemented. + String sourceColumnType=new String(); + sourceColumnType=table.columns.get(i-1).type.toString(); + if(implicitConversionTypes.contains(sourceColumnType)){ + statInsert.setObject(i, value,java.sql.Types.OTHER); + }else{ + statInsert.setObject(i, value, columnTypes[i - 1]); // throws java.sql.SQLFeatureNotSupportedException: Method org.postgresql.jdbc.PgPreparedStatement.setObject is not yet implemented. + } } try {