diff --git a/src/main/java/com/avaje/ebean/config/TableName.java b/src/main/java/com/avaje/ebean/config/TableName.java index 43a9e3df7..7085e4f8d 100644 --- a/src/main/java/com/avaje/ebean/config/TableName.java +++ b/src/main/java/com/avaje/ebean/config/TableName.java @@ -57,6 +57,13 @@ public final class TableName { this.name = split[len - 1]; } + /** + * Parse a qualifiedTableName that might include a catalog and schema and just return the table name. + */ + public static String parse(String qualifiedTableName) { + return new TableName(qualifiedTableName).getName(); + } + public String toString() { return getQualifiedName(); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableColumnVisitor.java b/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableColumnVisitor.java index 30e7b23b9..45062830e 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableColumnVisitor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableColumnVisitor.java @@ -2,6 +2,10 @@ package com.avaje.ebeaninternal.server.ddl; import java.sql.Types; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.avaje.ebean.config.TableName; import com.avaje.ebean.config.dbplatform.DbDdlSyntax; import com.avaje.ebean.config.dbplatform.IdType; import com.avaje.ebeaninternal.server.deploy.BeanProperty; @@ -12,8 +16,6 @@ import com.avaje.ebeaninternal.server.deploy.TableJoin; import com.avaje.ebeaninternal.server.deploy.TableJoinColumn; import com.avaje.ebeaninternal.server.deploy.id.ImportedId; import com.avaje.ebeaninternal.server.lib.util.StringHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Used as part of CreateTableVisitor to generated the create table DDL script. @@ -71,7 +73,7 @@ public class CreateTableColumnVisitor extends BaseTablePropertyVisitor { private StringBuilder createUniqueConstraintBuffer(String table, String column) { - String uqConstraintName = "uq_" + table + "_" + column; + String uqConstraintName = "uq_"+TableName.parse(table)+"_"+column; if (uqConstraintName.length() > ddl.getMaxConstraintNameLength()) { uqConstraintName = uqConstraintName.substring(0, ddl.getMaxConstraintNameLength()); diff --git a/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableVisitor.java b/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableVisitor.java index 1f331dbbd..06d97cc9c 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableVisitor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/ddl/CreateTableVisitor.java @@ -4,6 +4,10 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.avaje.ebean.config.TableName; import com.avaje.ebean.config.dbplatform.DbDdlSyntax; import com.avaje.ebean.config.dbplatform.DbType; import com.avaje.ebeaninternal.server.deploy.BeanDescriptor; @@ -13,8 +17,6 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyCompound; import com.avaje.ebeaninternal.server.deploy.CompoundUniqueContraint; import com.avaje.ebeaninternal.server.deploy.InheritInfo; import com.avaje.ebeaninternal.server.deploy.parse.SqlReservedWords; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Used to generated the create table DDL script. @@ -23,23 +25,22 @@ public class CreateTableVisitor extends AbstractBeanVisitor { private static final Logger logger = LoggerFactory.getLogger(CreateTableVisitor.class); - final DdlGenContext ctx; + private final DdlGenContext ctx; - final PropertyVisitor pv; + private final PropertyVisitor pv; - final DbDdlSyntax ddl; + private final DbDdlSyntax ddl; - final int columnNameWidth; + private final int columnNameWidth; // avoid writing columns twice, e.g. when used in associations with insertable=false and updateable=false private final Set wroteColumns = new HashSet(); - private ArrayList checkConstraints = new ArrayList(); + private ArrayList checkConstraints = new ArrayList(); - private ArrayList uniqueConstraints = new ArrayList(); + private ArrayList uniqueConstraints = new ArrayList(); - private String table; - private String schema; + private TableName tableName; public Set getWroteColumns() { return wroteColumns; @@ -53,235 +54,210 @@ public class CreateTableVisitor extends AbstractBeanVisitor { this.pv = new CreateTableColumnVisitor(this, ctx); } - public boolean isDbColumnWritten(String dbColumn) { - // Columns are not case sensitive - user lower case - // as e.g. @JoinColumn(s) may use a different case - return wroteColumns.contains(dbColumn.toLowerCase()); - } + public boolean isDbColumnWritten(String dbColumn) { + // Columns are not case sensitive - user lower case + // as e.g. @JoinColumn(s) may use a different case + return wroteColumns.contains(dbColumn.toLowerCase()); + } - public void addDbColumnWritten(String dbColumn){ - // Column names are case insensitive - wroteColumns.add(dbColumn.toLowerCase()); - } + public void addDbColumnWritten(String dbColumn) { + // Column names are case insensitive + wroteColumns.add(dbColumn.toLowerCase()); + } - /** - * Write the table name including a check for SQL reserved words. - */ - protected void writeTableName(BeanDescriptor descriptor) { - - String tableName = descriptor.getBaseTable(); - int dotPos = tableName.lastIndexOf('.'); - if (dotPos > -1){ - schema = tableName.substring(0, dotPos); - table = tableName.substring(dotPos+1); - } else { - table = tableName; - } - - if (SqlReservedWords.isKeyword(table)) { - logger.warn("Table name ["+table+"] is a suspected SQL reserved word for bean "+descriptor.getFullName()); - } - - ctx.write(tableName); - } - - protected String getTable() { - return table; - } - - protected String getSchema() { - return schema; - } - - /** - * Write the column name including a check for the SQL reserved words. - * @param p - */ - protected void writeColumnName(String columnName, BeanProperty p) { - - addDbColumnWritten(columnName); - - if (SqlReservedWords.isKeyword(columnName)) { - String propName = p == null ? "(Unknown)" : p.getFullBeanName(); - logger.warn("Column name ["+columnName+"] is a suspected SQL reserved word for property "+propName); - } - - ctx.write(" ").write(columnName, columnNameWidth).write(" "); - } - - /** - * Build a check constraint for the property if required. - *

- * Typically check constraint based on Enum mapping values. - *

- */ - protected void addCheckConstraint(BeanProperty p, String prefix, String constraintExpression) { - - if (p != null && constraintExpression != null){ - - // build constraint clause - String s = "constraint "+getConstraintName(prefix, p)+" "+constraintExpression; - - // add to list as we render all check constraints just prior to primary key - checkConstraints.add(s); - } - } - - protected String getConstraintName(String prefix, BeanProperty p) { - return prefix + table + "_" + p.getDbColumn(); - } - - protected void addUniqueConstraint(String constraintExpression) { - uniqueConstraints.add(constraintExpression); - } + /** + * Write the table name including a check for SQL reserved words. + */ + protected void writeTableName(BeanDescriptor descriptor) { - protected void addCheckConstraint(String constraintExpression) { - checkConstraints.add(constraintExpression); - } - - protected void addCheckConstraint(BeanProperty p) { - addCheckConstraint(p,"ck_", p.getDbConstraintExpression()); - } - - public boolean visitBean(BeanDescriptor descriptor) { - - wroteColumns.clear(); - - if (!descriptor.isInheritanceRoot()){ - return false; - } - - ctx.write("create table "); - writeTableName(descriptor); - ctx.write(" (").writeNewLine(); - - InheritInfo inheritInfo = descriptor.getInheritInfo(); - if (inheritInfo != null && inheritInfo.isRoot()){ - String discColumn = inheritInfo.getDiscriminatorColumn(); - int discType = inheritInfo.getDiscriminatorType(); - int discLength = inheritInfo.getDiscriminatorLength(); - DbType dbType = ctx.getDbTypeMap().get(discType); - String discDbType = dbType.renderType(discLength, 0); - - writeColumnName(discColumn, null); - ctx.write(discDbType); - ctx.write(" not null,"); - ctx.writeNewLine(); - - } - - return true; - } - - public void visitBeanEnd(BeanDescriptor descriptor) { + tableName = new TableName(descriptor.getBaseTable()); + ctx.write(descriptor.getBaseTable()); + } - visitInheritanceProperties(descriptor, pv); - - if (checkConstraints.size() > 0){ - for (String checkConstraint : checkConstraints) { - ctx.write(" ").write(checkConstraint).write(",").writeNewLine(); - } - checkConstraints = new ArrayList(); - } - - if (uniqueConstraints.size() > 0){ - for (String constraint : uniqueConstraints) { - ctx.write(" ").write(constraint).write(",").writeNewLine(); - } - uniqueConstraints = new ArrayList(); - } - - CompoundUniqueContraint[] compoundUniqueConstraints = descriptor.getCompoundUniqueConstraints(); - if (compoundUniqueConstraints != null){ - String table = descriptor.getBaseTable(); - for (int i = 0; i < compoundUniqueConstraints.length; i++) { - String constraint = createUniqueConstraint(table, i, compoundUniqueConstraints[i]); - ctx.write(" ").write(constraint).write(",").writeNewLine(); - } - } - - BeanProperty idProp = descriptor.getIdProperty(); + /** + * Write the column name including a check for the SQL reserved words. + */ + protected void writeColumnName(String columnName, BeanProperty p) { - if (idProp == null){ - // No comma + new line - ctx.removeLast().removeLast(); - } else if (ddl.isInlinePrimaryKeyConstraint()) { - // The Primary Key constraint was inlined with the column - // ... No comma + new line - ctx.removeLast().removeLast(); - - } else { - // Add the primay key constraint - String pkName = ddl.getPrimaryKeyName(table); - ctx.write(" constraint ").write(pkName).write(" primary key ("); - - VisitorUtil.visit(idProp, new AbstractPropertyVisitor() { - - @Override - public void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne embedded) { - ctx.write(p.getDbColumn()).write(", "); - } - - @Override - public void visitScalar(BeanProperty p) { - ctx.write(p.getDbColumn()).write(", "); - } - - @Override - public void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p) { - ctx.write(p.getDbColumn()).write(", "); - } - - }); - // remove the last comma, end of PK - ctx.removeLast().write(")"); - } - - // end of table - ctx.write(")").writeNewLine(); - ctx.write(";").writeNewLine().writeNewLine(); - ctx.flush(); - } - - private String createUniqueConstraint(String table, int idx, CompoundUniqueContraint uc) { - - String uqConstraintName = "uq_"+table+"_"+(idx+1) ; - - StringBuilder sb = new StringBuilder(); - sb.append("constraint ") - .append(uqConstraintName) - .append(" unique ("); - - String[] columns = uc.getColumns(); - - for (int i = 0; i < columns.length; i++) { - if (i > 0){ - sb.append(","); - } - sb.append(columns[i]); - } - sb.append(")"); - - return sb.toString(); + addDbColumnWritten(columnName); + + if (SqlReservedWords.isKeyword(columnName)) { + String propName = p == null ? "(Unknown)" : p.getFullBeanName(); + logger.warn("Column name [" + columnName + "] is a suspected SQL reserved word for property " + propName); } + + ctx.write(" ").write(columnName, columnNameWidth).write(" "); + } - public void visitBeanDescriptorEnd() { - ctx.write(");").writeNewLine().writeNewLine(); - } + /** + * Build a check constraint for the property if required. + *

+ * Typically check constraint based on Enum mapping values. + *

+ */ + protected void addCheckConstraint(BeanProperty p, String prefix, String constraintExpression) { + if (p != null && constraintExpression != null) { - public PropertyVisitor visitProperty(BeanProperty p) { - return pv; - } + // build constraint clause + String s = "constraint " + getConstraintName(prefix, p) + " " + constraintExpression; - public void visitBegin() { - - } + // add to list as we render all check constraints just prior to primary key + checkConstraints.add(s); + } + } - public void visitEnd() { - ctx.addIntersectionCreateTables(); - ctx.flush(); - } + protected String getConstraintName(String prefix, BeanProperty p) { + return prefix + tableName.getName() + "_" + p.getDbColumn(); + } + + protected void addUniqueConstraint(String constraintExpression) { + uniqueConstraints.add(constraintExpression); + } + + protected void addCheckConstraint(String constraintExpression) { + checkConstraints.add(constraintExpression); + } + + protected void addCheckConstraint(BeanProperty p) { + addCheckConstraint(p, "ck_", p.getDbConstraintExpression()); + } + + public boolean visitBean(BeanDescriptor descriptor) { + + wroteColumns.clear(); + + if (!descriptor.isInheritanceRoot()) { + return false; + } + + ctx.write("create table "); + writeTableName(descriptor); + ctx.write(" (").writeNewLine(); + + InheritInfo inheritInfo = descriptor.getInheritInfo(); + if (inheritInfo != null && inheritInfo.isRoot()) { + String discColumn = inheritInfo.getDiscriminatorColumn(); + int discType = inheritInfo.getDiscriminatorType(); + int discLength = inheritInfo.getDiscriminatorLength(); + DbType dbType = ctx.getDbTypeMap().get(discType); + String discDbType = dbType.renderType(discLength, 0); + + writeColumnName(discColumn, null); + ctx.write(discDbType); + ctx.write(" not null,"); + ctx.writeNewLine(); + } + + return true; + } + + public void visitBeanEnd(BeanDescriptor descriptor) { + + visitInheritanceProperties(descriptor, pv); + + if (checkConstraints.size() > 0) { + for (String checkConstraint : checkConstraints) { + ctx.write(" ").write(checkConstraint).write(",").writeNewLine(); + } + checkConstraints = new ArrayList(); + } + + if (uniqueConstraints.size() > 0) { + for (String constraint : uniqueConstraints) { + ctx.write(" ").write(constraint).write(",").writeNewLine(); + } + uniqueConstraints = new ArrayList(); + } + + CompoundUniqueContraint[] compoundUniqueConstraints = descriptor.getCompoundUniqueConstraints(); + if (compoundUniqueConstraints != null) { + String table = descriptor.getBaseTable(); + for (int i = 0; i < compoundUniqueConstraints.length; i++) { + String constraint = createUniqueConstraint(table, i, compoundUniqueConstraints[i]); + ctx.write(" ").write(constraint).write(",").writeNewLine(); + } + } + + BeanProperty idProp = descriptor.getIdProperty(); + + if (idProp == null) { + // No comma + new line + ctx.removeLast().removeLast(); + } else if (ddl.isInlinePrimaryKeyConstraint()) { + // The Primary Key constraint was inlined with the column + // ... No comma + new line + ctx.removeLast().removeLast(); + + } else { + // Add the primay key constraint + String pkName = ddl.getPrimaryKeyName(tableName.getName()); + ctx.write(" constraint ").write(pkName).write(" primary key ("); + + VisitorUtil.visit(idProp, new AbstractPropertyVisitor() { + + @Override + public void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne embedded) { + ctx.write(p.getDbColumn()).write(", "); + } + + @Override + public void visitScalar(BeanProperty p) { + ctx.write(p.getDbColumn()).write(", "); + } + + @Override + public void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p) { + ctx.write(p.getDbColumn()).write(", "); + } + + }); + // remove the last comma, end of PK + ctx.removeLast().write(")"); + } + + // end of table + ctx.write(")").writeNewLine(); + ctx.write(";").writeNewLine().writeNewLine(); + ctx.flush(); + } + + private String createUniqueConstraint(String table, int idx, CompoundUniqueContraint uc) { + + String uqConstraintName = "uq_"+TableName.parse(table)+"_"+(idx + 1); + + StringBuilder sb = new StringBuilder(); + sb.append("constraint ").append(uqConstraintName).append(" unique ("); + + String[] columns = uc.getColumns(); + + for (int i = 0; i < columns.length; i++) { + if (i > 0) { + sb.append(","); + } + sb.append(columns[i]); + } + sb.append(")"); + + return sb.toString(); + } + + public void visitBeanDescriptorEnd() { + ctx.write(");").writeNewLine().writeNewLine(); + } + + public PropertyVisitor visitProperty(BeanProperty p) { + return pv; + } + + public void visitBegin() { + + } + + public void visitEnd() { + ctx.addIntersectionCreateTables(); + ctx.flush(); + } }