/** * Generate the appropriate 'create table' and matching 'drop table' statements and add them to * the 'apply' and 'rollback' buffers. */ @Override public void generate(DdlWrite writer, CreateTable createTable) throws IOException { reset(); String tableName = lowerName(createTable.getName()); List<Column> columns = createTable.getColumn(); List<Column> pk = determinePrimaryKeyColumns(columns); boolean singleColumnPrimaryKey = pk.size() == 1; boolean useIdentity = false; boolean useSequence = false; if (singleColumnPrimaryKey) { IdType useDbIdentityType = platformDdl.useIdentityType(createTable.getIdentityType()); useIdentity = (IdType.IDENTITY == useDbIdentityType); useSequence = (IdType.SEQUENCE == useDbIdentityType); } DdlBuffer apply = writer.apply(); apply.append("create table ").append(tableName).append(" ("); for (int i = 0; i < columns.size(); i++) { apply.newLine(); writeColumnDefinition(apply, columns.get(i), useIdentity); if (i < columns.size() - 1) { apply.append(","); } } writeCheckConstraints(apply, createTable); writeUniqueConstraints(apply, createTable); writeCompoundUniqueConstraints(apply, createTable); if (!pk.isEmpty()) { // defined on the columns writePrimaryKeyConstraint(apply, tableName, toColumnNames(pk)); } apply.newLine().append(")").endOfStatement(); // add drop table to the rollback buffer - do this before // we drop the related sequence (if sequences are used) dropTable(writer.rollback(), tableName); if (useSequence) { writeSequence(writer, createTable); } // add blank line for a bit of whitespace between tables apply.end(); writer.rollback().end(); writeAddForeignKeys(writer, createTable); if (isTrue(createTable.isWithHistory())) { createWithHistory(writer, createTable.getName()); } }
/** Write the unique constraints inline with the create table statement. */ protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { List<Column> columns = createTable.getColumn(); for (Column column : columns) { if (isTrue(column.isUnique())) { inlineUniqueConstraintSingle(apply, createTable.getName(), column); indexSet.add(column); } } }
/** Write all the check constraints. */ protected void writeCheckConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { List<Column> columns = createTable.getColumn(); for (Column column : columns) { String checkConstraint = column.getCheckConstraint(); if (hasValue(checkConstraint)) { writeCheckConstraint(apply, createTable.getName(), column, checkConstraint); } } }
protected void writeAddForeignKeys(DdlWrite write, CreateTable createTable) throws IOException { String tableName = createTable.getName(); List<Column> columns = createTable.getColumn(); for (Column column : columns) { String references = column.getReferences(); if (hasValue(references)) { writeForeignKey(write, tableName, column.getName(), references); } } writeAddCompoundForeignKeys(write, createTable); }
private void writeSequence(DdlWrite writer, CreateTable createTable) throws IOException { // explicit sequence use or platform decides String explicitSequenceName = createTable.getSequenceName(); int initial = toInt(createTable.getSequenceInitial()); int allocate = toInt(createTable.getSequenceAllocate()); String seqName = namingConvention.sequenceName(createTable.getName(), explicitSequenceName); String createSeq = platformDdl.createSequence(seqName, initial, allocate); if (createSeq != null) { writer.apply().append(createSeq).newLine(); writer.rollback().append(platformDdl.dropSequence(seqName)).endOfStatement(); } }
protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { String tableName = createTable.getName(); List<UniqueConstraint> uniqueConstraints = createTable.getUniqueConstraint(); for (UniqueConstraint uniqueConstraint : uniqueConstraints) { String[] columns = toColumnNamesSplit(uniqueConstraint.getColumnNames()); apply .append( platformDdl.alterTableAddUniqueConstraint( tableName, uniqueConstraint.getName(), columns)) .endOfStatement(); } }
protected void writeAddCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException { String tableName = createTable.getName(); List<ForeignKey> foreignKey = createTable.getForeignKey(); for (ForeignKey key : foreignKey) { String refTableName = key.getRefTableName(); String fkName = determineForeignKeyConstraintName(tableName, refTableName); String[] cols = toColumnNamesSplit(key.getColumnNames()); String[] refColumns = toColumnNamesSplit(key.getRefColumnNames()); writeForeignKey(write, fkName, tableName, cols, refTableName, refColumns); } }
/** * Specific handling of OneToOne unique constraints for MsSqlServer. For all other DB platforms * these unique constraints are done inline as per normal. */ protected void writeUniqueOneToOneConstraints(DdlWrite write, CreateTable createTable) throws IOException { String tableName = createTable.getName(); for (Column col : externalUnique) { String uqName = col.getUniqueOneToOne(); String[] columnNames = {col.getName()}; write .apply() .append(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames)) .endOfStatement(); write.rollbackForeignKeys().append(platformDdl.dropIndex(uqName, tableName)).endOfStatement(); } }
/** Write the unique constraints inline with the create table statement. */ protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException { boolean inlineUniqueOneToOne = platformDdl.isInlineUniqueOneToOne(); List<Column> columns = createTable.getColumn(); for (Column column : columns) { if (hasValue(column.getUnique()) || (inlineUniqueOneToOne && hasValue(column.getUniqueOneToOne()))) { // normal mechanism for adding unique constraint inlineUniqueConstraintSingle(apply, column); } else if (!inlineUniqueOneToOne && hasValue(column.getUniqueOneToOne())) { // MsSqlServer specific mechanism for adding unique constraints (that allow nulls) externalUnique.add(column); } } }