mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 23:56:36 +00:00
#101 - SQL SERVER - drop.sql does not disable referential integrity
This commit is contained in:
@@ -7,30 +7,35 @@ import com.avaje.ebean.config.TableName;
|
||||
*/
|
||||
public class DbDdlSyntax {
|
||||
|
||||
private boolean renderIndexForFkey = true;
|
||||
protected boolean renderIndexForFkey = true;
|
||||
|
||||
private boolean inlinePrimaryKeyConstraint = false;
|
||||
protected boolean inlinePrimaryKeyConstraint = false;
|
||||
|
||||
private boolean addOneToOneUniqueContraint = true;
|
||||
protected boolean addOneToOneUniqueContraint = true;
|
||||
|
||||
private int maxConstraintNameLength = 32;
|
||||
protected int maxConstraintNameLength = 32;
|
||||
|
||||
private int columnNameWidth = 25;
|
||||
protected int columnNameWidth = 25;
|
||||
|
||||
private String dropTableCascade;
|
||||
private String dropIfExists;
|
||||
/**
|
||||
* Flag set when we want to disable constraints on each table (rather than globally).
|
||||
*/
|
||||
protected boolean dropKeyConstraints;
|
||||
|
||||
private String newLine = "\n";
|
||||
protected String dropTableCascade;
|
||||
protected String dropIfExists;
|
||||
|
||||
private String identity = "auto_increment";
|
||||
private String identitySuffix = "";
|
||||
protected String newLine = "\n";
|
||||
|
||||
private String pkPrefix = "pk_";
|
||||
protected String identity = "auto_increment";
|
||||
protected String identitySuffix = "";
|
||||
|
||||
private String disableReferentialIntegrity;
|
||||
private String enableReferentialIntegrity;
|
||||
protected String pkPrefix = "pk_";
|
||||
|
||||
private String foreignKeySuffix;
|
||||
protected String disableReferentialIntegrity;
|
||||
protected String enableReferentialIntegrity;
|
||||
|
||||
protected String foreignKeySuffix;
|
||||
|
||||
/**
|
||||
* Return the primary key name for a given bean descriptor.
|
||||
@@ -158,6 +163,20 @@ public class DbDdlSyntax {
|
||||
this.enableReferentialIntegrity = enableReferentialIntegrity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true to is constraints are disabled on each table.
|
||||
*/
|
||||
public boolean isDropKeyConstraints() {
|
||||
return dropKeyConstraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return some DDL to disable constraints on the given table.
|
||||
*/
|
||||
public String dropKeyConstraintPrefix(String tableName, String fkName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if indexes should be created for the foreign keys.
|
||||
*/
|
||||
@@ -188,6 +207,13 @@ public class DbDdlSyntax {
|
||||
this.dropIfExists = dropIfExists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return prefix text that goes before drop table.
|
||||
*/
|
||||
public String dropTablePrefix(String tableName) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the cascade option for the drop table command.
|
||||
*/
|
||||
|
||||
@@ -17,8 +17,12 @@ public class MsSqlServer2005Platform extends DatabasePlatform {
|
||||
public MsSqlServer2005Platform() {
|
||||
super();
|
||||
this.name = "mssqlserver2005";
|
||||
// effectively disable persistBatchOnCascade mode for SQL Server
|
||||
// due to lack of support for getGeneratedKeys in batch mode
|
||||
this.disallowBatchOnCascade = true;
|
||||
this.idInExpandedForm = true;
|
||||
this.sqlLimiter = new MsSqlServer2005SqlLimiter();
|
||||
this.dbDdlSyntax.setIdentity("identity(1,1)");
|
||||
this.dbDdlSyntax = new MsDdlSyntax();
|
||||
this.dbIdentity.setIdType(IdType.IDENTITY);
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(true);
|
||||
this.dbIdentity.setSupportsIdentity(true);
|
||||
@@ -28,6 +32,7 @@ public class MsSqlServer2005Platform extends DatabasePlatform {
|
||||
|
||||
dbTypeMap.put(Types.BOOLEAN, new DbType("bit default 0"));
|
||||
|
||||
dbTypeMap.put(Types.INTEGER, new DbType("integer", false));
|
||||
dbTypeMap.put(Types.BIGINT, new DbType("numeric", 19));
|
||||
dbTypeMap.put(Types.REAL, new DbType("float(16)"));
|
||||
dbTypeMap.put(Types.DOUBLE, new DbType("float(32)"));
|
||||
@@ -45,4 +50,30 @@ public class MsSqlServer2005Platform extends DatabasePlatform {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MS SQL Server specific DDL Syntax.
|
||||
*/
|
||||
public class MsDdlSyntax extends DbDdlSyntax {
|
||||
|
||||
MsDdlSyntax() {
|
||||
this.identity = "identity(1,1)";
|
||||
this.dropKeyConstraints = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return some DDL to disable constraints on the given table.
|
||||
*/
|
||||
public String dropKeyConstraintPrefix(String tableName, String fkName) {
|
||||
return "IF OBJECT_ID('"+fkName+"', 'F') IS NOT NULL";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return prefix text that goes before drop table.
|
||||
*/
|
||||
public String dropTablePrefix(String tableName) {
|
||||
return "IF OBJECT_ID('"+tableName+"', 'U') IS NOT NULL ";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.ddl;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.DbDdlSyntax;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
@@ -16,23 +17,23 @@ public class AddForeignKeysVisitor extends AbstractBeanVisitor {
|
||||
|
||||
final FkeyPropertyVisitor pv;
|
||||
|
||||
public AddForeignKeysVisitor(DdlGenContext ctx) {
|
||||
public AddForeignKeysVisitor(boolean addMode, DdlGenContext ctx) {
|
||||
this.ctx = ctx;
|
||||
this.pv = new FkeyPropertyVisitor(this, ctx);
|
||||
this.pv = new FkeyPropertyVisitor(addMode, this, ctx);
|
||||
}
|
||||
|
||||
public boolean visitBean(BeanDescriptor<?> descriptor) {
|
||||
if (!descriptor.isInheritanceRoot()){
|
||||
// ignore/skip if not a top level BeanDescriptor
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void visitBeanEnd(BeanDescriptor<?> descriptor) {
|
||||
|
||||
visitInheritanceProperties(descriptor, pv);
|
||||
public boolean visitBean(BeanDescriptor<?> descriptor) {
|
||||
if (!descriptor.isInheritanceRoot()) {
|
||||
// ignore/skip if not a top level BeanDescriptor
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void visitBeanEnd(BeanDescriptor<?> descriptor) {
|
||||
|
||||
visitInheritanceProperties(descriptor, pv);
|
||||
}
|
||||
|
||||
public void visitBegin() {
|
||||
}
|
||||
@@ -48,11 +49,17 @@ public class AddForeignKeysVisitor extends AbstractBeanVisitor {
|
||||
|
||||
public static class FkeyPropertyVisitor extends BaseTablePropertyVisitor {
|
||||
|
||||
/**
|
||||
* Set to false when generating drop foreign key statements.
|
||||
*/
|
||||
final boolean addMode;
|
||||
|
||||
final DdlGenContext ctx;
|
||||
|
||||
final AddForeignKeysVisitor parent;
|
||||
|
||||
public FkeyPropertyVisitor(AddForeignKeysVisitor parent, DdlGenContext ctx) {
|
||||
public FkeyPropertyVisitor(boolean addMode, AddForeignKeysVisitor parent, DdlGenContext ctx) {
|
||||
this.addMode = addMode;
|
||||
this.parent = parent;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
@@ -69,51 +76,59 @@ public class AddForeignKeysVisitor extends AbstractBeanVisitor {
|
||||
// Alter table o_address add Foreign Key (country_code) references o_country (code) on delete restrict on update restrict;
|
||||
|
||||
String baseTable = p.getBeanDescriptor().getBaseTable();
|
||||
|
||||
TableJoin tableJoin = p.getTableJoin();
|
||||
|
||||
TableJoinColumn[] columns = tableJoin.columns();
|
||||
|
||||
|
||||
String tableName = p.getBeanDescriptor().getBaseTable();
|
||||
String fkName = ctx.getDdlSyntax().getForeignKeyName(tableName, p.getName(), ctx.incrementFkCount());
|
||||
|
||||
ctx.write("alter table ").write(baseTable).write(" add ");
|
||||
DbDdlSyntax ddlSyntax = ctx.getDdlSyntax();
|
||||
String fkName = ddlSyntax.getForeignKeyName(tableName, p.getName(), ctx.incrementFkCount());
|
||||
|
||||
if (!addMode) {
|
||||
// look to generate drop foreign key statement
|
||||
String dropKeyConstraintPrefix = ddlSyntax.dropKeyConstraintPrefix(tableName, fkName);
|
||||
if (dropKeyConstraintPrefix != null && !dropKeyConstraintPrefix.isEmpty()) {
|
||||
ctx.write(dropKeyConstraintPrefix).write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
ctx.write("alter table ").write(baseTable).write(addOrDrop());
|
||||
if (fkName != null) {
|
||||
ctx.write("constraint ").write(fkName).write(" ");
|
||||
}
|
||||
ctx.write("foreign key (");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0){
|
||||
ctx.write(",");
|
||||
}
|
||||
ctx.write(columns[i].getLocalDbColumn());
|
||||
}
|
||||
ctx.write(")");
|
||||
if (addMode) {
|
||||
ctx.write("foreign key (");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
ctx.write(",");
|
||||
}
|
||||
ctx.write(columns[i].getLocalDbColumn());
|
||||
}
|
||||
ctx.write(")");
|
||||
|
||||
ctx.write(" references ");
|
||||
ctx.write(tableJoin.getTable());
|
||||
ctx.write(" (");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0){
|
||||
ctx.write(",");
|
||||
}
|
||||
ctx.write(columns[i].getForeignDbColumn());
|
||||
}
|
||||
ctx.write(")");
|
||||
ctx.write(" references ");
|
||||
ctx.write(tableJoin.getTable());
|
||||
ctx.write(" (");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
ctx.write(",");
|
||||
}
|
||||
ctx.write(columns[i].getForeignDbColumn());
|
||||
}
|
||||
ctx.write(")");
|
||||
|
||||
String fkeySuffix = ctx.getDdlSyntax().getForeignKeySuffix();
|
||||
if (fkeySuffix != null){
|
||||
ctx.write(" ").write(fkeySuffix);
|
||||
}
|
||||
String fkeySuffix = ctx.getDdlSyntax().getForeignKeySuffix();
|
||||
if (fkeySuffix != null) {
|
||||
ctx.write(" ").write(fkeySuffix);
|
||||
}
|
||||
}
|
||||
ctx.write(";").writeNewLine();
|
||||
|
||||
if (ctx.getDdlSyntax().isRenderIndexForFkey()){
|
||||
if (addMode && ddlSyntax.isRenderIndexForFkey()){
|
||||
|
||||
//create index idx_fk_o_address_ctry on o_address(country_code);
|
||||
ctx.write("create index ");
|
||||
|
||||
String idxName = ctx.getDdlSyntax().getIndexName(tableName, p.getName(), ctx.incrementIxCount());
|
||||
String idxName = ddlSyntax.getIndexName(tableName, p.getName(), ctx.incrementIxCount());
|
||||
if (idxName != null){
|
||||
ctx.write(idxName);
|
||||
}
|
||||
@@ -129,21 +144,27 @@ public class AddForeignKeysVisitor extends AbstractBeanVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitScalar(BeanProperty p) {
|
||||
// not interested
|
||||
}
|
||||
/**
|
||||
* Return 'add' or 'drop' of foreign key.
|
||||
*/
|
||||
protected String addOrDrop() {
|
||||
return addMode ? " add " : " drop " ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCompound(BeanPropertyCompound p) {
|
||||
// not interested
|
||||
}
|
||||
@Override
|
||||
public void visitScalar(BeanProperty p) {
|
||||
// not interested
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p) {
|
||||
// not interested
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void visitCompound(BeanPropertyCompound p) {
|
||||
// not interested
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p) {
|
||||
// not interested
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -126,6 +126,13 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
|
||||
DdlGenContext ctx = createContext();
|
||||
|
||||
if (ctx.getDdlSyntax().isDropKeyConstraints()) {
|
||||
// generate drop foreign key constraint statements (sql server joy)
|
||||
AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(false, ctx);
|
||||
VisitorUtil.visit(server, fkeys);
|
||||
ctx.writeNewLine();
|
||||
}
|
||||
|
||||
DropTableVisitor drop = new DropTableVisitor(ctx);
|
||||
VisitorUtil.visit(server, drop);
|
||||
|
||||
@@ -146,7 +153,7 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
CreateSequenceVisitor createSequence = new CreateSequenceVisitor(ctx);
|
||||
VisitorUtil.visit(server, createSequence);
|
||||
|
||||
AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(ctx);
|
||||
AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(true, ctx);
|
||||
VisitorUtil.visit(server, fkeys);
|
||||
|
||||
CreateIndexVisitor indexes = new CreateIndexVisitor(ctx);
|
||||
@@ -275,7 +282,6 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
} catch (Exception e) {
|
||||
if (expectErrors) {
|
||||
logger.info(" ... ignoring error executing " + getSummary(stmt) + " error: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
String msg = "Error executing stmt[" + stmt + "] error[" + e.getMessage() + "]";
|
||||
throw new RuntimeException(msg, e);
|
||||
|
||||
@@ -24,6 +24,7 @@ public class DropTableVisitor implements BeanVisitor {
|
||||
}
|
||||
|
||||
protected void writeDropTable(String tableName){
|
||||
ctx.write(ddlSyntax.dropTablePrefix(tableName));
|
||||
ctx.write("drop table ");
|
||||
if (ddlSyntax.getDropIfExists() != null){
|
||||
ctx.write(ddlSyntax.getDropIfExists()).write(" ");
|
||||
|
||||
Reference in New Issue
Block a user