Skip to content

Commit

Permalink
0002849: Create Table maps a column originally created as an
Browse files Browse the repository at this point in the history
ENUM('y','n') to a Enum(2)
  • Loading branch information
philipmarzullo committed Jan 14, 2019
1 parent 7348dc2 commit e289a8c
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 35 deletions.
26 changes: 13 additions & 13 deletions symmetric-db/src/main/java/org/jumpmind/db/model/Column.java
Expand Up @@ -109,7 +109,7 @@ public class Column implements Cloneable, Serializable {

private Map<String, PlatformColumn> platformColumns;

private String[] enumValues;
// private String[] enumValues;

public Column() {
}
Expand Down Expand Up @@ -739,17 +739,17 @@ public boolean isTimestampWithTimezone() {
public boolean containsJdbcTypes() {
return jdbcTypeCode != Integer.MIN_VALUE && jdbcTypeName != null;
}

public void setEnumValues(String[] enumValues) {
this.enumValues = enumValues;
}

public String[] getEnumValues() {
return enumValues;
}

public boolean isEnum() {
return enumValues != null && enumValues.length > 0;
}
//
// public void setEnumValues(String[] enumValues) {
// this.enumValues = enumValues;
// }
//
// public String[] getEnumValues() {
// return enumValues;
// }
//
// public boolean isEnum() {
// return enumValues != null && enumValues.length > 0;
// }

}
Expand Up @@ -36,6 +36,8 @@ public class PlatformColumn implements Serializable, Cloneable {

private String defaultValue;

private String[] enumValues;

public PlatformColumn(String name, String type, int size, int decimalDigits, String defaultValue) {
this.name = name;
this.type = type;
Expand Down Expand Up @@ -86,6 +88,18 @@ public void setDecimalDigits(int decimalDigits) {
public int getDecimalDigits() {
return decimalDigits;
}

public void setEnumValues(String[] enumValues) {
this.enumValues = enumValues;
}

public String[] getEnumValues() {
return enumValues;
}

public boolean isEnum() {
return enumValues != null && enumValues.length > 0;
}

@Override
public Object clone() throws CloneNotSupportedException {
Expand Down
Expand Up @@ -38,6 +38,7 @@
import org.jumpmind.db.model.Database;
import org.jumpmind.db.model.ForeignKey;
import org.jumpmind.db.model.IIndex;
import org.jumpmind.db.model.PlatformColumn;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.platform.AbstractDdlBuilder;
import org.jumpmind.db.platform.DatabaseNamesConstants;
Expand Down Expand Up @@ -335,22 +336,26 @@ protected String getSqlType(Column column) {
sqlType = "DATETIME(" + column.getScale() + ")";
}
if("ENUM".equalsIgnoreCase(column.getJdbcTypeName())) {
if(column.getEnumValues() != null && column.getEnumValues().length > 0) {
// Redo the enum, specifying the values returned from the database in the enumValues field
// instead of the size of the column
StringBuilder tmpSqlType = new StringBuilder();
tmpSqlType.append(column.getJdbcTypeName());
tmpSqlType.append("(");
boolean appendComma = false;
for(String s : column.getEnumValues()) {
if(appendComma) {
tmpSqlType.append(",");
}
tmpSqlType.append("'").append(s).append("'");
appendComma = true;
PlatformColumn pc = column.getPlatformColumns().get(DatabaseNamesConstants.MYSQL);
if(pc != null) {
String[] enumValues = pc.getEnumValues();
if(enumValues != null && enumValues.length > 0) {
// Redo the enum, specifying the values returned from the database in the enumValues field
// instead of the size of the column
StringBuilder tmpSqlType = new StringBuilder();
tmpSqlType.append(column.getJdbcTypeName());
tmpSqlType.append("(");
boolean appendComma = false;
for(String s : enumValues) {
if(appendComma) {
tmpSqlType.append(",");
}
tmpSqlType.append("'").append(s).append("'");
appendComma = true;
}
tmpSqlType.append(")");
sqlType = tmpSqlType.toString();
}
tmpSqlType.append(")");
sqlType = tmpSqlType.toString();
}
}
return sqlType;
Expand All @@ -363,7 +368,8 @@ public static void main(String[] args) {
s[1]="b";
s[2]="c";
Column col = new Column("enumcol", true, 12, 3, 0);
col.setEnumValues(s);
// col.setEnumValues(s);
col.getPlatformColumns().get("mysql").setEnumValues(s);
col.setJdbcTypeName("ENUM");
Table currentTable = new Table("enumtest", col);
String ddl = ddlBuilder.createTable(currentTable);
Expand Down
Expand Up @@ -34,6 +34,7 @@
import org.jumpmind.db.model.Database;
import org.jumpmind.db.model.ForeignKey;
import org.jumpmind.db.model.IIndex;
import org.jumpmind.db.model.PlatformColumn;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.platform.AbstractDdlBuilder;
import org.jumpmind.db.platform.DatabaseNamesConstants;
Expand Down Expand Up @@ -294,5 +295,35 @@ protected void processColumnChange(Table sourceTable, Table targetTable, Column

protected void writeColumnNullableStmt(StringBuilder ddl) {
}

@Override
protected String getSqlType(Column column) {
String sqlType = super.getSqlType(column);

if("ENUM".equalsIgnoreCase(column.getJdbcTypeName())) {
PlatformColumn pc = column.getPlatformColumns().get(DatabaseNamesConstants.NUODB);
if(pc != null) {
String[] enumValues = pc.getEnumValues();
if(enumValues != null && enumValues.length > 0) {
// Redo the enum, specifying the values returned from the database in the enumValues field
// instead of the size of the column
StringBuilder tmpSqlType = new StringBuilder();
tmpSqlType.append(column.getJdbcTypeName());
tmpSqlType.append("(");
boolean appendComma = false;
for(String s : enumValues) {
if(appendComma) {
tmpSqlType.append(",");
}
tmpSqlType.append("'").append(s).append("'");
appendComma = true;
}
tmpSqlType.append(")");
sqlType = tmpSqlType.toString();
}
}
}
return sqlType;
}

}
Expand Up @@ -763,8 +763,8 @@ private void clearDependentColumnValues(List<Table> tables) {
private Object generateRandomValueForColumn(Column column) {
Object objectValue = null;
int type = column.getMappedTypeCode();
if (column.isEnum()) {
objectValue = column.getEnumValues()[new Random().nextInt(column.getEnumValues().length)];
if (column.getPlatformColumns().get(platform.getName()) != null && column.getPlatformColumns().get(platform.getName()).isEnum()) {
objectValue = column.getPlatformColumns().get(platform.getName()).getEnumValues()[new Random().nextInt(column.getPlatformColumns().get(platform.getName()).getEnumValues().length)];
} else if (column.isTimestampWithTimezone()) {
objectValue = String.format("%s %s",
FormatUtils.TIMESTAMP_FORMATTER.format(randomDate()),
Expand Down
Expand Up @@ -42,6 +42,8 @@
import org.jumpmind.db.platform.AbstractJdbcDdlReader;
import org.jumpmind.db.platform.DatabaseMetaDataWrapper;
import org.jumpmind.db.platform.IDatabasePlatform;
import org.jumpmind.db.platform.nuodb.NuoDbDdlBuilder;
import org.jumpmind.db.platform.oracle.OracleDdlBuilder;
import org.jumpmind.db.sql.ISqlRowMapper;
import org.jumpmind.db.sql.ISqlTemplate;
import org.jumpmind.db.sql.JdbcSqlTemplate;
Expand Down Expand Up @@ -205,7 +207,8 @@ protected Column readColumn(DatabaseMetaDataWrapper metaData, Map<String, Object
parsedEnums[i] = parsedEnum;
}

column.setEnumValues(parsedEnums);
// column.setEnumValues(parsedEnums);
column.getPlatformColumns().get(platform.getName()).setEnumValues(parsedEnums);
}
}
return column;
Expand Down Expand Up @@ -350,6 +353,9 @@ public static void main(String[] args) throws SQLException {
MySqlDdlBuilder ddlBuilder = new MySqlDdlBuilder();
String ddl = ddlBuilder.createTable(table);
System.out.println(ddl);
OracleDdlBuilder oDdlBuilder = new OracleDdlBuilder();
System.out.println(oDdlBuilder.createTable(table));
System.out.println(new NuoDbDdlBuilder().createTable(table));
}

}
Expand Up @@ -19,6 +19,7 @@
package org.jumpmind.db.platform.nuodb;

import java.sql.Connection;
import java.sql.JDBCType;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
Expand All @@ -31,19 +32,28 @@
import java.util.Map;

import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.Database;
import org.jumpmind.db.model.ForeignKey;
import org.jumpmind.db.model.IIndex;
import org.jumpmind.db.model.PlatformColumn;
import org.jumpmind.db.model.Reference;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.model.Trigger;
import org.jumpmind.db.model.Trigger.TriggerType;
import org.jumpmind.db.platform.AbstractJdbcDdlReader;
import org.jumpmind.db.platform.DatabaseMetaDataWrapper;
import org.jumpmind.db.platform.DatabaseNamesConstants;
import org.jumpmind.db.platform.IDatabasePlatform;
import org.jumpmind.db.platform.mysql.MySqlDdlBuilder;
import org.jumpmind.db.platform.oracle.OracleDdlBuilder;
import org.jumpmind.db.sql.ISqlRowMapper;
import org.jumpmind.db.sql.ISqlTemplate;
import org.jumpmind.db.sql.JdbcSqlTemplate;
import org.jumpmind.db.sql.Row;
import org.jumpmind.db.sql.SqlTemplateSettings;
import org.jumpmind.db.util.BasicDataSourceFactory;
import org.jumpmind.properties.TypedProperties;
import org.jumpmind.security.SecurityServiceFactory;

/*
* Reads a database model from a MySql database.
Expand Down Expand Up @@ -131,12 +141,14 @@ protected Column readColumn(DatabaseMetaDataWrapper metaData, Map<String, Object
}

if (column.getJdbcTypeName().equalsIgnoreCase("enum")) {
column.setMappedTypeCode(Types.VARCHAR);
column.setMappedType(JDBCType.VARCHAR.name());
ISqlTemplate template = platform.getSqlTemplate();
String unParsedEnums = template.queryForString("SELECT SUBSTRING(ENUMERATION, 2, LENGTH(ENUMERATION)-2) FROM SYSTEM.FIELDS"
+ " WHERE SCHEMA=? AND TABLENAME=? AND FIELD=?", metaData.getCatalog(), (String) values.get("TABLENAME"), column.getName());
+ " WHERE SCHEMA=? AND TABLENAME=? AND FIELD=?", (String) values.get("SCHEMA"), (String) values.get("TABLENAME"), column.getName());
if (unParsedEnums != null) {
String[] parsedEnums = unParsedEnums.split("^");
column.setEnumValues(parsedEnums);
String[] parsedEnums = unParsedEnums.split("\\^");
column.getPlatformColumns().get(platform.getName()).setEnumValues(parsedEnums);
}
}
return column;
Expand Down Expand Up @@ -248,4 +260,56 @@ protected Integer mapUnknownJdbcTypeForColumn(Map<String, Object> values) {
}
}

public static void main2(String[] args) throws SQLException {
// nuodb.db.driver=com.nuodb.jdbc.Driver
// nuodb.db.user=root
// nuodb.db.password=admin
// nuodb.root.db.url=jdbc:com.nuodb://dbdev2.loc/SymmetricRoot?schema=SymmetricRoot
// nuodb.server.db.url=jdbc:com.nuodb://dbdev2.loc/SymmetricRoot?schema=SymmetricRoot
// nuodb.client.db.url=jdbc:com.nuodb://dbdev2.loc/SymmetricClient?schema=SymmetricClient

TypedProperties properties = new TypedProperties();
properties.put("db.driver", "com.nuodb.jdbc.Driver");
properties.put("db.user", "root");
properties.put("db.password", "admin");
properties.put("db.url", "jdbc:com.nuodb://dbdev2.loc/SymmetricRoot?schema=SymmetricRoot");
Connection connection = null;
NuoDbDdlReader reader = new NuoDbDdlReader(
new NuoDbDatabasePlatform(BasicDataSourceFactory.create(properties, SecurityServiceFactory.create()),
new SqlTemplateSettings()));
Database database = reader.getDatabase(connection);
Table[] tables = database.getTables();
Table table = null;
NuoDbDdlBuilder ddlBuilder = new NuoDbDdlBuilder();
for(Table t : tables) {
if("enumcols".equalsIgnoreCase(t.getName())) {
table = t;
}
}
String ddl = ddlBuilder.createTable(table);
System.out.println(ddl);
System.out.println(new OracleDdlBuilder().createTable(table));
System.out.println(new MySqlDdlBuilder().createTable(table));
}

public static void main(String[] args) {
Table table = new Table("enumcols");
table.addColumn(new Column("enumcol", false));
Column column = table.getColumnWithName("enumcol");
column.setTypeCode(Types.VARCHAR);
column.setJdbcTypeCode(Types.SMALLINT);
column.setSizeAndScale(2, 0);
column.setRequired(true);
column.setJdbcTypeName("enum");
PlatformColumn fc = new PlatformColumn();
fc.setType("enum");
fc.setSize(2);
fc.setName(DatabaseNamesConstants.NUODB);
fc.setEnumValues(new String[] {"a","b","c","d"});
column.addPlatformColumn(fc);

System.out.println(new NuoDbDdlBuilder().createTable(table));
System.out.println(new OracleDdlBuilder().createTable(table));
System.out.println(new MySqlDdlBuilder().createTable(table));
}
}
Expand Up @@ -36,13 +36,15 @@
import org.jumpmind.db.model.Column;
import org.jumpmind.db.model.ColumnTypes;
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.platform.IDatabasePlatform;
import org.jumpmind.db.platform.IDdlBuilder;
import org.jumpmind.db.platform.PermissionResult;
import org.jumpmind.db.platform.PermissionResult.Status;
import org.jumpmind.db.platform.PermissionType;
import org.jumpmind.db.platform.oracle.OracleDdlBuilder;
import org.jumpmind.db.sql.ISqlTemplate;
import org.jumpmind.db.sql.SqlScript;
import org.junit.Before;
Expand Down Expand Up @@ -311,4 +313,49 @@ public void getPermissionsTest() {
assertTrue(!result.getStatus().equals(Status.FAIL));
}
}

@Test
public void testEnumType() {
boolean enumSupported = (
platform.getName().equals(DatabaseNamesConstants.MYSQL) ||
platform.getName().equals(DatabaseNamesConstants.NUODB)
);

if(enumSupported) {
Table table = new Table("table1");
table.addColumn(new Column("col1", false));
Column column = table.getColumnWithName("col1");
column.setTypeCode(Types.VARCHAR);
column.setJdbcTypeCode(Types.SMALLINT);
column.setSizeAndScale(2, 0);
column.setRequired(true);
column.setJdbcTypeName("enum");
PlatformColumn fc = new PlatformColumn();
fc.setType("enum");
fc.setSize(2);
fc.setName(platform.getName());
fc.setEnumValues(new String[] {"a","b","c","d"});
column.addPlatformColumn(fc);

Database database = new Database();
database.addTable(table);
platform.createDatabase(database, true, false);

Database readDatabase = platform.getDdlReader().readTables(null,null,null);
Table[] readTables = readDatabase.getTables();
for(Table t : readTables) {
if(t.getName().equalsIgnoreCase("table1")) {
for(Column c : t.getColumns()) {
assertTrue(c.getJdbcTypeName().equalsIgnoreCase("enum"));
PlatformColumn readFc = c.getPlatformColumns().get(platform.getName());
assertNotNull("Platform column not created for enum column type in platform " + platform.getName(), readFc);
assertTrue("Platform column not created as an enum in platform " + platform.getName(), readFc.getType().equalsIgnoreCase("enum"));
}
// Pick a database platform that does not implement enum, and check definition of column (should be varchar)
String ddl = new OracleDdlBuilder().createTable(table);
assertTrue("Non-implementing enum platform not defined as type varchar", ddl.contains("varchar") || ddl.contains("VARCHAR"));
}
}
}
}
}

0 comments on commit e289a8c

Please sign in to comment.