mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Fix for Issue 19 - Wrong database configuration for SQLite /
AUTOINCREMENT position in generated DDL
This commit is contained in:
@@ -6,3 +6,4 @@
|
||||
target/
|
||||
logs/
|
||||
log/
|
||||
/mydb.db
|
||||
|
||||
@@ -104,6 +104,13 @@
|
||||
<version>1.3.153</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.7.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
|
||||
@@ -18,9 +18,10 @@ public class DbDdlSyntax {
|
||||
private String dropTableCascade;
|
||||
private String dropIfExists;
|
||||
|
||||
private String newLine = "\r\n";
|
||||
private String newLine = "\n";
|
||||
|
||||
private String identity = "auto_increment";
|
||||
private String identitySuffix = "";
|
||||
|
||||
private String pkPrefix = "pk_";
|
||||
|
||||
@@ -56,6 +57,24 @@ public class DbDdlSyntax {
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Typically returns empty string but for SQLite and perhaps others
|
||||
* the Identity/AutoIncrement clause comes after the primary key clause.
|
||||
*/
|
||||
public String getIdentitySuffix() {
|
||||
return identitySuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the identity clause that would appear after the primary key clause.
|
||||
* <p>
|
||||
* Only used for SQLite at this stage.
|
||||
* </p>
|
||||
*/
|
||||
public void setIdentitySuffix(String identitySuffix) {
|
||||
this.identitySuffix = identitySuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the width for padding whitespace after column names.
|
||||
*/
|
||||
|
||||
@@ -22,9 +22,15 @@ public class SQLitePlatform extends DatabasePlatform {
|
||||
|
||||
dbTypeMap.put(Types.BIT, new DbType("int default 0"));
|
||||
dbTypeMap.put(Types.BOOLEAN, new DbType("int default 0"));
|
||||
|
||||
dbTypeMap.put(Types.BIGINT, new DbType("integer"));
|
||||
dbTypeMap.put(Types.SMALLINT, new DbType("integer"));
|
||||
|
||||
dbDdlSyntax.setInlinePrimaryKeyConstraint(true);
|
||||
dbDdlSyntax.setIdentity("AUTOINCREMENT");
|
||||
|
||||
// AutoIncrement goes the primary key declaration
|
||||
dbDdlSyntax.setIdentity("");
|
||||
dbDdlSyntax.setIdentitySuffix("AUTOINCREMENT");
|
||||
|
||||
dbDdlSyntax.setDisableReferentialIntegrity("PRAGMA foreign_keys = OFF");
|
||||
dbDdlSyntax.setEnableReferentialIntegrity("PRAGMA foreign_keys = ON");
|
||||
}
|
||||
|
||||
@@ -21,136 +21,130 @@ import org.slf4j.LoggerFactory;
|
||||
public class CreateTableColumnVisitor extends BaseTablePropertyVisitor {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CreateTableColumnVisitor.class);
|
||||
|
||||
private final DdlGenContext ctx;
|
||||
|
||||
private final DbDdlSyntax ddl;
|
||||
private final DdlGenContext ctx;
|
||||
|
||||
private final CreateTableVisitor parent;
|
||||
private final DbDdlSyntax ddl;
|
||||
|
||||
public CreateTableColumnVisitor(CreateTableVisitor parent, DdlGenContext ctx) {
|
||||
this.parent = parent;
|
||||
this.ctx = ctx;
|
||||
this.ddl = ctx.getDdlSyntax();
|
||||
}
|
||||
private final CreateTableVisitor parent;
|
||||
|
||||
public CreateTableColumnVisitor(CreateTableVisitor parent, DdlGenContext ctx) {
|
||||
this.parent = parent;
|
||||
this.ctx = ctx;
|
||||
this.ddl = ctx.getDdlSyntax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMany(BeanPropertyAssocMany<?> p) {
|
||||
if (p.isManyToMany()){
|
||||
if (p.getMappedBy() != null) {
|
||||
// only create on other 'owning' side
|
||||
|
||||
} else {
|
||||
TableJoin intersectionTableJoin = p.getIntersectionTableJoin();
|
||||
|
||||
// check if the intersection table has already been created
|
||||
String intTable = intersectionTableJoin.getTable();
|
||||
if (ctx.isProcessIntersectionTable(intTable)){
|
||||
// build the create table and fkey constraints
|
||||
// putting the DDL into ctx for later output as we are
|
||||
// in the middle of rendering the create table DDL
|
||||
new CreateIntersectionTable(ctx, p).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void visitMany(BeanPropertyAssocMany<?> p) {
|
||||
if (p.isManyToMany()) {
|
||||
if (p.getMappedBy() != null) {
|
||||
// only create on other 'owning' side
|
||||
|
||||
|
||||
public void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p) {
|
||||
visitScalar(p);
|
||||
}
|
||||
} else {
|
||||
TableJoin intersectionTableJoin = p.getIntersectionTableJoin();
|
||||
|
||||
|
||||
public void visitCompound(BeanPropertyCompound p) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne<?> embedded) {
|
||||
|
||||
visitScalar(p);
|
||||
}
|
||||
|
||||
private StringBuilder createUniqueConstraintBuffer(String table, String column) {
|
||||
|
||||
String uqConstraintName = "uq_"+ table+ "_"+column;
|
||||
|
||||
if (uqConstraintName.length() > ddl.getMaxConstraintNameLength()){
|
||||
uqConstraintName = uqConstraintName.substring(0, ddl.getMaxConstraintNameLength());
|
||||
// check if the intersection table has already been created
|
||||
String intTable = intersectionTableJoin.getTable();
|
||||
if (ctx.isProcessIntersectionTable(intTable)) {
|
||||
// build the create table and fkey constraints
|
||||
// putting the DDL into ctx for later output as we are
|
||||
// in the middle of rendering the create table DDL
|
||||
new CreateIntersectionTable(ctx, p).build();
|
||||
}
|
||||
|
||||
uqConstraintName = ctx.removeQuotes(uqConstraintName);
|
||||
uqConstraintName = StringHelper.replaceString(uqConstraintName, " ", "_");
|
||||
|
||||
StringBuilder constraintExpr = new StringBuilder();
|
||||
constraintExpr.append("constraint ")
|
||||
.append(uqConstraintName)
|
||||
.append(" unique (");
|
||||
|
||||
return constraintExpr;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOneImported(BeanPropertyAssocOne<?> p) {
|
||||
}
|
||||
|
||||
public void visitCompoundScalar(BeanPropertyCompound compound, BeanProperty p) {
|
||||
visitScalar(p);
|
||||
}
|
||||
|
||||
ImportedId importedId = p.getImportedId();
|
||||
public void visitCompound(BeanPropertyCompound p) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
TableJoinColumn[] columns = p.getTableJoin().columns();
|
||||
if (columns.length == 0){
|
||||
String msg = "No join columns for "+p.getFullBeanName();
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
|
||||
StringBuilder constraintExpr = createUniqueConstraintBuffer(p.getBeanDescriptor().getBaseTable(), columns[0].getLocalDbColumn());
|
||||
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
|
||||
String dbCol = columns[i].getLocalDbColumn();
|
||||
@Override
|
||||
public void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne<?> embedded) {
|
||||
|
||||
if (i > 0){
|
||||
constraintExpr.append(", ");
|
||||
}
|
||||
constraintExpr.append(dbCol);
|
||||
|
||||
if (parent.isDbColumnWritten(dbCol)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
parent.writeColumnName(dbCol, p);
|
||||
visitScalar(p);
|
||||
}
|
||||
|
||||
BeanProperty importedProperty = importedId.findMatchImport(dbCol);
|
||||
if (importedProperty != null) {
|
||||
private StringBuilder createUniqueConstraintBuffer(String table, String column) {
|
||||
|
||||
String columnDefn = ctx.getColumnDefn(importedProperty);
|
||||
ctx.write(columnDefn);
|
||||
String uqConstraintName = "uq_" + table + "_" + column;
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Imported BeanProperty not found?");
|
||||
}
|
||||
if (uqConstraintName.length() > ddl.getMaxConstraintNameLength()) {
|
||||
uqConstraintName = uqConstraintName.substring(0, ddl.getMaxConstraintNameLength());
|
||||
}
|
||||
|
||||
if (!p.isNullable()) {
|
||||
ctx.write(" not null");
|
||||
}
|
||||
ctx.write(",").writeNewLine();
|
||||
}
|
||||
constraintExpr.append(")");
|
||||
|
||||
if (p.isOneToOne()){
|
||||
if (ddl.isAddOneToOneUniqueContraint()){
|
||||
parent.addUniqueConstraint( constraintExpr.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uqConstraintName = ctx.removeQuotes(uqConstraintName);
|
||||
uqConstraintName = StringHelper.replaceString(uqConstraintName, " ", "_");
|
||||
|
||||
StringBuilder constraintExpr = new StringBuilder();
|
||||
constraintExpr.append("constraint ").append(uqConstraintName).append(" unique (");
|
||||
|
||||
return constraintExpr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOneImported(BeanPropertyAssocOne<?> p) {
|
||||
|
||||
ImportedId importedId = p.getImportedId();
|
||||
|
||||
TableJoinColumn[] columns = p.getTableJoin().columns();
|
||||
if (columns.length == 0) {
|
||||
String msg = "No join columns for " + p.getFullBeanName();
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
|
||||
StringBuilder constraintExpr = createUniqueConstraintBuffer(p.getBeanDescriptor().getBaseTable(), columns[0].getLocalDbColumn());
|
||||
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
|
||||
String dbCol = columns[i].getLocalDbColumn();
|
||||
|
||||
if (i > 0) {
|
||||
constraintExpr.append(", ");
|
||||
}
|
||||
constraintExpr.append(dbCol);
|
||||
|
||||
if (parent.isDbColumnWritten(dbCol)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
parent.writeColumnName(dbCol, p);
|
||||
|
||||
BeanProperty importedProperty = importedId.findMatchImport(dbCol);
|
||||
if (importedProperty != null) {
|
||||
|
||||
String columnDefn = ctx.getColumnDefn(importedProperty);
|
||||
ctx.write(columnDefn);
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Imported BeanProperty not found?");
|
||||
}
|
||||
|
||||
if (!p.isNullable()) {
|
||||
ctx.write(" not null");
|
||||
}
|
||||
ctx.write(",").writeNewLine();
|
||||
}
|
||||
constraintExpr.append(")");
|
||||
|
||||
if (p.isOneToOne()) {
|
||||
if (ddl.isAddOneToOneUniqueContraint()) {
|
||||
parent.addUniqueConstraint(constraintExpr.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitScalar(BeanProperty p) {
|
||||
|
||||
if (p.isSecondaryTable()) {
|
||||
return;
|
||||
}
|
||||
if (p.isSecondaryTable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent.isDbColumnWritten(p.getDbColumn())) {
|
||||
return;
|
||||
@@ -161,7 +155,8 @@ public class CreateTableColumnVisitor extends BaseTablePropertyVisitor {
|
||||
String columnDefn = ctx.getColumnDefn(p);
|
||||
ctx.write(columnDefn);
|
||||
|
||||
if (isIdentity(p)) {
|
||||
boolean identity = isIdentity(p);
|
||||
if (identity) {
|
||||
writeIdentity();
|
||||
}
|
||||
|
||||
@@ -172,23 +167,25 @@ public class CreateTableColumnVisitor extends BaseTablePropertyVisitor {
|
||||
ctx.write(" not null");
|
||||
}
|
||||
|
||||
if (p.isUnique() && !p.isId()){
|
||||
parent.addUniqueConstraint(createUniqueConstraint(p));
|
||||
}
|
||||
if (identity) {
|
||||
writeIdentitySuffix();
|
||||
}
|
||||
|
||||
if (p.isUnique() && !p.isId()) {
|
||||
parent.addUniqueConstraint(createUniqueConstraint(p));
|
||||
}
|
||||
|
||||
parent.addCheckConstraint(p);
|
||||
|
||||
ctx.write(",").writeNewLine();
|
||||
}
|
||||
|
||||
private String createUniqueConstraint(BeanProperty p) {
|
||||
|
||||
StringBuilder expr = createUniqueConstraintBuffer(p.getBeanDescriptor().getBaseTable(), p.getDbColumn());
|
||||
|
||||
expr.append(p.getDbColumn()).append(")");
|
||||
|
||||
return expr.toString();
|
||||
}
|
||||
private String createUniqueConstraint(BeanProperty p) {
|
||||
|
||||
StringBuilder expr = createUniqueConstraintBuffer(p.getBeanDescriptor().getBaseTable(), p.getDbColumn());
|
||||
|
||||
expr.append(p.getDbColumn()).append(")");
|
||||
return expr.toString();
|
||||
}
|
||||
|
||||
protected void writeIdentity() {
|
||||
String identity = ddl.getIdentity();
|
||||
@@ -197,27 +194,33 @@ public class CreateTableColumnVisitor extends BaseTablePropertyVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isIdentity(BeanProperty p) {
|
||||
|
||||
if (p.isId()) {
|
||||
try {
|
||||
IdType idType = p.getBeanDescriptor().getIdType();
|
||||
|
||||
if (idType.equals(IdType.IDENTITY)){
|
||||
|
||||
int jdbcType = p.getScalarType().getJdbcType();
|
||||
if (jdbcType == Types.INTEGER || jdbcType == Types.BIGINT || jdbcType == Types.SMALLINT) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e){
|
||||
String msg = "Error determining identity on property "+p.getFullBeanName();
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected void writeIdentitySuffix() {
|
||||
String identity = ddl.getIdentitySuffix();
|
||||
if (identity != null && identity.length() > 0) {
|
||||
ctx.write(" ").write(identity);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isIdentity(BeanProperty p) {
|
||||
|
||||
if (p.isId()) {
|
||||
try {
|
||||
IdType idType = p.getBeanDescriptor().getIdType();
|
||||
|
||||
if (idType.equals(IdType.IDENTITY)) {
|
||||
|
||||
int jdbcType = p.getScalarType().getJdbcType();
|
||||
if (jdbcType == Types.INTEGER || jdbcType == Types.BIGINT || jdbcType == Types.SMALLINT) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Error determining identity on property " + p.getFullBeanName();
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,75 +31,75 @@ import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
public class DdlGenerator implements SpiEbeanPlugin {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DdlGenerator.class);
|
||||
|
||||
private SpiEbeanServer server;
|
||||
|
||||
private DatabasePlatform dbPlatform;
|
||||
private SpiEbeanServer server;
|
||||
|
||||
private int summaryLength = 80;
|
||||
private DatabasePlatform dbPlatform;
|
||||
|
||||
private boolean generateDdl;
|
||||
private boolean runDdl;
|
||||
private int summaryLength = 80;
|
||||
|
||||
private String dropContent;
|
||||
private String createContent;
|
||||
private boolean generateDdl;
|
||||
private boolean runDdl;
|
||||
|
||||
private NamingConvention namingConvention;
|
||||
private String dropContent;
|
||||
private String createContent;
|
||||
|
||||
public void setup(SpiEbeanServer server, DatabasePlatform dbPlatform, ServerConfig serverConfig) {
|
||||
this.server = server;
|
||||
this.dbPlatform = dbPlatform;
|
||||
this.generateDdl = serverConfig.isDdlGenerate();
|
||||
this.runDdl = serverConfig.isDdlRun();
|
||||
this.namingConvention = serverConfig.getNamingConvention();
|
||||
}
|
||||
private NamingConvention namingConvention;
|
||||
|
||||
/**
|
||||
* Generate the DDL and then run the DDL based on property settings (ebean.ddl.generate and ebean.ddl.run etc).
|
||||
*/
|
||||
public void execute(boolean online) {
|
||||
generateDdl();
|
||||
if (online){
|
||||
runDdl();
|
||||
}
|
||||
}
|
||||
public void setup(SpiEbeanServer server, DatabasePlatform dbPlatform, ServerConfig serverConfig) {
|
||||
this.server = server;
|
||||
this.dbPlatform = dbPlatform;
|
||||
this.generateDdl = serverConfig.isDdlGenerate();
|
||||
this.runDdl = serverConfig.isDdlRun();
|
||||
this.namingConvention = serverConfig.getNamingConvention();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the DDL drop and create scripts if the properties have been set.
|
||||
*/
|
||||
public void generateDdl() {
|
||||
if (generateDdl) {
|
||||
writeDrop(getDropFileName());
|
||||
writeCreate(getCreateFileName());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generate the DDL and then run the DDL based on property settings
|
||||
* (ebean.ddl.generate and ebean.ddl.run etc).
|
||||
*/
|
||||
public void execute(boolean online) {
|
||||
generateDdl();
|
||||
if (online) {
|
||||
runDdl();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the DDL drop and DDL create scripts if properties have been set.
|
||||
*/
|
||||
public void runDdl() {
|
||||
/**
|
||||
* Generate the DDL drop and create scripts if the properties have been set.
|
||||
*/
|
||||
public void generateDdl() {
|
||||
if (generateDdl) {
|
||||
writeDrop(getDropFileName());
|
||||
writeCreate(getCreateFileName());
|
||||
}
|
||||
}
|
||||
|
||||
if (runDdl) {
|
||||
try {
|
||||
if (dropContent == null){
|
||||
dropContent = readFile(getDropFileName());
|
||||
}
|
||||
if (createContent == null){
|
||||
createContent = readFile(getCreateFileName());
|
||||
}
|
||||
runScript(true, dropContent);
|
||||
runScript(false, createContent);
|
||||
/**
|
||||
* Run the DDL drop and DDL create scripts if properties have been set.
|
||||
*/
|
||||
public void runDdl() {
|
||||
|
||||
} catch (IOException e){
|
||||
String msg = "Error reading drop/create script from file system";
|
||||
throw new RuntimeException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (runDdl) {
|
||||
try {
|
||||
if (dropContent == null) {
|
||||
dropContent = readFile(getDropFileName());
|
||||
}
|
||||
if (createContent == null) {
|
||||
createContent = readFile(getCreateFileName());
|
||||
}
|
||||
runScript(true, dropContent);
|
||||
runScript(false, createContent);
|
||||
|
||||
} catch (IOException e) {
|
||||
String msg = "Error reading drop/create script from file system";
|
||||
throw new RuntimeException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeDrop(String dropFile) {
|
||||
|
||||
// String c = generateDropDdl();
|
||||
try {
|
||||
String c = generateDropDdl();
|
||||
writeFile(dropFile, c);
|
||||
@@ -110,224 +110,223 @@ public class DdlGenerator implements SpiEbeanPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeCreate(String createFile) {
|
||||
protected void writeCreate(String createFile) {
|
||||
|
||||
// String c = generateCreateDdl();
|
||||
try {
|
||||
String c = generateCreateDdl();
|
||||
writeFile(createFile, c);
|
||||
try {
|
||||
String c = generateCreateDdl();
|
||||
writeFile(createFile, c);
|
||||
|
||||
} catch (IOException e) {
|
||||
String msg = "Error generating Create DDL";
|
||||
throw new PersistenceException(msg, e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
String msg = "Error generating Create DDL";
|
||||
throw new PersistenceException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public String generateDropDdl() {
|
||||
public String generateDropDdl() {
|
||||
|
||||
DdlGenContext ctx = createContext();
|
||||
DdlGenContext ctx = createContext();
|
||||
|
||||
DropTableVisitor drop = new DropTableVisitor(ctx);
|
||||
VisitorUtil.visit(server, drop);
|
||||
DropTableVisitor drop = new DropTableVisitor(ctx);
|
||||
VisitorUtil.visit(server, drop);
|
||||
|
||||
DropSequenceVisitor dropSequence = new DropSequenceVisitor(ctx);
|
||||
VisitorUtil.visit(server, dropSequence);
|
||||
DropSequenceVisitor dropSequence = new DropSequenceVisitor(ctx);
|
||||
VisitorUtil.visit(server, dropSequence);
|
||||
|
||||
ctx.flush();
|
||||
dropContent = ctx.getContent();
|
||||
return dropContent;
|
||||
}
|
||||
ctx.flush();
|
||||
dropContent = ctx.getContent();
|
||||
return dropContent;
|
||||
}
|
||||
|
||||
public String generateCreateDdl() {
|
||||
public String generateCreateDdl() {
|
||||
|
||||
DdlGenContext ctx = createContext();
|
||||
CreateTableVisitor create = new CreateTableVisitor(ctx);
|
||||
VisitorUtil.visit(server, create);
|
||||
DdlGenContext ctx = createContext();
|
||||
CreateTableVisitor create = new CreateTableVisitor(ctx);
|
||||
VisitorUtil.visit(server, create);
|
||||
|
||||
CreateSequenceVisitor createSequence = new CreateSequenceVisitor(ctx);
|
||||
VisitorUtil.visit(server, createSequence);
|
||||
CreateSequenceVisitor createSequence = new CreateSequenceVisitor(ctx);
|
||||
VisitorUtil.visit(server, createSequence);
|
||||
|
||||
AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(ctx);
|
||||
VisitorUtil.visit(server, fkeys);
|
||||
AddForeignKeysVisitor fkeys = new AddForeignKeysVisitor(ctx);
|
||||
VisitorUtil.visit(server, fkeys);
|
||||
|
||||
ctx.flush();
|
||||
createContent = ctx.getContent();
|
||||
return createContent;
|
||||
}
|
||||
ctx.flush();
|
||||
createContent = ctx.getContent();
|
||||
return createContent;
|
||||
}
|
||||
|
||||
protected String getDropFileName() {
|
||||
return server.getName() + "-drop.sql";
|
||||
}
|
||||
protected String getDropFileName() {
|
||||
return server.getName() + "-drop.sql";
|
||||
}
|
||||
|
||||
protected String getCreateFileName() {
|
||||
return server.getName() + "-create.sql";
|
||||
}
|
||||
protected String getCreateFileName() {
|
||||
return server.getName() + "-create.sql";
|
||||
}
|
||||
|
||||
protected DdlGenContext createContext() {
|
||||
return new DdlGenContext(dbPlatform, namingConvention);
|
||||
}
|
||||
protected DdlGenContext createContext() {
|
||||
return new DdlGenContext(dbPlatform, namingConvention);
|
||||
}
|
||||
|
||||
protected void writeFile(String fileName, String fileContent) throws IOException {
|
||||
protected void writeFile(String fileName, String fileContent) throws IOException {
|
||||
|
||||
File f = new File(fileName);
|
||||
File f = new File(fileName);
|
||||
|
||||
FileWriter fw = new FileWriter(f);
|
||||
try {
|
||||
fw.write(fileContent);
|
||||
fw.flush();
|
||||
} finally {
|
||||
fw.close();
|
||||
}
|
||||
}
|
||||
FileWriter fw = new FileWriter(f);
|
||||
try {
|
||||
fw.write(fileContent);
|
||||
fw.flush();
|
||||
} finally {
|
||||
fw.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected String readFile(String fileName) throws IOException {
|
||||
protected String readFile(String fileName) throws IOException {
|
||||
|
||||
File f = new File(fileName);
|
||||
if (!f.exists()){
|
||||
return null;
|
||||
}
|
||||
File f = new File(fileName);
|
||||
if (!f.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
FileReader fr = new FileReader(f);
|
||||
LineNumberReader lr = new LineNumberReader(fr);
|
||||
try {
|
||||
String s = null;
|
||||
while ((s = lr.readLine()) != null){
|
||||
buf.append(s).append("\n");
|
||||
}
|
||||
} finally {
|
||||
lr.close();
|
||||
}
|
||||
FileReader fr = new FileReader(f);
|
||||
LineNumberReader lr = new LineNumberReader(fr);
|
||||
try {
|
||||
String s = null;
|
||||
while ((s = lr.readLine()) != null) {
|
||||
buf.append(s).append("\n");
|
||||
}
|
||||
} finally {
|
||||
lr.close();
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all the DDL statements in the script.
|
||||
*/
|
||||
public void runScript(boolean expectErrors, String content) {
|
||||
/**
|
||||
* Execute all the DDL statements in the script.
|
||||
*/
|
||||
public void runScript(boolean expectErrors, String content) {
|
||||
|
||||
StringReader sr = new StringReader(content);
|
||||
List<String> statements = parseStatements(sr);
|
||||
StringReader sr = new StringReader(content);
|
||||
List<String> statements = parseStatements(sr);
|
||||
|
||||
Transaction t = server.createTransaction();
|
||||
try {
|
||||
Connection connection = t.getConnection();
|
||||
Transaction t = server.createTransaction();
|
||||
try {
|
||||
Connection connection = t.getConnection();
|
||||
|
||||
logger.info("Running DDL");
|
||||
logger.info("Running DDL");
|
||||
|
||||
runStatements(expectErrors, statements, connection);
|
||||
runStatements(expectErrors, statements, connection);
|
||||
|
||||
logger.info("Running DDL Complete");
|
||||
logger.info("Running DDL Complete");
|
||||
|
||||
t.commit();
|
||||
t.commit();
|
||||
|
||||
} catch (Exception e){
|
||||
String msg = "Error: "+e.getMessage();
|
||||
throw new PersistenceException(msg, e);
|
||||
} finally {
|
||||
t.end();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Error: " + e.getMessage();
|
||||
throw new PersistenceException(msg, e);
|
||||
} finally {
|
||||
t.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the list of statements.
|
||||
*/
|
||||
private void runStatements(boolean expectErrors, List<String> statements, Connection c) {
|
||||
/**
|
||||
* Execute the list of statements.
|
||||
*/
|
||||
private void runStatements(boolean expectErrors, List<String> statements, Connection c) {
|
||||
|
||||
for (int i = 0; i < statements.size(); i++) {
|
||||
String xOfy = (i + 1) + " of " + statements.size();
|
||||
runStatement(expectErrors, xOfy, statements.get(i), c);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < statements.size(); i++) {
|
||||
String xOfy = (i + 1) + " of " + statements.size();
|
||||
runStatement(expectErrors, xOfy, statements.get(i), c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the statement.
|
||||
*/
|
||||
private void runStatement(boolean expectErrors, String oneOf, String stmt, Connection c) {
|
||||
/**
|
||||
* Execute the statement.
|
||||
*/
|
||||
private void runStatement(boolean expectErrors, String oneOf, String stmt, Connection c) {
|
||||
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
|
||||
// trim and remove trailing ; or /
|
||||
stmt = stmt.trim();
|
||||
if (stmt.endsWith(";")){
|
||||
stmt = stmt.substring(0, stmt.length()-1);
|
||||
} else if (stmt.endsWith("/")) {
|
||||
stmt = stmt.substring(0, stmt.length()-1);
|
||||
}
|
||||
// trim and remove trailing ; or /
|
||||
stmt = stmt.trim();
|
||||
if (stmt.endsWith(";")) {
|
||||
stmt = stmt.substring(0, stmt.length() - 1);
|
||||
} else if (stmt.endsWith("/")) {
|
||||
stmt = stmt.substring(0, stmt.length() - 1);
|
||||
}
|
||||
|
||||
logger.trace("executing "+oneOf+" "+ getSummary(stmt));
|
||||
logger.trace("executing " + oneOf + " " + getSummary(stmt));
|
||||
|
||||
pstmt = c.prepareStatement(stmt);
|
||||
pstmt.execute();
|
||||
pstmt = c.prepareStatement(stmt);
|
||||
pstmt.execute();
|
||||
|
||||
} 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);
|
||||
}
|
||||
} finally {
|
||||
if (pstmt != null){
|
||||
try {
|
||||
pstmt.close();
|
||||
} catch (SQLException e){
|
||||
logger.error("Error closing pstmt", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
} finally {
|
||||
if (pstmt != null) {
|
||||
try {
|
||||
pstmt.close();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Error closing pstmt", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Break up the sql in reader into a list of statements using the semi-colon
|
||||
* character;
|
||||
*/
|
||||
protected List<String> parseStatements(StringReader reader) {
|
||||
/**
|
||||
* Break up the sql in reader into a list of statements using the semi-colon
|
||||
* character;
|
||||
*/
|
||||
protected List<String> parseStatements(StringReader reader) {
|
||||
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(reader);
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(reader);
|
||||
|
||||
ArrayList<String> statements = new ArrayList<String>();
|
||||
ArrayList<String> statements = new ArrayList<String>();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s;
|
||||
while ((s = br.readLine()) != null) {
|
||||
s = s.trim();
|
||||
int semiPos = s.indexOf(';');
|
||||
if (semiPos == -1) {
|
||||
sb.append(s).append(" ");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s;
|
||||
while ((s = br.readLine()) != null) {
|
||||
s = s.trim();
|
||||
int semiPos = s.indexOf(';');
|
||||
if (semiPos == -1) {
|
||||
sb.append(s).append(" ");
|
||||
|
||||
} else if (semiPos == s.length()-1) {
|
||||
// semicolon at end of line
|
||||
sb.append(s);
|
||||
statements.add(sb.toString().trim());
|
||||
sb = new StringBuilder();
|
||||
} else if (semiPos == s.length() - 1) {
|
||||
// semicolon at end of line
|
||||
sb.append(s);
|
||||
statements.add(sb.toString().trim());
|
||||
sb = new StringBuilder();
|
||||
|
||||
} else {
|
||||
// semicolon in middle of line
|
||||
String preSemi = s.substring(0, semiPos);
|
||||
sb.append(preSemi);
|
||||
statements.add(sb.toString().trim());
|
||||
sb = new StringBuilder();
|
||||
sb.append(s.substring(semiPos+1));
|
||||
} else {
|
||||
// semicolon in middle of line
|
||||
String preSemi = s.substring(0, semiPos);
|
||||
sb.append(preSemi);
|
||||
statements.add(sb.toString().trim());
|
||||
sb = new StringBuilder();
|
||||
sb.append(s.substring(semiPos + 1));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return statements;
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException(e);
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getSummary(String s){
|
||||
if (s.length() > summaryLength){
|
||||
return s.substring(0, summaryLength).trim()+"...";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
private String getSummary(String s) {
|
||||
if (s.length() > summaryLength) {
|
||||
return s.substring(0, summaryLength).trim() + "...";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,14 @@ datasource.h2.poolListener=com.avaje.tests.basic.MyTestDataSourcePoolListener
|
||||
|
||||
datasource.h2.customProperties=IGNORECASE=TRUE;MODE=Oracle;
|
||||
|
||||
datasource.sqlite.username=
|
||||
datasource.sqlite.password=
|
||||
datasource.sqlite.databaseUrl=jdbc:sqlite:mydb.db
|
||||
datasource.sqlite.databaseDriver=org.sqlite.JDBC
|
||||
datasource.sqlite.isolationlevel=read_uncommitted
|
||||
datasource.sqlite.minConnections=1
|
||||
datasource.sqlite.maxConnections=25
|
||||
|
||||
datasource.hsqldb.username=sa
|
||||
datasource.hsqldb.password=
|
||||
datasource.hsqldb.databaseUrl=jdbc:hsqldb:mem:tests
|
||||
|
||||
Reference in New Issue
Block a user