mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-04 00:26:20 +00:00
#2074 - Refactor extract ebean-ddlgen module. In future this module would expected to be a test only dependency
This commit is contained in:
1 parent
b9047bf280
commit
b22bffe770
426 files changed
+5533
-229
No files matched your search
@@ -1,373 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DbMigrationConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.migration.ddl.DdlRunner;
|
||||
import io.ebean.migration.runner.ScriptTransform;
|
||||
import io.ebean.util.JdbcClose;
|
||||
import io.ebeaninternal.api.SpiDdlGenerator;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.dbmigration.model.CurrentModel;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
import io.ebeaninternal.extraddl.model.ExtraDdlXmlReader;
|
||||
import io.ebeaninternal.server.deploy.PartitionMeta;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Controls the generation and execution of "Create All" and "Drop All" DDL scripts.
|
||||
* <p>
|
||||
* Typically the "Create All" DDL is executed for running tests etc and has nothing to do
|
||||
* with DB Migration (diff based) DDL.
|
||||
*/
|
||||
public class DdlGenerator implements SpiDdlGenerator {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DdlGenerator.class);
|
||||
private static final String[] BUILD_DIRS = {"target", "build"};
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
private final boolean generateDdl;
|
||||
private final boolean runDdl;
|
||||
private final boolean extraDdl;
|
||||
private final boolean createOnly;
|
||||
private final boolean jaxbPresent;
|
||||
private final boolean ddlAutoCommit;
|
||||
private final String dbSchema;
|
||||
private final ScriptTransform scriptTransform;
|
||||
private final Platform platform;
|
||||
private final String platformName;
|
||||
|
||||
private CurrentModel currentModel;
|
||||
private String dropAllContent;
|
||||
private String createAllContent;
|
||||
private final File baseDir;
|
||||
|
||||
public DdlGenerator(SpiEbeanServer server) {
|
||||
this.server = server;
|
||||
final DatabaseConfig config = server.getServerConfig();
|
||||
this.jaxbPresent = config.getClassLoadConfig().isJavaxJAXBPresent();
|
||||
this.generateDdl = config.isDdlGenerate();
|
||||
this.extraDdl = config.isDdlExtra();
|
||||
this.createOnly = config.isDdlCreateOnly();
|
||||
this.dbSchema = config.getDbSchema();
|
||||
final DatabasePlatform databasePlatform = server.getDatabasePlatform();
|
||||
this.platform = databasePlatform.getPlatform();
|
||||
this.platformName = platform.base().name();
|
||||
if (!config.getTenantMode().isDdlEnabled() && config.isDdlRun()) {
|
||||
log.warn("DDL can't be run on startup with TenantMode " + config.getTenantMode());
|
||||
this.runDdl = false;
|
||||
this.ddlAutoCommit = false;
|
||||
} else {
|
||||
this.runDdl = config.isDdlRun();
|
||||
this.ddlAutoCommit = databasePlatform.isDdlAutoCommit();
|
||||
}
|
||||
this.scriptTransform = createScriptTransform(config.getMigrationConfig());
|
||||
this.baseDir = initBaseDir();
|
||||
}
|
||||
|
||||
private File initBaseDir() {
|
||||
for (String buildDir : BUILD_DIRS) {
|
||||
File dir = new File(buildDir);
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
return new File(".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(boolean online) {
|
||||
generateDdl();
|
||||
if (online) {
|
||||
runDdl();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the DDL drop and create scripts if the properties have been set.
|
||||
*/
|
||||
protected void generateDdl() {
|
||||
if (generateDdl) {
|
||||
if (!createOnly) {
|
||||
writeDrop(getDropFileName());
|
||||
}
|
||||
writeCreate(getCreateFileName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the DDL drop and DDL create scripts if properties have been set.
|
||||
*/
|
||||
protected void runDdl() {
|
||||
if (runDdl) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = obtainConnection();
|
||||
runDdlWith(connection);
|
||||
} finally {
|
||||
JdbcClose.rollback(connection);
|
||||
JdbcClose.close(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runDdlWith(Connection connection) {
|
||||
try {
|
||||
if (dbSchema != null) {
|
||||
createSchemaIfRequired(connection);
|
||||
}
|
||||
runInitSql(connection);
|
||||
runDropSql(connection);
|
||||
runCreateSql(connection);
|
||||
runSeedSql(connection);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading drop/create script from file system", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Connection obtainConnection() {
|
||||
try {
|
||||
return server.getPluginApi().getDataSource().getConnection();
|
||||
} catch (SQLException e) {
|
||||
throw new PersistenceException("Failed to obtain connection to run DDL", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void createSchemaIfRequired(Connection connection) {
|
||||
try {
|
||||
for (String schema : dbSchema.split(",")) {
|
||||
server.getDatabasePlatform().createSchemaIfNotExists(schema, connection);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new PersistenceException("Failed to create DB Schema", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all the DDL statements in the script.
|
||||
*/
|
||||
void runScript(Connection connection, boolean expectErrors, String content, String scriptName) {
|
||||
|
||||
DdlRunner runner = createDdlRunner(expectErrors, scriptName);
|
||||
try {
|
||||
if (expectErrors || ddlAutoCommit) {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
runner.runAll(scriptTransform.transform(content), connection);
|
||||
if (expectErrors || ddlAutoCommit) {
|
||||
connection.setAutoCommit(false);
|
||||
}
|
||||
connection.commit();
|
||||
runner.runNonTransactional(connection);
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new PersistenceException("Failed to run script", e);
|
||||
} finally {
|
||||
JdbcClose.rollback(connection);
|
||||
}
|
||||
}
|
||||
|
||||
private DdlRunner createDdlRunner(boolean expectErrors, String scriptName) {
|
||||
return new DdlRunner(expectErrors, scriptName, platformName);
|
||||
}
|
||||
|
||||
protected void runDropSql(Connection connection) throws IOException {
|
||||
if (!createOnly) {
|
||||
if (extraDdl && jaxbPresent) {
|
||||
String extraApply = ExtraDdlXmlReader.buildExtra(platform, true);
|
||||
if (extraApply != null) {
|
||||
runScript(connection, false, extraApply, "extra-ddl");
|
||||
}
|
||||
}
|
||||
|
||||
if (dropAllContent == null) {
|
||||
dropAllContent = readFile(getDropFileName());
|
||||
}
|
||||
runScript(connection, true, dropAllContent, getDropFileName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void runCreateSql(Connection connection) throws IOException {
|
||||
if (createAllContent == null) {
|
||||
createAllContent = readFile(getCreateFileName());
|
||||
}
|
||||
runScript(connection, false, createAllContent, getCreateFileName());
|
||||
|
||||
if (extraDdl && jaxbPresent) {
|
||||
if (currentModel().isTablePartitioning()) {
|
||||
String extraPartitioning = ExtraDdlXmlReader.buildPartitioning(platform);
|
||||
if (extraPartitioning != null && !extraPartitioning.isEmpty()) {
|
||||
runScript(connection, false, extraPartitioning, "builtin-partitioning-ddl");
|
||||
}
|
||||
}
|
||||
|
||||
String extraApply = ExtraDdlXmlReader.buildExtra(platform, false);
|
||||
if (extraApply != null) {
|
||||
runScript(connection, false, extraApply, "extra-ddl");
|
||||
}
|
||||
|
||||
if (currentModel().isTablePartitioning()) {
|
||||
checkInitialTablePartitions(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if table partitions exist and if not create some. The expectation is that
|
||||
* extra-ddl.xml should have some partition initialisation but this helps people get going.
|
||||
*/
|
||||
private void checkInitialTablePartitions(Connection connection) {
|
||||
DatabasePlatform databasePlatform = server.getDatabasePlatform();
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (MTable table : currentModel.getPartitionedTables()) {
|
||||
String tableName = table.getName();
|
||||
if (!databasePlatform.tablePartitionsExist(connection, tableName)) {
|
||||
log.info("No table partitions for table {}", tableName);
|
||||
PartitionMeta meta = table.getPartitionMeta();
|
||||
String initPart = databasePlatform.tablePartitionInit(tableName, meta.getMode(), meta.getProperty(), table.singlePrimaryKey());
|
||||
sb.append(initPart).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
String initialPartitionSql = sb.toString();
|
||||
if (!initialPartitionSql.isEmpty()) {
|
||||
runScript(connection, false, initialPartitionSql, "initial table partitions");
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
log.error("Error checking initial table partitions", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void runInitSql(Connection connection) throws IOException {
|
||||
runResourceScript(connection, server.getServerConfig().getDdlInitSql());
|
||||
}
|
||||
|
||||
protected void runSeedSql(Connection connection) throws IOException {
|
||||
runResourceScript(connection, server.getServerConfig().getDdlSeedSql());
|
||||
}
|
||||
|
||||
protected void runResourceScript(Connection connection, String sqlScript) throws IOException {
|
||||
if (sqlScript != null) {
|
||||
try (InputStream is = getClassLoader().getResourceAsStream(sqlScript)) {
|
||||
if (is == null) {
|
||||
log.warn("sql script {} was not found as a resource", sqlScript);
|
||||
} else {
|
||||
String content = readContent(new InputStreamReader(is));
|
||||
runScript(connection, false, content, sqlScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the classLoader to use to read sql scripts as resources.
|
||||
*/
|
||||
protected ClassLoader getClassLoader() {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
if (cl == null) {
|
||||
cl = this.getClassLoader();
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
protected void writeDrop(String dropFile) {
|
||||
try {
|
||||
writeFile(dropFile, generateDropAllDdl());
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException("Error generating Drop DDL", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeCreate(String createFile) {
|
||||
try {
|
||||
writeFile(createFile, generateCreateAllDdl());
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException("Error generating Create DDL", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected String generateDropAllDdl() {
|
||||
try {
|
||||
dropAllContent = currentModel().getDropAllDdl();
|
||||
return dropAllContent;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected String generateCreateAllDdl() {
|
||||
try {
|
||||
createAllContent = currentModel().getCreateDdl();
|
||||
return createAllContent;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getDropFileName() {
|
||||
return server.getName() + "-drop-all.sql";
|
||||
}
|
||||
|
||||
protected String getCreateFileName() {
|
||||
return server.getName() + "-create-all.sql";
|
||||
}
|
||||
|
||||
protected CurrentModel currentModel() {
|
||||
if (currentModel == null) {
|
||||
currentModel = new CurrentModel(server);
|
||||
}
|
||||
return currentModel;
|
||||
}
|
||||
|
||||
protected void writeFile(String fileName, String fileContent) throws IOException {
|
||||
File f = new File(baseDir, fileName);
|
||||
try (FileWriter fw = new FileWriter(f)) {
|
||||
fw.write(fileContent);
|
||||
fw.flush();
|
||||
}
|
||||
}
|
||||
|
||||
protected String readFile(String fileName) throws IOException {
|
||||
File f = new File(baseDir, fileName);
|
||||
if (!f.exists()) {
|
||||
return null;
|
||||
}
|
||||
return readContent(new FileReader(f));
|
||||
}
|
||||
|
||||
protected String readContent(Reader reader) throws IOException {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
try (LineNumberReader lineReader = new LineNumberReader(reader)) {
|
||||
String s;
|
||||
while ((s = lineReader.readLine()) != null) {
|
||||
buf.append(s).append("\n");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the ScriptTransform for placeholder key/value replacement.
|
||||
*/
|
||||
private ScriptTransform createScriptTransform(DbMigrationConfig config) {
|
||||
return ScriptTransform.build(config.getRunPlaceholders(), config.getRunPlaceholderMap());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration;
|
||||
|
||||
import io.ebeaninternal.api.SpiDdlGenerator;
|
||||
import io.ebeaninternal.api.SpiDdlGeneratorProvider;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
|
||||
public class DdlGeneratorProvider implements SpiDdlGeneratorProvider {
|
||||
|
||||
@Override
|
||||
public SpiDdlGenerator generator(SpiEbeanServer server) {
|
||||
return new DdlGenerator(server);
|
||||
}
|
||||
}
|
||||
@@ -1,886 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebean.config.DbMigrationConfig;
|
||||
import io.ebean.config.PlatformConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform;
|
||||
import io.ebean.config.dbplatform.cockroach.CockroachPlatform;
|
||||
import io.ebean.config.dbplatform.db2.DB2Platform;
|
||||
import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebean.config.dbplatform.hana.HanaPlatform;
|
||||
import io.ebean.config.dbplatform.hsqldb.HsqldbPlatform;
|
||||
import io.ebean.config.dbplatform.mariadb.MariaDbPlatform;
|
||||
import io.ebean.config.dbplatform.mysql.MySql55Platform;
|
||||
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
||||
import io.ebean.config.dbplatform.nuodb.NuoDbPlatform;
|
||||
import io.ebean.config.dbplatform.oracle.Oracle11Platform;
|
||||
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
||||
import io.ebean.config.dbplatform.postgres.Postgres9Platform;
|
||||
import io.ebean.config.dbplatform.postgres.PostgresPlatform;
|
||||
import io.ebean.config.dbplatform.sqlanywhere.SqlAnywherePlatform;
|
||||
import io.ebean.config.dbplatform.sqlite.SQLitePlatform;
|
||||
import io.ebean.config.dbplatform.sqlserver.SqlServer16Platform;
|
||||
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
|
||||
import io.ebean.dbmigration.DbMigration;
|
||||
import io.ebean.migration.MigrationVersion;
|
||||
import io.ebeaninternal.api.DbOffline;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.Migration;
|
||||
import io.ebeaninternal.dbmigration.migrationreader.MigrationXmlWriter;
|
||||
import io.ebeaninternal.dbmigration.model.CurrentModel;
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
import io.ebeaninternal.dbmigration.model.MigrationModel;
|
||||
import io.ebeaninternal.dbmigration.model.ModelContainer;
|
||||
import io.ebeaninternal.dbmigration.model.ModelDiff;
|
||||
import io.ebeaninternal.dbmigration.model.PlatformDdlWriter;
|
||||
import io.ebeaninternal.extraddl.model.DdlScript;
|
||||
import io.ebeaninternal.extraddl.model.ExtraDdl;
|
||||
import io.ebeaninternal.extraddl.model.ExtraDdlXmlReader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
|
||||
|
||||
/**
|
||||
* Generates DB Migration xml and sql scripts.
|
||||
* <p>
|
||||
* Reads the prior migrations and compares with the current model of the EbeanServer
|
||||
* and generates a migration 'diff' in the form of xml document with the logical schema
|
||||
* changes and a series of sql scripts to apply, rollback the applied changes if necessary
|
||||
* and drop objects (drop tables, drop columns).
|
||||
* </p>
|
||||
* <p>
|
||||
* This does not run the migration or ddl scripts but just generates them.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbMigration migration = DbMigration.create();
|
||||
* migration.setPathToResources("src/main/resources");
|
||||
* migration.setPlatform(Platform.POSTGRES);
|
||||
*
|
||||
* migration.generateMigration();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class DefaultDbMigration implements DbMigration {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger("io.ebean.GenerateMigration");
|
||||
|
||||
private static final String initialVersion = "1.0";
|
||||
|
||||
private static final String GENERATED_COMMENT = "THIS IS A GENERATED FILE - DO NOT MODIFY";
|
||||
|
||||
private boolean logToSystemOut = true;
|
||||
|
||||
/**
|
||||
* Set to true if DefaultDbMigration run with online EbeanServer instance.
|
||||
*/
|
||||
protected final boolean online;
|
||||
|
||||
protected SpiEbeanServer server;
|
||||
|
||||
protected DbMigrationConfig migrationConfig;
|
||||
|
||||
protected String pathToResources = "src/main/resources";
|
||||
|
||||
protected String migrationPath;
|
||||
|
||||
protected DatabasePlatform databasePlatform;
|
||||
|
||||
private boolean vanillaPlatform;
|
||||
|
||||
protected List<Pair> platforms = new ArrayList<>();
|
||||
|
||||
protected DatabaseConfig databaseConfig;
|
||||
|
||||
protected DbConstraintNaming constraintNaming;
|
||||
|
||||
protected Boolean strictMode;
|
||||
protected Boolean includeGeneratedFileComment;
|
||||
protected String header;
|
||||
protected String applyPrefix;
|
||||
protected String version;
|
||||
protected String name;
|
||||
protected String generatePendingDrop;
|
||||
private boolean addForeignKeySkipCheck;
|
||||
private int lockTimeoutSeconds;
|
||||
|
||||
protected boolean includeBuiltInPartitioning = true;
|
||||
|
||||
/**
|
||||
* Create for offline migration generation.
|
||||
*/
|
||||
public DefaultDbMigration() {
|
||||
this.online = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using online EbeanServer.
|
||||
*/
|
||||
public DefaultDbMigration(EbeanServer server) {
|
||||
this.online = true;
|
||||
setServer(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path from the current working directory to the application resources.
|
||||
* <p>
|
||||
* This defaults to maven style 'src/main/resources'.
|
||||
*/
|
||||
@Override
|
||||
public void setPathToResources(String pathToResources) {
|
||||
this.pathToResources = pathToResources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMigrationPath(String migrationPath) {
|
||||
this.migrationPath = migrationPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the server to use to determine the current model.
|
||||
* Typically this is not called explicitly.
|
||||
*/
|
||||
@Override
|
||||
public void setServer(Database database) {
|
||||
this.server = (SpiEbeanServer) database;
|
||||
setServerConfig(server.getServerConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the DatabaseConfig to use. Typically this is not called explicitly.
|
||||
*/
|
||||
@Override
|
||||
public void setServerConfig(DatabaseConfig config) {
|
||||
if (this.databaseConfig == null) {
|
||||
this.databaseConfig = config;
|
||||
}
|
||||
if (migrationConfig == null) {
|
||||
this.migrationConfig = databaseConfig.getMigrationConfig();
|
||||
}
|
||||
if (constraintNaming == null) {
|
||||
this.constraintNaming = databaseConfig.getConstraintNaming();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStrictMode(boolean strictMode) {
|
||||
this.strictMode = strictMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplyPrefix(String applyPrefix) {
|
||||
this.applyPrefix = applyPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddForeignKeySkipCheck(boolean addForeignKeySkipCheck) {
|
||||
this.addForeignKeySkipCheck = addForeignKeySkipCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLockTimeout(int seconds) {
|
||||
this.lockTimeoutSeconds = seconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGeneratePendingDrop(String generatePendingDrop) {
|
||||
this.generatePendingDrop = generatePendingDrop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIncludeGeneratedFileComment(boolean includeGeneratedFileComment) {
|
||||
this.includeGeneratedFileComment = includeGeneratedFileComment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIncludeBuiltInPartitioning(boolean includeBuiltInPartitioning) {
|
||||
this.includeBuiltInPartitioning = includeBuiltInPartitioning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeader(String header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specific platform to generate DDL for.
|
||||
* <p>
|
||||
* If not set this defaults to the platform of the default server.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void setPlatform(Platform platform) {
|
||||
vanillaPlatform = true;
|
||||
setPlatform(getPlatform(platform));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specific platform to generate DDL for.
|
||||
* <p>
|
||||
* If not set this defaults to the platform of the default server.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void setPlatform(DatabasePlatform databasePlatform) {
|
||||
this.databasePlatform = databasePlatform;
|
||||
if (!online) {
|
||||
DbOffline.setPlatform(databasePlatform.getPlatform());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an additional platform to write the migration DDL.
|
||||
* <p>
|
||||
* Use this when you want to generate sql scripts for multiple database platforms
|
||||
* from the migration (e.g. generate migration sql for MySql, Postgres and Oracle).
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void addPlatform(Platform platform, String prefix) {
|
||||
platforms.add(new Pair(getPlatform(platform), prefix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDatabasePlatform(DatabasePlatform databasePlatform, String prefix) {
|
||||
platforms.add(new Pair(databasePlatform, prefix));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the next migration xml file and associated apply and rollback sql scripts.
|
||||
* <p>
|
||||
* This does not run the migration or ddl scripts but just generates them.
|
||||
* </p>
|
||||
* <h3>Example: Run for a single specific platform</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbMigration migration = DbMigration.create();
|
||||
* migration.setPathToResources("src/main/resources");
|
||||
* migration.setPlatform(DbPlatformName.ORACLE);
|
||||
*
|
||||
* migration.generateMigration();
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* <h3>Example: Run migration generating DDL for multiple platforms</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbMigration migration = DbMigration.create();
|
||||
* migration.setPathToResources("src/main/resources");
|
||||
*
|
||||
* migration.addPlatform(DbPlatformName.POSTGRES, "pg");
|
||||
* migration.addPlatform(DbPlatformName.MYSQL, "mysql");
|
||||
* migration.addPlatform(DbPlatformName.ORACLE, "mysql");
|
||||
*
|
||||
* migration.generateMigration();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return the generated migration or null
|
||||
*/
|
||||
@Override
|
||||
public String generateMigration() throws IOException {
|
||||
return generateMigrationFor(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateInitMigration() throws IOException {
|
||||
return generateMigrationFor(true);
|
||||
}
|
||||
|
||||
private String generateMigrationFor(boolean dbinitMigration) throws IOException {
|
||||
|
||||
// use this flag to stop other plugins like full DDL generation
|
||||
if (!online) {
|
||||
DbOffline.setGenerateMigration();
|
||||
if (databasePlatform == null && !platforms.isEmpty()) {
|
||||
// for multiple platform generation the first platform
|
||||
// is used to generate the "logical" model diff
|
||||
setPlatform(platforms.get(0).platform);
|
||||
}
|
||||
}
|
||||
setDefaults();
|
||||
if (!platforms.isEmpty()) {
|
||||
configurePlatforms();
|
||||
}
|
||||
try {
|
||||
Request request = createRequest(dbinitMigration);
|
||||
if (!dbinitMigration) {
|
||||
// repeatable migrations
|
||||
if (platforms.isEmpty()) {
|
||||
generateExtraDdl(request.migrationDir, databasePlatform, request.isTablePartitioning());
|
||||
} else {
|
||||
for (Pair pair : platforms) {
|
||||
PlatformDdlWriter platformWriter = createDdlWriter(pair.platform);
|
||||
File subPath = platformWriter.subPath(request.migrationDir, pair.prefix);
|
||||
generateExtraDdl(subPath, pair.platform, request.isTablePartitioning());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String pendingVersion = generatePendingDrop();
|
||||
if (pendingVersion != null) {
|
||||
return generatePendingDrop(request, pendingVersion);
|
||||
} else {
|
||||
return generateDiff(request);
|
||||
}
|
||||
|
||||
} catch (UnknownResourcePathException e) {
|
||||
logError("ERROR - " + e.getMessage());
|
||||
logError("Check the working directory or change dbMigration.setPathToResources() value?");
|
||||
return null;
|
||||
|
||||
} finally {
|
||||
if (!online) {
|
||||
DbOffline.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the versions containing pending drops.
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPendingDrops() {
|
||||
if (!online) {
|
||||
DbOffline.setGenerateMigration();
|
||||
}
|
||||
setDefaults();
|
||||
try {
|
||||
return createRequest(false).getPendingDrops();
|
||||
} finally {
|
||||
if (!online) {
|
||||
DbOffline.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the configuration for each of the target platforms.
|
||||
*/
|
||||
private void configurePlatforms() {
|
||||
for (Pair pair : platforms) {
|
||||
PlatformConfig config = databaseConfig.newPlatformConfig("dbmigration.platform", pair.prefix);
|
||||
pair.platform.configure(config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate "repeatable" migration scripts.
|
||||
* <p>
|
||||
* These take scrips from extra-ddl.xml (typically views) and outputs "repeatable"
|
||||
* migration scripts (starting with "R__") to be run by FlywayDb or Ebean's own
|
||||
* migration runner.
|
||||
* </p>
|
||||
*/
|
||||
private void generateExtraDdl(File migrationDir, DatabasePlatform dbPlatform, boolean tablePartitioning) throws IOException {
|
||||
|
||||
if (dbPlatform != null) {
|
||||
if (tablePartitioning && includeBuiltInPartitioning) {
|
||||
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.readBuiltinTablePartitioning());
|
||||
}
|
||||
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.readBuiltin());
|
||||
generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.read());
|
||||
}
|
||||
}
|
||||
|
||||
private void generateExtraDdlFor(File migrationDir, DatabasePlatform dbPlatform, ExtraDdl extraDdl) throws IOException {
|
||||
if (extraDdl != null) {
|
||||
List<DdlScript> ddlScript = extraDdl.getDdlScript();
|
||||
for (DdlScript script : ddlScript) {
|
||||
if (!script.isDrop() && matchPlatform(dbPlatform.getPlatform(), script.getPlatforms())) {
|
||||
writeExtraDdl(migrationDir, script);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write (or override) the "repeatable" migration script.
|
||||
*/
|
||||
private void writeExtraDdl(File migrationDir, DdlScript script) throws IOException {
|
||||
|
||||
String fullName = repeatableMigrationName(script.isInit(), script.getName());
|
||||
logger.debug("writing repeatable script {}", fullName);
|
||||
|
||||
File file = new File(migrationDir, fullName);
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
writer.write(script.getValue());
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogToSystemOut(boolean logToSystemOut) {
|
||||
this.logToSystemOut = logToSystemOut;
|
||||
}
|
||||
|
||||
private void logError(String message) {
|
||||
if (logToSystemOut) {
|
||||
System.out.println("DbMigration> " + message);
|
||||
} else {
|
||||
logger.error(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void logInfo(String message, Object value) {
|
||||
if (value != null) {
|
||||
message = String.format(message, value);
|
||||
}
|
||||
if (logToSystemOut) {
|
||||
System.out.println("DbMigration> " + message);
|
||||
} else {
|
||||
logger.info(message);
|
||||
}
|
||||
}
|
||||
|
||||
private String repeatableMigrationName(boolean init, String scriptName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (init) {
|
||||
sb.append("I__");
|
||||
} else {
|
||||
sb.append("R__");
|
||||
}
|
||||
sb.append(scriptName.replace(' ', '_'));
|
||||
sb.append(migrationConfig.getApplySuffix());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the diff migration.
|
||||
*/
|
||||
private String generateDiff(Request request) throws IOException {
|
||||
|
||||
List<String> pendingDrops = request.getPendingDrops();
|
||||
if (!pendingDrops.isEmpty()) {
|
||||
logInfo("Pending un-applied drops in versions %s", pendingDrops);
|
||||
}
|
||||
|
||||
Migration migration = request.createDiffMigration();
|
||||
if (migration == null) {
|
||||
logInfo("no changes detected - no migration written", null);
|
||||
return null;
|
||||
} else {
|
||||
// there were actually changes to write
|
||||
return generateMigration(request, migration, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the migration based on the pendingDrops from a prior version.
|
||||
*/
|
||||
private String generatePendingDrop(Request request, String pendingVersion) throws IOException {
|
||||
|
||||
Migration migration = request.migrationForPendingDrop(pendingVersion);
|
||||
|
||||
String version = generateMigration(request, migration, pendingVersion);
|
||||
|
||||
List<String> pendingDrops = request.getPendingDrops();
|
||||
if (!pendingDrops.isEmpty()) {
|
||||
logInfo("... remaining pending un-applied drops in versions %s", pendingDrops);
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
private Request createRequest(boolean dbinitMigration) {
|
||||
return new Request(dbinitMigration);
|
||||
}
|
||||
|
||||
private class Request {
|
||||
|
||||
final boolean dbinitMigration;
|
||||
final File migrationDir;
|
||||
final File modelDir;
|
||||
final CurrentModel currentModel;
|
||||
final ModelContainer migrated;
|
||||
final ModelContainer current;
|
||||
|
||||
private Request(boolean dbinitMigration) {
|
||||
this.dbinitMigration = dbinitMigration;
|
||||
this.currentModel = new CurrentModel(server, constraintNaming);
|
||||
this.current = currentModel.read();
|
||||
this.migrationDir = getMigrationDirectory(dbinitMigration);
|
||||
if (dbinitMigration) {
|
||||
this.modelDir = null;
|
||||
this.migrated = new ModelContainer();
|
||||
} else {
|
||||
this.modelDir = getModelDirectory(migrationDir);
|
||||
MigrationModel migrationModel = new MigrationModel(modelDir, migrationConfig.getModelSuffix());
|
||||
this.migrated = migrationModel.read(dbinitMigration);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isTablePartitioning() {
|
||||
return current.isTablePartitioning();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next migration version (based on existing migration versions).
|
||||
*/
|
||||
String nextVersion() {
|
||||
// always read the next version using the main migration directory (not dbinit)
|
||||
File migDirectory = getMigrationDirectory(false);
|
||||
File modelDir = getModelDirectory(migDirectory);
|
||||
return LastMigration.nextVersion(migDirectory, modelDir, dbinitMigration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the migration for the pending drops for a given version.
|
||||
*/
|
||||
Migration migrationForPendingDrop(String pendingVersion) {
|
||||
|
||||
Migration migration = migrated.migrationForPendingDrop(pendingVersion);
|
||||
|
||||
// register any remaining pending drops
|
||||
migrated.registerPendingHistoryDropColumns(current);
|
||||
return migration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of versions that have pending un-applied drops.
|
||||
*/
|
||||
public List<String> getPendingDrops() {
|
||||
return migrated.getPendingDrops();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return the diff of the current model to the migration model.
|
||||
*/
|
||||
Migration createDiffMigration() {
|
||||
ModelDiff diff = new ModelDiff(migrated);
|
||||
diff.compareTo(current);
|
||||
return diff.isEmpty() ? null : diff.getMigration();
|
||||
}
|
||||
}
|
||||
|
||||
private String generateMigration(Request request, Migration dbMigration, String dropsFor) throws IOException {
|
||||
|
||||
String fullVersion = getFullVersion(request.nextVersion(), dropsFor);
|
||||
|
||||
logInfo("generating migration:%s", fullVersion);
|
||||
if (!request.dbinitMigration && !writeMigrationXml(dbMigration, request.modelDir, fullVersion)) {
|
||||
logError("migration already exists, not generating DDL");
|
||||
return null;
|
||||
} else {
|
||||
if (!platforms.isEmpty()) {
|
||||
writeExtraPlatformDdl(fullVersion, request.currentModel, dbMigration, request.migrationDir);
|
||||
|
||||
} else if (databasePlatform != null) {
|
||||
// writer needs the current model to provide table/column details for
|
||||
// history ddl generation (triggers, history tables etc)
|
||||
DdlOptions options = new DdlOptions(addForeignKeySkipCheck);
|
||||
DdlWrite write = new DdlWrite(new MConfiguration(), request.current, options);
|
||||
PlatformDdlWriter writer = createDdlWriter(databasePlatform);
|
||||
writer.processMigration(dbMigration, write, request.migrationDir, fullVersion);
|
||||
}
|
||||
return fullVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the next pending drop changeSet should be generated as the next migration.
|
||||
*/
|
||||
private String generatePendingDrop() {
|
||||
|
||||
String nextDrop = System.getProperty("ddl.migration.pendingDropsFor");
|
||||
if (nextDrop != null) {
|
||||
return nextDrop;
|
||||
}
|
||||
return generatePendingDrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full version for the migration being generated.
|
||||
* <p>
|
||||
* The full version can contain a comment suffix after a "__" double underscore.
|
||||
*/
|
||||
private String getFullVersion(String nextVersion, String dropsFor) {
|
||||
|
||||
String version = getVersion();
|
||||
if (version == null) {
|
||||
version = (nextVersion != null) ? nextVersion : initialVersion;
|
||||
}
|
||||
|
||||
String fullVersion = migrationConfig.getApplyPrefix() + version;
|
||||
String name = getName();
|
||||
if (name != null) {
|
||||
fullVersion += "__" + toUnderScore(name);
|
||||
|
||||
} else if (dropsFor != null) {
|
||||
fullVersion += "__" + toUnderScore("dropsFor_" + MigrationVersion.trim(dropsFor));
|
||||
|
||||
} else if (version.equals(initialVersion)) {
|
||||
fullVersion += "__initial";
|
||||
}
|
||||
return fullVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace spaces with underscores.
|
||||
*/
|
||||
private String toUnderScore(String name) {
|
||||
return name.replace(' ', '_');
|
||||
}
|
||||
|
||||
/**
|
||||
* Write any extra platform ddl.
|
||||
*/
|
||||
private void writeExtraPlatformDdl(String fullVersion, CurrentModel currentModel, Migration dbMigration, File writePath) throws IOException {
|
||||
|
||||
DdlOptions options = new DdlOptions(addForeignKeySkipCheck);
|
||||
for (Pair pair : platforms) {
|
||||
DdlWrite platformBuffer = new DdlWrite(new MConfiguration(), currentModel.read(), options);
|
||||
PlatformDdlWriter platformWriter = createDdlWriter(pair.platform);
|
||||
File subPath = platformWriter.subPath(writePath, pair.prefix);
|
||||
platformWriter.processMigration(dbMigration, platformBuffer, subPath, fullVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private PlatformDdlWriter createDdlWriter(DatabasePlatform platform) {
|
||||
return new PlatformDdlWriter(platform, databaseConfig, migrationConfig, lockTimeoutSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the migration xml.
|
||||
*/
|
||||
private boolean writeMigrationXml(Migration dbMigration, File resourcePath, String fullVersion) {
|
||||
|
||||
String modelFile = fullVersion + migrationConfig.getModelSuffix();
|
||||
File file = new File(resourcePath, modelFile);
|
||||
if (file.exists()) {
|
||||
return false;
|
||||
}
|
||||
String comment = Boolean.TRUE.equals(includeGeneratedFileComment) ? GENERATED_COMMENT : null;
|
||||
MigrationXmlWriter xmlWriter = new MigrationXmlWriter(comment);
|
||||
xmlWriter.write(dbMigration, file);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default server and platform if necessary.
|
||||
*/
|
||||
private void setDefaults() {
|
||||
if (server == null) {
|
||||
setServer(DB.getDefault());
|
||||
}
|
||||
if (vanillaPlatform || databasePlatform == null) {
|
||||
// not explicitly set so use the platform of the server
|
||||
databasePlatform = server.getDatabasePlatform();
|
||||
}
|
||||
if (migrationConfig != null) {
|
||||
if (strictMode != null) {
|
||||
migrationConfig.setStrictMode(strictMode);
|
||||
}
|
||||
if (applyPrefix != null) {
|
||||
migrationConfig.setApplyPrefix(applyPrefix);
|
||||
}
|
||||
if (migrationPath != null) {
|
||||
migrationConfig.setMigrationPath(migrationPath);
|
||||
}
|
||||
if (header != null) {
|
||||
migrationConfig.setDdlHeader(header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the migration version (typically FlywayDb compatible).
|
||||
* <p>
|
||||
* Example: 1.1.1_2
|
||||
* <p>
|
||||
* The version is expected to be the combination of the current pom version plus
|
||||
* a 'feature' id. The combined version must be unique and ordered to work with
|
||||
* FlywayDb so each developer sets a unique version so that the migration script
|
||||
* generated is unique (typically just prior to being submitted as a merge request).
|
||||
*/
|
||||
private String getVersion() {
|
||||
String envVersion = readEnvironment("ddl.migration.version");
|
||||
if (!isEmpty(envVersion)) {
|
||||
return envVersion.trim();
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the migration name which is short description text that can be appended to
|
||||
* the migration version to become the ddl script file name.
|
||||
* <p>
|
||||
* So if the name is "a foo table" then the ddl script file could be:
|
||||
* "1.1.1_2__a-foo-table.sql"
|
||||
* </p>
|
||||
* <p>
|
||||
* When the DB migration relates to a git feature (merge request) then this description text
|
||||
* is a short description of the feature.
|
||||
* </p>
|
||||
*/
|
||||
private String getName() {
|
||||
String envName = readEnvironment("ddl.migration.name");
|
||||
if (!isEmpty(envName)) {
|
||||
return envName.trim();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the string is null or empty.
|
||||
*/
|
||||
private boolean isEmpty(String val) {
|
||||
return val == null || val.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the system or environment property.
|
||||
*/
|
||||
private String readEnvironment(String key) {
|
||||
|
||||
String val = System.getProperty(key);
|
||||
if (val == null) {
|
||||
val = System.getenv(key);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the main migration directory.
|
||||
*/
|
||||
File getMigrationDirectory() {
|
||||
return getMigrationDirectory(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the file path to write the xml and sql to.
|
||||
*/
|
||||
File getMigrationDirectory(boolean dbinitMigration) {
|
||||
|
||||
// path to src/main/resources in typical maven project
|
||||
File resourceRootDir = new File(pathToResources);
|
||||
if (!resourceRootDir.exists()) {
|
||||
String msg = String.format("Error - path to resources %s does not exist. Absolute path is %s", pathToResources, resourceRootDir.getAbsolutePath());
|
||||
throw new UnknownResourcePathException(msg);
|
||||
}
|
||||
String resourcePath = migrationConfig.getMigrationPath(dbinitMigration);
|
||||
|
||||
// expect to be a path to something like - src/main/resources/dbmigration/model
|
||||
File path = new File(resourceRootDir, resourcePath);
|
||||
if (!path.exists()) {
|
||||
if (!path.mkdirs()) {
|
||||
logInfo("Warning - Unable to ensure migration directory exists at %s", path.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the model directory (relative to the migration directory).
|
||||
*/
|
||||
private File getModelDirectory(File migrationDirectory) {
|
||||
String modelPath = migrationConfig.getModelPath();
|
||||
if (modelPath == null || modelPath.isEmpty()) {
|
||||
return migrationDirectory;
|
||||
}
|
||||
File modelDir = new File(migrationDirectory, migrationConfig.getModelPath());
|
||||
if (!modelDir.exists() && !modelDir.mkdirs()) {
|
||||
logInfo("Warning - Unable to ensure migration model directory exists at %s", modelDir.getAbsolutePath());
|
||||
}
|
||||
return modelDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DatabasePlatform given the platform key.
|
||||
*/
|
||||
protected DatabasePlatform getPlatform(Platform platform) {
|
||||
switch (platform) {
|
||||
case H2:
|
||||
return new H2Platform();
|
||||
case HSQLDB:
|
||||
return new HsqldbPlatform();
|
||||
case POSTGRES9:
|
||||
return new Postgres9Platform();
|
||||
case POSTGRES:
|
||||
return new PostgresPlatform();
|
||||
case MARIADB:
|
||||
return new MariaDbPlatform();
|
||||
case MYSQL55:
|
||||
return new MySql55Platform();
|
||||
case MYSQL:
|
||||
return new MySqlPlatform();
|
||||
case ORACLE:
|
||||
return new OraclePlatform();
|
||||
case ORACLE11:
|
||||
return new Oracle11Platform();
|
||||
case SQLANYWHERE:
|
||||
return new SqlAnywherePlatform();
|
||||
case SQLSERVER16:
|
||||
return new SqlServer16Platform();
|
||||
case SQLSERVER17:
|
||||
return new SqlServer17Platform();
|
||||
case SQLSERVER:
|
||||
throw new IllegalArgumentException("Please choose the more specific SQLSERVER16 or SQLSERVER17 platform. Refer to issue #1340 for details");
|
||||
case DB2:
|
||||
return new DB2Platform();
|
||||
case SQLITE:
|
||||
return new SQLitePlatform();
|
||||
case HANA:
|
||||
return new HanaPlatform();
|
||||
case NUODB:
|
||||
return new NuoDbPlatform();
|
||||
case COCKROACH:
|
||||
return new CockroachPlatform();
|
||||
case CLICKHOUSE:
|
||||
return new ClickHousePlatform();
|
||||
|
||||
case GENERIC:
|
||||
return new DatabasePlatform();
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Platform missing? " + platform);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds a platform and prefix. Used to generate multiple platform specific DDL
|
||||
* for a single migration.
|
||||
*/
|
||||
static class Pair {
|
||||
|
||||
/**
|
||||
* The platform to generate the DDL for.
|
||||
*/
|
||||
final DatabasePlatform platform;
|
||||
|
||||
/**
|
||||
* A prefix included into the file/resource names indicating the platform.
|
||||
*/
|
||||
final String prefix;
|
||||
|
||||
Pair(DatabasePlatform platform, String prefix) {
|
||||
this.platform = platform;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.ebean.migration.MigrationVersion;
|
||||
|
||||
/**
|
||||
* Utility to determine the last sql migration version and next version.
|
||||
*/
|
||||
class LastMigration {
|
||||
|
||||
private static final String SQL = ".sql";
|
||||
|
||||
private static final String MODEL_XML = ".model.xml";
|
||||
|
||||
/**
|
||||
* Return the next migation version given the migration directory.
|
||||
*/
|
||||
static String nextVersion(File migDir, File modelDir, boolean dbinitMigration) {
|
||||
|
||||
String last = lastVersion(migDir, modelDir);
|
||||
if (last == null) {
|
||||
return null;
|
||||
}
|
||||
return (dbinitMigration) ? last : MigrationVersion.parse(last).nextVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last migation version given the migration directory.
|
||||
*/
|
||||
static String lastVersion(File migDirectory, File modelDir) {
|
||||
|
||||
List<MigrationVersion> versions = new ArrayList<>();
|
||||
|
||||
File[] sqlFiles = migDirectory.listFiles(pathname -> includeSqlFile(pathname.getName().toLowerCase()));
|
||||
if (sqlFiles != null) {
|
||||
for (File file : sqlFiles) {
|
||||
versions.add(trimAndParse(file.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
if (modelDir != null) {
|
||||
File[] xmlFiles = modelDir.listFiles(pathname -> includeModelFile(pathname.getName().toLowerCase()));
|
||||
if (xmlFiles != null) {
|
||||
for (File file : xmlFiles) {
|
||||
versions.add(trimAndParse(file.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(versions);
|
||||
if (!versions.isEmpty()) {
|
||||
return versions.get(versions.size() - 1).asString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean includeSqlFile(String lowerFileName) {
|
||||
return !lowerFileName.startsWith("r") && !lowerFileName.startsWith("i") && lowerFileName.endsWith(SQL);
|
||||
}
|
||||
|
||||
private static boolean includeModelFile(String lowerFileName) {
|
||||
return lowerFileName.endsWith(MODEL_XML);
|
||||
}
|
||||
|
||||
private static MigrationVersion trimAndParse(String name) {
|
||||
if (name.endsWith(SQL)) {
|
||||
name = name.substring(0, name.length() - 4);
|
||||
}
|
||||
if (name.endsWith(MODEL_XML)) {
|
||||
name = name.substring(0, name.length() - 10);
|
||||
}
|
||||
return MigrationVersion.parse(name);
|
||||
}
|
||||
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration;
|
||||
|
||||
/**
|
||||
* Exception when db migration resource path does not exist.
|
||||
* <p>
|
||||
* Typically the working directory or pathToResources is incorrect.
|
||||
* </p>
|
||||
*/
|
||||
public class UnknownResourcePathException extends RuntimeException {
|
||||
|
||||
public UnknownResourcePathException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.BaseTableDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AddTableComment;
|
||||
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.ChangeSet;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class BaseDdlHandler implements DdlHandler {
|
||||
|
||||
protected final TableDdl tableDdl;
|
||||
|
||||
public BaseDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
this(config, platformDdl, new BaseTableDdl(config, platformDdl));
|
||||
}
|
||||
|
||||
protected BaseDdlHandler(DatabaseConfig config, PlatformDdl platformDdl, TableDdl tableDdl) {
|
||||
this.tableDdl = tableDdl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, ChangeSet changeSet) throws IOException {
|
||||
|
||||
List<Object> changeSetChildren = changeSet.getChangeSetChildren();
|
||||
for (Object change : changeSetChildren) {
|
||||
if (change instanceof CreateTable) {
|
||||
generate(writer, (CreateTable) change);
|
||||
}
|
||||
}
|
||||
for (Object change : changeSetChildren) {
|
||||
if (change instanceof CreateTable) {
|
||||
// ignore
|
||||
} else if (change instanceof DropTable) {
|
||||
generate(writer, (DropTable) change);
|
||||
} else if (change instanceof AddTableComment) {
|
||||
generate(writer, (AddTableComment) change);
|
||||
} else if (change instanceof CreateIndex) {
|
||||
generate(writer, (CreateIndex) change);
|
||||
} else if (change instanceof DropIndex) {
|
||||
generate(writer, (DropIndex) change);
|
||||
} else if (change instanceof AddColumn) {
|
||||
generate(writer, (AddColumn) change);
|
||||
} else if (change instanceof DropColumn) {
|
||||
generate(writer, (DropColumn) change);
|
||||
} else if (change instanceof AlterColumn) {
|
||||
generate(writer, (AlterColumn) change);
|
||||
} else if (change instanceof AddHistoryTable) {
|
||||
generate(writer, (AddHistoryTable) change);
|
||||
} else if (change instanceof DropHistoryTable) {
|
||||
generate(writer, (DropHistoryTable) change);
|
||||
} else if (change instanceof AddUniqueConstraint) {
|
||||
generate(writer, (AddUniqueConstraint) change);
|
||||
} else if (change instanceof AlterForeignKey) {
|
||||
generate(writer, (AlterForeignKey) change);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported change: " + change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
tableDdl.generateProlog(write);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateEpilog(DdlWrite write) throws IOException {
|
||||
tableDdl.generateEpilog(write);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateTable createTable) throws IOException {
|
||||
tableDdl.generate(writer, createTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropTable dropTable) throws IOException {
|
||||
tableDdl.generate(writer, dropTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException {
|
||||
tableDdl.generate(writer, addTableComment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
tableDdl.generate(writer, addColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
tableDdl.generate(writer, dropColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
tableDdl.generate(writer, alterColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
tableDdl.generate(writer, addHistoryTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
tableDdl.generate(writer, dropHistoryTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateIndex createIndex) throws IOException {
|
||||
tableDdl.generate(writer, createIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropIndex dropIndex) throws IOException {
|
||||
tableDdl.generate(writer, dropIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException {
|
||||
tableDdl.generate(writer, constraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException {
|
||||
tableDdl.generate(writer, alterForeignKey);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Write DDL for AddColumn , DropColumn or AlterColumn.
|
||||
*/
|
||||
public interface ColumnDdl {
|
||||
|
||||
/**
|
||||
* Write the add column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the drop column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the alter column changes.
|
||||
*/
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Buffer to append generated DDL to.
|
||||
*/
|
||||
public interface DdlBuffer {
|
||||
|
||||
/**
|
||||
* Return the configuration (default tablespaces etc).
|
||||
*/
|
||||
MConfiguration getConfiguration();
|
||||
|
||||
/**
|
||||
* Return true if the buffer is empty.
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Append a statement allowing for null or empty statements.
|
||||
*/
|
||||
DdlBuffer appendStatement(String content) throws IOException;
|
||||
|
||||
/**
|
||||
* Append DDL content to the buffer.
|
||||
*/
|
||||
DdlBuffer append(String content) throws IOException;
|
||||
|
||||
/**
|
||||
* Append DDL content to the buffer with space padding.
|
||||
*/
|
||||
DdlBuffer append(String type, int space) throws IOException;
|
||||
|
||||
/**
|
||||
* Append a value that is potentially null or empty and proceed it with a space if so.
|
||||
*/
|
||||
DdlBuffer appendWithSpace(String foreignKeyRestrict) throws IOException;
|
||||
|
||||
/**
|
||||
* Append new line character to the buffer.
|
||||
*/
|
||||
DdlBuffer newLine() throws IOException;
|
||||
|
||||
/**
|
||||
* Append the end of statement content.
|
||||
*/
|
||||
DdlBuffer endOfStatement() throws IOException;
|
||||
|
||||
/**
|
||||
* End of a change - add some whitespace.
|
||||
*/
|
||||
DdlBuffer end() throws IOException;
|
||||
|
||||
/**
|
||||
* Return the buffer content.
|
||||
*/
|
||||
String getBuffer();
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AddTableComment;
|
||||
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.ChangeSet;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DDL generation interface.
|
||||
*/
|
||||
public interface DdlHandler {
|
||||
|
||||
void generate(DdlWrite writer, ChangeSet changeSet) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, CreateTable createTable) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, DropTable dropTable) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, CreateIndex createIndex) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, DropIndex dropIndex) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException;
|
||||
|
||||
void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException;
|
||||
|
||||
void generateProlog(DdlWrite write) throws IOException;
|
||||
|
||||
void generateEpilog(DdlWrite write) throws IOException;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
/**
|
||||
* Options used when generated DDL.
|
||||
*/
|
||||
public class DdlOptions {
|
||||
|
||||
private boolean foreignKeySkipCheck;
|
||||
|
||||
public DdlOptions(boolean foreignKeySkipCheck) {
|
||||
this.foreignKeySkipCheck = foreignKeySkipCheck;
|
||||
}
|
||||
|
||||
public DdlOptions() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if ADD FOREIGN KEY should use a skip check option.
|
||||
*/
|
||||
public boolean isForeignKeySkipCheck() {
|
||||
return foreignKeySkipCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if ADD FOREIGN KEY should use a skip check option.
|
||||
*/
|
||||
public void setForeignKeySkipCheck(boolean foreignKeySkipCheck) {
|
||||
this.foreignKeySkipCheck = foreignKeySkipCheck;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.BaseDdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
import io.ebeaninternal.dbmigration.model.ModelContainer;
|
||||
|
||||
/**
|
||||
* Write context holding the buffers for both apply and rollback DDL.
|
||||
*/
|
||||
public class DdlWrite {
|
||||
|
||||
private final ModelContainer currentModel;
|
||||
|
||||
private final DdlBuffer applyDropDependencies;
|
||||
|
||||
private final DdlBuffer apply;
|
||||
|
||||
private final DdlBuffer applyForeignKeys;
|
||||
|
||||
private final DdlBuffer applyHistoryView;
|
||||
|
||||
private final DdlBuffer applyHistoryTrigger;
|
||||
|
||||
private final DdlBuffer dropAllForeignKeys;
|
||||
|
||||
private final DdlBuffer dropAll;
|
||||
|
||||
private final DdlOptions options;
|
||||
|
||||
/**
|
||||
* Create without any configuration or current model (no history support).
|
||||
*/
|
||||
public DdlWrite() {
|
||||
this(new MConfiguration(), new ModelContainer(), new DdlOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create with a configuration.
|
||||
*/
|
||||
public DdlWrite(MConfiguration configuration, ModelContainer currentModel, DdlOptions options) {
|
||||
this.currentModel = currentModel;
|
||||
this.applyDropDependencies = new BaseDdlBuffer(configuration);
|
||||
this.apply = new BaseDdlBuffer(configuration);
|
||||
this.applyForeignKeys = new BaseDdlBuffer(configuration);
|
||||
this.applyHistoryView = new BaseDdlBuffer(configuration);
|
||||
this.applyHistoryTrigger = new BaseDdlBuffer(configuration);
|
||||
this.dropAllForeignKeys = new BaseDdlBuffer(configuration);
|
||||
this.dropAll = new BaseDdlBuffer(configuration);
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DDL options.
|
||||
*/
|
||||
public DdlOptions getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Table information from the current model.
|
||||
* <p>
|
||||
* This is typically required for the history support (used to determine the list of columns
|
||||
* included in the history when creating or recreating the associated trigger/stored procedure).
|
||||
* </p>
|
||||
*/
|
||||
public MTable getTable(String tableName) {
|
||||
return currentModel.getTable(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the apply buffers are all empty.
|
||||
*/
|
||||
public boolean isApplyEmpty() {
|
||||
return apply.getBuffer().isEmpty()
|
||||
&& applyForeignKeys.getBuffer().isEmpty()
|
||||
&& applyHistoryView.getBuffer().isEmpty()
|
||||
&& applyHistoryTrigger.getBuffer().isEmpty()
|
||||
&& applyDropDependencies.getBuffer().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that APPLY DDL is written to.
|
||||
*/
|
||||
public DdlBuffer apply() {
|
||||
return apply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that executes early to drop dependencies like views etc.
|
||||
*/
|
||||
public DdlBuffer applyDropDependencies() {
|
||||
return applyDropDependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that APPLY DDL is written to for foreign keys and their associated indexes.
|
||||
* <p>
|
||||
* Statements added to this buffer are executed after all the normal apply statements and
|
||||
* typically 'add foreign key' is added to this buffer.
|
||||
*/
|
||||
public DdlBuffer applyForeignKeys() {
|
||||
return applyForeignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that apply history-view DDL is written to.
|
||||
*/
|
||||
public DdlBuffer applyHistoryView() {
|
||||
return applyHistoryView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that apply history-trigger DDL is written to.
|
||||
*/
|
||||
public DdlBuffer applyHistoryTrigger() {
|
||||
return applyHistoryTrigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer used for the 'drop all DDL' for dropping foreign keys and associated indexes.
|
||||
*/
|
||||
public DdlBuffer dropAllForeignKeys() {
|
||||
return dropAllForeignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer used for the 'drop all DDL' to drop tables, views and history triggers etc.
|
||||
*/
|
||||
public DdlBuffer dropAll() {
|
||||
return dropAll;
|
||||
}
|
||||
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.ClickHouseDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.CockroachDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.DB2Ddl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.H2Ddl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.HanaColumnStoreDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.HsqldbDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.MariaDbDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.MySqlDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.NuoDbDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.OracleDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.Postgres9Ddl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PostgresDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.SQLiteDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.SqlServerDdl;
|
||||
|
||||
/**
|
||||
* Builds platform specific DDL handler.
|
||||
*/
|
||||
public class PlatformDdlBuilder {
|
||||
|
||||
/**
|
||||
* Return platform specific DDL handler.
|
||||
*/
|
||||
public static PlatformDdl create(DatabasePlatform platform) {
|
||||
|
||||
switch (platform.getPlatform()) {
|
||||
case H2:
|
||||
return new H2Ddl(platform);
|
||||
case DB2:
|
||||
return new DB2Ddl(platform);
|
||||
case MARIADB:
|
||||
return new MariaDbDdl(platform);
|
||||
case MYSQL55:
|
||||
case MYSQL:
|
||||
return new MySqlDdl(platform);
|
||||
case HSQLDB:
|
||||
return new HsqldbDdl(platform);
|
||||
case NUODB:
|
||||
return new NuoDbDdl(platform);
|
||||
case ORACLE:
|
||||
case ORACLE11:
|
||||
return new OracleDdl(platform);
|
||||
case SQLITE:
|
||||
return new SQLiteDdl(platform);
|
||||
case POSTGRES9:
|
||||
return new Postgres9Ddl(platform);
|
||||
case POSTGRES:
|
||||
return new PostgresDdl(platform);
|
||||
case COCKROACH:
|
||||
return new CockroachDdl(platform);
|
||||
case SQLSERVER16:
|
||||
case SQLSERVER17:
|
||||
case SQLSERVER:
|
||||
return new SqlServerDdl(platform);
|
||||
case HANA:
|
||||
return new HanaColumnStoreDdl(platform);
|
||||
case CLICKHOUSE:
|
||||
return new ClickHouseDdl(platform);
|
||||
default:
|
||||
return new PlatformDdl(platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AddTableComment;
|
||||
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Write table DDL.
|
||||
*/
|
||||
public interface TableDdl {
|
||||
|
||||
/**
|
||||
* Generate the create table change.
|
||||
*/
|
||||
void generate(DdlWrite writer, CreateTable createTable) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the drop column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropTable dropTable) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the add column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the alter column changes.
|
||||
*/
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the drop column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the AddTableComment change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the AddHistoryTable change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the DropHistoryTable change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
|
||||
|
||||
/**
|
||||
* Generate the create index change.
|
||||
*/
|
||||
void generate(DdlWrite writer, CreateIndex createIndex) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the drop index change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropIndex dropIndex) throws IOException;
|
||||
|
||||
/**
|
||||
* Write add unique constraint.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes alter foreign key statements.
|
||||
*/
|
||||
void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException;
|
||||
|
||||
/**
|
||||
* Generate any extra DDL such as stored procedures or TableValueParameters.
|
||||
*/
|
||||
void generateProlog(DdlWrite write) throws IOException;
|
||||
|
||||
/**
|
||||
* Generate any extra DDL such as regeneration of history triggers.
|
||||
*/
|
||||
void generateEpilog(DdlWrite write) throws IOException;
|
||||
}
|
||||
-225
@@ -1,225 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
|
||||
private static final Pattern ARRAY_PATTERN = Pattern.compile("(\\w+)\\s*\\[\\s*\\]\\s*(\\(\\d+\\))?", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public AbstractHanaDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.addColumn = "add (";
|
||||
this.addColumnSuffix = ")";
|
||||
this.alterColumn = "alter (";
|
||||
this.alterColumnSuffix = ")";
|
||||
this.columnDropDefault = " default null";
|
||||
this.columnSetDefault = " default";
|
||||
this.columnSetNotnull = " not null";
|
||||
this.columnSetNull = " null";
|
||||
this.dropColumn = "drop (";
|
||||
this.dropColumnSuffix = ")";
|
||||
this.dropConstraintIfExists = "drop constraint ";
|
||||
this.dropIndexIfExists = "drop index ";
|
||||
this.dropSequenceIfExists = "drop sequence ";
|
||||
this.dropTableCascade = " cascade";
|
||||
this.dropTableIfExists = "drop table ";
|
||||
this.fallbackArrayType = "nvarchar(1000)";
|
||||
this.historyDdl = new HanaHistoryDdl();
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String currentType = alter.getCurrentType();
|
||||
String type = alter.getType() != null ? alter.getType() : currentType;
|
||||
type = convert(type);
|
||||
currentType = convert(currentType);
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String notnullClause = notnull ? " not null" : "";
|
||||
String defaultValue = DdlHelp.isDropDefault(alter.getDefaultValue()) ? "null"
|
||||
: (alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue());
|
||||
String defaultValueClause = (defaultValue == null || defaultValue.isEmpty()) ? "" : " default " + defaultValue;
|
||||
|
||||
try {
|
||||
DdlBuffer buffer = new BaseDdlBuffer(null);
|
||||
if (!isConvertible(currentType, type)) {
|
||||
// add an intermediate conversion if possible
|
||||
if (isNumberType(currentType)) {
|
||||
// numbers can always be converted to decimal
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
|
||||
.append(" decimal ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix)
|
||||
.endOfStatement();
|
||||
|
||||
} else if (isStringType(currentType)) {
|
||||
// strings can always be converted to nclob
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
|
||||
.append(" nclob ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix)
|
||||
.endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
|
||||
.append(" ").append(type).append(defaultValueClause).append(notnullClause).append(alterColumnSuffix);
|
||||
|
||||
return buffer.getBuffer();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlHandler createDdlHandler(DatabaseConfig config) {
|
||||
return new HanaDdlHandler(config, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String convertArrayType(String logicalArrayType) {
|
||||
Matcher matcher = ARRAY_PATTERN.matcher(logicalArrayType);
|
||||
if (matcher.matches()) {
|
||||
return convert(matcher.group(1)) + " array" + (matcher.group(2) == null ? "" : matcher.group(2));
|
||||
} else {
|
||||
return fallbackArrayType;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
|
||||
if (nullableColumns == null || nullableColumns.length == 0) {
|
||||
return super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
|
||||
} else {
|
||||
return "-- cannot create unique index \"" + uqName + "\" on table \"" + tableName + "\" with nullable columns";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
DdlBuffer buffer = new BaseDdlBuffer(null);
|
||||
try {
|
||||
buffer.append("delimiter $$").newLine();
|
||||
buffer.append("do").newLine();
|
||||
buffer.append("begin").newLine();
|
||||
buffer.append("declare exit handler for sql_error_code 397 begin end").endOfStatement();
|
||||
buffer.append("exec 'alter table ").append(tableName).append(" ").append(dropUniqueConstraint).append(" ")
|
||||
.append(maxConstraintName(uniqueConstraintName)).append("'").endOfStatement();
|
||||
buffer.append("end").endOfStatement();
|
||||
buffer.append("$$");
|
||||
return buffer.getBuffer();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
return alterTableDropUniqueConstraint(tableName, constraintName);
|
||||
}
|
||||
|
||||
/**
|
||||
* It is rather complex to delete a column on HANA as there must not exist any
|
||||
* foreign keys. That's why we call a user stored procedure here
|
||||
*/
|
||||
@Override
|
||||
public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')")
|
||||
.endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a data type can be converted to another data type. Data types can't
|
||||
* be converted if the target type has a lower precision than the source type.
|
||||
*
|
||||
* @param sourceType The source data type
|
||||
* @param targetType the target data type
|
||||
* @return {@code true} if the type can be converted, {@code false} otherwise
|
||||
*/
|
||||
private boolean isConvertible(String sourceType, String targetType) {
|
||||
if (Objects.equals(sourceType, targetType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sourceType == null || targetType == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ("bigint".equals(sourceType)) {
|
||||
if ("integer".equals(targetType) || "smallint".equals(targetType) || "tinyint".equals(targetType)) {
|
||||
return false;
|
||||
}
|
||||
} else if ("integer".equals(sourceType)) {
|
||||
if ("smallint".equals(targetType) || "tinyint".equals(targetType)) {
|
||||
return false;
|
||||
}
|
||||
} else if ("smallint".equals(sourceType)) {
|
||||
if ("tinyint".equals(targetType)) {
|
||||
return false;
|
||||
}
|
||||
} else if ("double".equals(sourceType)) {
|
||||
if ("real".equals(targetType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DbPlatformType dbPlatformSourceType = DbPlatformType.parse(sourceType);
|
||||
|
||||
if ("float".equals(dbPlatformSourceType.getName())) {
|
||||
if ("real".equals(targetType)) {
|
||||
return false;
|
||||
}
|
||||
} else if ("varchar".equals(dbPlatformSourceType.getName()) || "nvarchar".equals(dbPlatformSourceType.getName())) {
|
||||
DbPlatformType dbPlatformTargetType = DbPlatformType.parse(targetType);
|
||||
if ("varchar".equals(dbPlatformTargetType.getName()) || "nvarchar".equals(dbPlatformTargetType.getName())) {
|
||||
if (dbPlatformSourceType.getDefaultLength() > dbPlatformTargetType.getDefaultLength()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if ("decimal".equals(dbPlatformSourceType.getName())) {
|
||||
DbPlatformType dbPlatformTargetType = DbPlatformType.parse(targetType);
|
||||
if ("decimal".equals(dbPlatformTargetType.getName())) {
|
||||
if (dbPlatformSourceType.getDefaultLength() > dbPlatformTargetType.getDefaultLength()
|
||||
|| dbPlatformSourceType.getDefaultScale() > dbPlatformTargetType.getDefaultScale()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isNumberType(String type) {
|
||||
return type != null
|
||||
&& ("bigint".equals(type) || "integer".equals(type) || "smallint".equals(type) || "tinyint".equals(type)
|
||||
|| type.startsWith("float") || "real".equals(type) || "double".equals(type) || type.startsWith("decimal"));
|
||||
}
|
||||
|
||||
private boolean isStringType(String type) {
|
||||
return type != null
|
||||
&& (type.startsWith("varchar") || type.startsWith("nvarchar") || "clob".equals(type) || "nclob".equals(type));
|
||||
}
|
||||
}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Base implementation of DdlBuffer using an underlying writer.
|
||||
*/
|
||||
public class BaseDdlBuffer implements DdlBuffer {
|
||||
|
||||
protected final StringWriter writer;
|
||||
|
||||
protected final MConfiguration configuration;
|
||||
|
||||
public BaseDdlBuffer(MConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.writer = new StringWriter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MConfiguration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return writer.getBuffer().length() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer appendWithSpace(String foreignKeyRestrict) throws IOException {
|
||||
if (foreignKeyRestrict != null && !foreignKeyRestrict.isEmpty()) {
|
||||
writer.append(" ").append(foreignKeyRestrict);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer appendStatement(String content) throws IOException {
|
||||
if (content != null && !content.isEmpty()) {
|
||||
writer.append(content);
|
||||
endOfStatement();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer append(String content) throws IOException {
|
||||
writer.append(content);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer append(String content, int space) throws IOException {
|
||||
writer.append(content);
|
||||
appendSpace(space, content);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void appendSpace(int max, String content) throws IOException {
|
||||
int space = max - content.length();
|
||||
if (space > 0) {
|
||||
for (int i = 0; i < space; i++) {
|
||||
append(" ");
|
||||
}
|
||||
}
|
||||
append(" ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer endOfStatement() throws IOException {
|
||||
writer.append(";\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to demarcate the end of a series of statements.
|
||||
* This should be just whitespace or a sql comment.
|
||||
*/
|
||||
@Override
|
||||
public DdlBuffer end() throws IOException {
|
||||
if (!isEmpty()) {
|
||||
writer.append("\n");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer newLine() throws IOException {
|
||||
writer.append("\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBuffer() {
|
||||
return writer.toString();
|
||||
}
|
||||
}
|
||||
-924
@@ -1,924 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebean.config.NamingConvention;
|
||||
import io.ebean.config.dbplatform.DbHistorySupport;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.util.StringHelper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.TableDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.IndexSet;
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AddTableComment;
|
||||
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DdlScript;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
import io.ebeaninternal.dbmigration.migration.ForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.UniqueConstraint;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTableIdentity;
|
||||
import io.ebeaninternal.server.deploy.IdentityMode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.ebean.util.StringHelper.replace;
|
||||
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
|
||||
import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.split;
|
||||
|
||||
/**
|
||||
* Base implementation for 'create table' and 'alter table' statements.
|
||||
*/
|
||||
public class BaseTableDdl implements TableDdl {
|
||||
|
||||
enum HistorySupport {
|
||||
NONE,
|
||||
SQL2011,
|
||||
TRIGGER_BASED
|
||||
}
|
||||
|
||||
protected final DbConstraintNaming naming;
|
||||
|
||||
protected final NamingConvention namingConvention;
|
||||
|
||||
protected final PlatformDdl platformDdl;
|
||||
|
||||
protected final String historyTableSuffix;
|
||||
|
||||
/**
|
||||
* Used to check that indexes on foreign keys should be skipped as a unique index on the columns
|
||||
* already exists.
|
||||
*/
|
||||
protected final IndexSet indexSet = new IndexSet();
|
||||
|
||||
/**
|
||||
* Used when unique constraints specifically for OneToOne can't be created normally (MsSqlServer).
|
||||
*/
|
||||
protected final List<Column> externalUnique = new ArrayList<>();
|
||||
|
||||
protected final List<UniqueConstraint> externalCompoundUnique = new ArrayList<>();
|
||||
|
||||
// counters used when constraint names are truncated due to maximum length
|
||||
// and these counters are used to keep the constraint name unique
|
||||
protected int countCheck;
|
||||
protected int countUnique;
|
||||
protected int countForeignKey;
|
||||
protected int countIndex;
|
||||
|
||||
/**
|
||||
* Base tables that have associated history tables that need their triggers/functions regenerated as
|
||||
* columns have been added, removed, included or excluded.
|
||||
*/
|
||||
protected final Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<>();
|
||||
|
||||
private final boolean strictMode;
|
||||
|
||||
private final HistorySupport historySupport;
|
||||
|
||||
/**
|
||||
* Helper class that is used to execute the migration ddl before and after the migration action.
|
||||
*/
|
||||
private class DdlMigrationHelp {
|
||||
private final List<String> before;
|
||||
private final List<String> after;
|
||||
private final String tableName;
|
||||
private final String columnName;
|
||||
private final String defaultValue;
|
||||
private final boolean withHistory;
|
||||
|
||||
/**
|
||||
* Constructor for DdlMigrationHelp when adding a NEW column.
|
||||
*/
|
||||
DdlMigrationHelp(String tableName, Column column, boolean withHistory) {
|
||||
this.tableName = tableName;
|
||||
this.columnName = column.getName();
|
||||
this.defaultValue = platformDdl.convertDefaultValue(column.getDefaultValue());
|
||||
boolean alterNotNull = Boolean.TRUE.equals(column.isNotnull());
|
||||
if (column.getBefore().isEmpty() && alterNotNull && defaultValue == null) {
|
||||
handleStrictError(tableName, columnName);
|
||||
}
|
||||
before = getScriptsForPlatform(column.getBefore());
|
||||
after = getScriptsForPlatform(column.getAfter());
|
||||
this.withHistory = withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for DdlMigrationHelp when altering a column.
|
||||
*/
|
||||
DdlMigrationHelp(AlterColumn alter) {
|
||||
this.tableName = alter.getTableName();
|
||||
this.columnName = alter.getColumnName();
|
||||
String tmp = alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue();
|
||||
this.defaultValue = platformDdl.convertDefaultValue(tmp);
|
||||
boolean alterNotNull = Boolean.TRUE.equals(alter.isNotnull());
|
||||
// here we add the platform's default update script
|
||||
withHistory = isTrue(alter.isWithHistory());
|
||||
if (alter.getBefore().isEmpty() && alterNotNull) {
|
||||
if (defaultValue == null) {
|
||||
handleStrictError(tableName, columnName);
|
||||
}
|
||||
before = Collections.singletonList(platformDdl.getUpdateNullWithDefault());
|
||||
} else {
|
||||
before = getScriptsForPlatform(alter.getBefore());
|
||||
}
|
||||
after = getScriptsForPlatform(alter.getAfter());
|
||||
}
|
||||
|
||||
void writeBefore(DdlBuffer buffer) throws IOException {
|
||||
if (!before.isEmpty()) {
|
||||
buffer.end();
|
||||
}
|
||||
|
||||
if (!before.isEmpty() && withHistory) {
|
||||
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
|
||||
}
|
||||
for (String ddlScript : before) {
|
||||
buffer.appendStatement(translate(ddlScript, tableName, columnName, this.defaultValue));
|
||||
}
|
||||
}
|
||||
|
||||
void writeAfter(DdlBuffer buffer) throws IOException {
|
||||
if (!after.isEmpty() && withHistory) {
|
||||
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
|
||||
}
|
||||
// here we run post migration scripts
|
||||
for (String ddlScript : after) {
|
||||
buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
|
||||
}
|
||||
if (!after.isEmpty()) {
|
||||
buffer.end();
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getScriptsForPlatform(List<DdlScript> scripts) {
|
||||
Platform searchPlatform = platformDdl.getPlatform().getPlatform();
|
||||
for (DdlScript script : scripts) {
|
||||
if (matchPlatform(searchPlatform, script.getPlatforms())) {
|
||||
// just returns the first match (rather than appends them)
|
||||
return script.getDdl();
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces Table name (${table}), Column name (${column}) and default value (${default}) in DDL.
|
||||
*/
|
||||
private String translate(String ddl, String tableName, String columnName, String defaultValue) {
|
||||
String ret = replace(ddl, "${table}", tableName);
|
||||
ret = replace(ret, "${column}", columnName);
|
||||
return replace(ret, "${default}", defaultValue);
|
||||
}
|
||||
|
||||
private void handleStrictError(String tableName, String columnName) {
|
||||
if (strictMode) {
|
||||
String message = "DB Migration of non-null column with no default value specified for: " + tableName + "." + columnName+" Use @DbDefault to specify a default value or specify dbMigration.setStrictMode(false)";
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a naming convention and platform specific DDL.
|
||||
*/
|
||||
public BaseTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
this.namingConvention = config.getNamingConvention();
|
||||
this.naming = config.getConstraintNaming();
|
||||
this.historyTableSuffix = config.getHistoryTableSuffix();
|
||||
this.platformDdl = platformDdl;
|
||||
this.platformDdl.configure(config);
|
||||
this.strictMode = config.getMigrationConfig().isStrictMode();
|
||||
DbHistorySupport hist = platformDdl.getPlatform().getHistorySupport();
|
||||
if (hist == null) {
|
||||
this.historySupport = HistorySupport.NONE;
|
||||
} else {
|
||||
this.historySupport = hist.isStandardsBased() ? HistorySupport.SQL2011 : HistorySupport.TRIGGER_BASED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset counters and index set for each table processed.
|
||||
*/
|
||||
protected void reset() {
|
||||
indexSet.clear();
|
||||
externalUnique.clear();
|
||||
externalCompoundUnique.clear();
|
||||
countCheck = 0;
|
||||
countUnique = 0;
|
||||
countForeignKey = 0;
|
||||
countIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the appropriate 'create table' and matching 'drop table' statements
|
||||
* and add them to the appropriate 'apply' and 'rollback' buffers.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateTable createTable) throws IOException {
|
||||
reset();
|
||||
|
||||
String tableName = lowerTableName(createTable.getName());
|
||||
List<Column> columns = createTable.getColumn();
|
||||
List<Column> pk = determinePrimaryKeyColumns(columns);
|
||||
|
||||
DdlIdentity identity = DdlIdentity.NONE;
|
||||
if ((pk.size() == 1)) {
|
||||
final IdentityMode identityMode = MTableIdentity.fromCreateTable(createTable);
|
||||
IdType idType = platformDdl.useIdentityType(identityMode.getIdType());
|
||||
String sequenceName = identityMode.getSequenceName();
|
||||
if (IdType.SEQUENCE == idType && (sequenceName == null || sequenceName.isEmpty())) {
|
||||
sequenceName = sequenceName(createTable, pk);
|
||||
}
|
||||
identity = new DdlIdentity(idType, identityMode, sequenceName);
|
||||
}
|
||||
|
||||
String partitionMode = createTable.getPartitionMode();
|
||||
|
||||
DdlBuffer apply = writer.apply();
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(tableName).append(" (");
|
||||
writeTableColumns(apply, columns, identity);
|
||||
writeUniqueConstraints(apply, createTable);
|
||||
writeCompoundUniqueConstraints(apply, createTable);
|
||||
if (!pk.isEmpty()) {
|
||||
// defined on the columns
|
||||
if (partitionMode == null || !platformDdl.suppressPrimaryKeyOnPartition()) {
|
||||
writePrimaryKeyConstraint(apply, createTable.getPkName(), toColumnNames(pk));
|
||||
}
|
||||
}
|
||||
if (platformDdl.isInlineForeignKeys()) {
|
||||
writeInlineForeignKeys(writer, createTable);
|
||||
}
|
||||
apply.newLine().append(")");
|
||||
addTableStorageEngine(apply, createTable);
|
||||
addTableCommentInline(apply, createTable);
|
||||
if (partitionMode != null) {
|
||||
platformDdl.addTablePartition(apply, partitionMode, createTable.getPartitionColumn());
|
||||
}
|
||||
apply.endOfStatement();
|
||||
|
||||
addComments(apply, createTable);
|
||||
writeUniqueOneToOneConstraints(writer, createTable);
|
||||
if (isTrue(createTable.isWithHistory())) {
|
||||
// create history with rollback before the
|
||||
// associated drop table is written to rollback
|
||||
createWithHistory(writer, createTable.getName());
|
||||
}
|
||||
|
||||
// add drop table to the rollback buffer - do this before
|
||||
// we drop the related sequence (if sequences are used)
|
||||
dropTable(writer.dropAll(), tableName);
|
||||
|
||||
if (identity.useSequence()) {
|
||||
writeSequence(writer, identity);
|
||||
}
|
||||
|
||||
// add blank line for a bit of whitespace between tables
|
||||
apply.end();
|
||||
writer.dropAll().end();
|
||||
if (!platformDdl.isInlineForeignKeys()) {
|
||||
writeAddForeignKeys(writer, createTable);
|
||||
}
|
||||
}
|
||||
|
||||
private String sequenceName(CreateTable createTable, List<Column> pk) {
|
||||
return namingConvention.getSequenceName(createTable.getName(), pk.get(0).getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table and column comments (separate from the create table statement).
|
||||
*/
|
||||
private void addComments(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
if (!platformDdl.isInlineComments()) {
|
||||
String tableComment = createTable.getComment();
|
||||
if (hasValue(tableComment)) {
|
||||
platformDdl.addTableComment(apply, createTable.getName(), tableComment);
|
||||
}
|
||||
for (Column column : createTable.getColumn()) {
|
||||
if (!StringHelper.isNull(column.getComment())) {
|
||||
platformDdl.addColumnComment(apply, createTable.getName(), column.getName(), column.getComment());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the table storage engine clause.
|
||||
*/
|
||||
private void addTableStorageEngine(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
if (platformDdl.isIncludeStorageEngine()) {
|
||||
platformDdl.tableStorageEngine(apply, createTable.getStorageEngine());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the table comment inline with the create table statement.
|
||||
*/
|
||||
private void addTableCommentInline(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
if (platformDdl.isInlineComments()) {
|
||||
String tableComment = createTable.getComment();
|
||||
if (!StringHelper.isNull(tableComment)) {
|
||||
platformDdl.inlineTableComment(apply, tableComment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTableColumns(DdlBuffer apply, List<Column> columns, DdlIdentity identity) throws IOException {
|
||||
platformDdl.writeTableColumns(apply, columns, identity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
if (uqName == null) {
|
||||
uqName = col.getUnique();
|
||||
}
|
||||
String[] columnNames = {col.getName()};
|
||||
write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, Boolean.TRUE.equals(col.isNotnull()) ? null : columnNames));
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
|
||||
}
|
||||
|
||||
for (UniqueConstraint constraint : externalCompoundUnique) {
|
||||
String uqName = constraint.getName();
|
||||
String[] columnNames = split(constraint.getColumnNames());
|
||||
String[] nullableColumns = split(constraint.getNullableColumns());
|
||||
|
||||
write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns));
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeSequence(DdlWrite writer, DdlIdentity identity) throws IOException {
|
||||
String seqName = identity.getSequenceName();
|
||||
String createSeq = platformDdl.createSequence(seqName, identity);
|
||||
if (hasValue(createSeq)) {
|
||||
writer.apply().append(createSeq).newLine();
|
||||
writer.dropAll().appendStatement(platformDdl.dropSequence(seqName));
|
||||
}
|
||||
}
|
||||
|
||||
protected void createWithHistory(DdlWrite writer, String name) throws IOException {
|
||||
MTable table = writer.getTable(name);
|
||||
platformDdl.createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
protected void writeInlineForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
for (Column column : createTable.getColumn()) {
|
||||
String references = column.getReferences();
|
||||
if (hasValue(references)) {
|
||||
writeInlineForeignKey(write, column);
|
||||
}
|
||||
}
|
||||
writeInlineCompoundForeignKeys(write, createTable);
|
||||
}
|
||||
|
||||
protected void writeInlineForeignKey(DdlWrite write, Column column) throws IOException {
|
||||
String fkConstraint = platformDdl.tableInlineForeignKey(new WriteForeignKey(null, column));
|
||||
write.apply().append(",").newLine().append(" ").append(fkConstraint);
|
||||
}
|
||||
|
||||
protected void writeInlineCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
for (ForeignKey key : createTable.getForeignKey()) {
|
||||
String fkConstraint = platformDdl.tableInlineForeignKey(new WriteForeignKey(null, key));
|
||||
write.apply().append(",").newLine().append(" ").append(fkConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeAddForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
for (Column column : createTable.getColumn()) {
|
||||
String references = column.getReferences();
|
||||
if (hasValue(references)) {
|
||||
writeForeignKey(write, createTable.getName(), column);
|
||||
}
|
||||
}
|
||||
writeAddCompoundForeignKeys(write, createTable);
|
||||
}
|
||||
|
||||
protected void writeAddCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
for (ForeignKey key : createTable.getForeignKey()) {
|
||||
writeForeignKey(write, new WriteForeignKey(createTable.getName(), key));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, String tableName, Column column) throws IOException {
|
||||
writeForeignKey(write, new WriteForeignKey(tableName, column));
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, WriteForeignKey request) throws IOException {
|
||||
DdlBuffer fkeyBuffer = write.applyForeignKeys();
|
||||
String tableName = lowerTableName(request.table());
|
||||
if (request.indexName() != null) {
|
||||
// no matching unique constraint so add the index
|
||||
fkeyBuffer.appendStatement(platformDdl.createIndex(new WriteCreateIndex(request.indexName(), tableName, request.cols(), false)));
|
||||
}
|
||||
alterTableAddForeignKey(write.getOptions(), fkeyBuffer, request);
|
||||
fkeyBuffer.end();
|
||||
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.alterTableDropForeignKey(tableName, request.fkName()));
|
||||
if (hasValue(request.indexName())) {
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(request.indexName(), tableName));
|
||||
}
|
||||
write.dropAllForeignKeys().end();
|
||||
}
|
||||
|
||||
protected void alterTableAddForeignKey(DdlOptions options, DdlBuffer buffer, WriteForeignKey request) throws IOException {
|
||||
buffer.appendStatement(platformDdl.alterTableAddForeignKey(options, request));
|
||||
}
|
||||
|
||||
protected void appendColumns(String[] columns, DdlBuffer buffer) throws IOException {
|
||||
buffer.append(" (");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(lowerColumnName(columns[i].trim()));
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'drop table' statement to the buffer.
|
||||
*/
|
||||
protected void dropTable(DdlBuffer buffer, String tableName) throws IOException {
|
||||
buffer.appendStatement(platformDdl.dropTable(tableName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'drop sequence' statement to the buffer.
|
||||
*/
|
||||
protected void dropSequence(DdlBuffer buffer, String sequenceName) throws IOException {
|
||||
buffer.appendStatement(platformDdl.dropSequence(sequenceName));
|
||||
}
|
||||
|
||||
protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
boolean inlineUniqueWhenNull = platformDdl.isInlineUniqueWhenNullable();
|
||||
for (UniqueConstraint uniqueConstraint : createTable.getUniqueConstraint()) {
|
||||
if (platformInclude(uniqueConstraint.getPlatforms())) {
|
||||
if (inlineUniqueWhenNull) {
|
||||
String uqName = uniqueConstraint.getName();
|
||||
apply.append(",").newLine();
|
||||
apply.append(" constraint ").append(uqName).append(" unique");
|
||||
appendColumns(split(uniqueConstraint.getColumnNames()), apply);
|
||||
} else {
|
||||
externalCompoundUnique.add(uniqueConstraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean platformInclude(String platforms) {
|
||||
return matchPlatform(platformDdl.getPlatform().getPlatform(), platforms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unique constraints inline with the create table statement.
|
||||
*/
|
||||
protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
boolean inlineUniqueWhenNullable = platformDdl.isInlineUniqueWhenNullable();
|
||||
List<Column> columns = new WriteUniqueConstraint(createTable.getColumn()).uniqueKeys();
|
||||
for (Column column : columns) {
|
||||
if (Boolean.TRUE.equals(column.isNotnull()) || inlineUniqueWhenNullable) {
|
||||
// normal mechanism for adding unique constraint
|
||||
inlineUniqueConstraintSingle(apply, column);
|
||||
} else {
|
||||
// SqlServer & DB2 specific mechanism for adding unique constraints (that allow nulls)
|
||||
externalUnique.add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unique constraint inline with the create table statement.
|
||||
*/
|
||||
protected void inlineUniqueConstraintSingle(DdlBuffer buffer, Column column) throws IOException {
|
||||
String uqName = column.getUnique();
|
||||
if (uqName == null) {
|
||||
uqName = column.getUniqueOneToOne();
|
||||
}
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(uqName).append(" unique ");
|
||||
buffer.append("(");
|
||||
buffer.append(lowerColumnName(column.getName()));
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the primary key constraint inline with the create table statement.
|
||||
*/
|
||||
protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) throws IOException {
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(pkName).append(" primary key");
|
||||
appendColumns(pkColumns, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return as an array of string column names.
|
||||
*/
|
||||
protected String[] toColumnNames(List<Column> columns) {
|
||||
String[] cols = new String[columns.size()];
|
||||
for (int i = 0; i < cols.length; i++) {
|
||||
cols[i] = columns.get(i).getName();
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the table lower case.
|
||||
*/
|
||||
protected String lowerTableName(String name) {
|
||||
return naming.lowerTableName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the column name to lower case.
|
||||
*/
|
||||
protected String lowerColumnName(String name) {
|
||||
return naming.lowerColumnName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of columns that make the primary key.
|
||||
*/
|
||||
protected List<Column> determinePrimaryKeyColumns(List<Column> columns) {
|
||||
List<Column> pk = new ArrayList<>(3);
|
||||
for (Column column : columns) {
|
||||
if (isTrue(column.isPrimaryKey())) {
|
||||
pk.add(column);
|
||||
}
|
||||
}
|
||||
return pk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateIndex index) throws IOException {
|
||||
if (platformInclude(index.getPlatforms())) {
|
||||
writer.apply().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
|
||||
writer.dropAll().appendStatement(platformDdl.dropIndex(index.getIndexName(), index.getTableName(), Boolean.TRUE.equals(index.isConcurrent())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropIndex dropIndex) throws IOException {
|
||||
if (platformInclude(dropIndex.getPlatforms())) {
|
||||
writer.apply().appendStatement(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName(), Boolean.TRUE.equals(dropIndex.isConcurrent())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException {
|
||||
if (platformInclude(constraint.getPlatforms())) {
|
||||
if (DdlHelp.isDropConstraint(constraint.getColumnNames())) {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName()));
|
||||
|
||||
} else {
|
||||
String[] cols = split(constraint.getColumnNames());
|
||||
String[] nullableColumns = split(constraint.getNullableColumns());
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException {
|
||||
if (DdlHelp.isDropForeignKey(alterForeignKey.getColumnNames())) {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName()));
|
||||
} else {
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddForeignKey(writer.getOptions(), new WriteForeignKey(alterForeignKey)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add add history table DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
platformDdl.addHistoryTable(writer, addHistoryTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add drop history table DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
platformDdl.dropHistoryTable(writer, dropHistoryTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
platformDdl.generateProlog(write);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the end to generate additional ddl such as regenerate history triggers.
|
||||
*/
|
||||
@Override
|
||||
public void generateEpilog(DdlWrite write) throws IOException {
|
||||
if (!regenerateHistoryTriggers.isEmpty()) {
|
||||
platformDdl.lockTables(write.applyHistoryTrigger(), regenerateHistoryTriggers.keySet());
|
||||
|
||||
for (HistoryTableUpdate update : this.regenerateHistoryTriggers.values()) {
|
||||
platformDdl.regenerateHistoryTriggers(write, update);
|
||||
}
|
||||
|
||||
platformDdl.unlockTables(write.applyHistoryTrigger(), regenerateHistoryTriggers.keySet());
|
||||
}
|
||||
platformDdl.generateEpilog(write);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException {
|
||||
if (hasValue(addTableComment.getComment())) {
|
||||
platformDdl.addTableComment(writer.apply(), addTableComment.getName(), addTableComment.getComment());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add add column DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
String tableName = addColumn.getTableName();
|
||||
List<Column> columns = addColumn.getColumn();
|
||||
for (Column column : columns) {
|
||||
alterTableAddColumn(writer.apply(), tableName, column, false, isTrue(addColumn.isWithHistory()));
|
||||
}
|
||||
if (isTrue(addColumn.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
// make same changes to the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
for (Column column : columns) {
|
||||
regenerateHistoryTriggers(tableName, HistoryTableUpdate.Change.ADD, column.getName());
|
||||
alterTableAddColumn(writer.apply(), historyTable, column, true, true);
|
||||
}
|
||||
}
|
||||
for (Column column : columns) {
|
||||
if (hasValue(column.getReferences())) {
|
||||
writeForeignKey(writer, tableName, column);
|
||||
}
|
||||
}
|
||||
writer.apply().end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add drop table DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropTable dropTable) throws IOException {
|
||||
dropTable(writer.apply(), dropTable.getName());
|
||||
if (hasValue(dropTable.getSequenceCol())
|
||||
&& platformDdl.getPlatform().getDbIdentity().isSupportsSequence()) {
|
||||
String sequenceName = dropTable.getSequenceName();
|
||||
if (!hasValue(sequenceName)) {
|
||||
sequenceName = namingConvention.getSequenceName(dropTable.getName(), dropTable.getSequenceCol());
|
||||
}
|
||||
dropSequence(writer.apply(), sequenceName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add drop column DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
String tableName = dropColumn.getTableName();
|
||||
alterTableDropColumn(writer.apply(), tableName, dropColumn.getColumnName());
|
||||
|
||||
if (isTrue(dropColumn.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
// also drop from the history table
|
||||
regenerateHistoryTriggers(tableName, HistoryTableUpdate.Change.DROP, dropColumn.getColumnName());
|
||||
alterTableDropColumn(writer.apply(), historyTable(tableName), dropColumn.getColumnName());
|
||||
}
|
||||
writer.apply().end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the appropriate changes based on the column changes.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
DdlMigrationHelp ddlHelp = new DdlMigrationHelp(alterColumn);
|
||||
ddlHelp.writeBefore(writer.apply());
|
||||
|
||||
if (isTrue(alterColumn.isHistoryExclude())) {
|
||||
regenerateHistoryTriggers(alterColumn.getTableName(), HistoryTableUpdate.Change.EXCLUDE, alterColumn.getColumnName());
|
||||
} else if (isFalse(alterColumn.isHistoryExclude())) {
|
||||
regenerateHistoryTriggers(alterColumn.getTableName(), HistoryTableUpdate.Change.INCLUDE, alterColumn.getColumnName());
|
||||
}
|
||||
|
||||
if (hasValue(alterColumn.getDropForeignKey())) {
|
||||
alterColumnDropForeignKey(writer, alterColumn);
|
||||
}
|
||||
if (hasValue(alterColumn.getReferences())) {
|
||||
alterColumnAddForeignKey(writer, alterColumn);
|
||||
}
|
||||
|
||||
if (hasValue(alterColumn.getDropUnique())) {
|
||||
alterColumnDropUniqueConstraint(writer, alterColumn);
|
||||
}
|
||||
if (hasValue(alterColumn.getUnique())) {
|
||||
alterColumnAddUniqueConstraint(writer, alterColumn);
|
||||
}
|
||||
if (hasValue(alterColumn.getUniqueOneToOne())) {
|
||||
alterColumnAddUniqueOneToOneConstraint(writer, alterColumn);
|
||||
}
|
||||
if (hasValue(alterColumn.getComment())) {
|
||||
alterColumnComment(writer, alterColumn);
|
||||
}
|
||||
if (hasValue(alterColumn.getDropCheckConstraint())) {
|
||||
dropCheckConstraint(writer, alterColumn, alterColumn.getDropCheckConstraint());
|
||||
}
|
||||
|
||||
boolean alterCheckConstraint = hasValue(alterColumn.getCheckConstraint());
|
||||
|
||||
if (alterCheckConstraint) {
|
||||
// drop constraint before altering type etc
|
||||
dropCheckConstraint(writer, alterColumn, alterColumn.getCheckConstraintName());
|
||||
}
|
||||
boolean alterBaseAttributes = false;
|
||||
if (hasValue(alterColumn.getType())) {
|
||||
alterColumnType(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (hasValue(alterColumn.getDefaultValue())) {
|
||||
alterColumnDefaultValue(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (alterColumn.isNotnull() != null) {
|
||||
alterColumnNotnull(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (alterBaseAttributes) {
|
||||
alterColumnBaseAttributes(writer, alterColumn);
|
||||
}
|
||||
if (alterCheckConstraint) {
|
||||
// add constraint last (after potential type change)
|
||||
addCheckConstraint(writer, alterColumn);
|
||||
}
|
||||
ddlHelp.writeAfter(writer.apply());
|
||||
}
|
||||
|
||||
private void alterColumnComment(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
platformDdl.addColumnComment(writer.apply(), alterColumn.getTableName(), alterColumn.getColumnName(), alterColumn.getComment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the history table given the base table name.
|
||||
*/
|
||||
protected String historyTable(String baseTable) {
|
||||
return baseTable + historyTableSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the base table that we need to regenerate the history triggers on.
|
||||
*/
|
||||
protected void regenerateHistoryTriggers(String baseTableName, HistoryTableUpdate.Change change, String column) {
|
||||
HistoryTableUpdate update = regenerateHistoryTriggers.computeIfAbsent(baseTableName, HistoryTableUpdate::new);
|
||||
update.add(change, column);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is mysql specific - alter all the base attributes of the column together.
|
||||
* Will be called, if there is a type, dbdefault or notnull change.
|
||||
*/
|
||||
protected void alterColumnBaseAttributes(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
String ddl = platformDdl.alterColumnBaseAttributes(alter);
|
||||
if (hasValue(ddl)) {
|
||||
writer.apply().appendStatement(ddl);
|
||||
|
||||
if (isTrue(alter.isWithHistory()) && alter.getType() != null && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
// mysql and sql server column type change allowing nulls in the history table column
|
||||
regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName());
|
||||
AlterColumn alterHistoryColumn = new AlterColumn();
|
||||
alterHistoryColumn.setTableName(historyTable(alter.getTableName()));
|
||||
alterHistoryColumn.setColumnName(alter.getColumnName());
|
||||
alterHistoryColumn.setType(alter.getType());
|
||||
String histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn);
|
||||
|
||||
// write the apply to history table
|
||||
writer.apply().appendStatement(histColumnDdl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterColumnDefaultValue(alter.getTableName(), alter.getColumnName(), alter.getDefaultValue()));
|
||||
}
|
||||
|
||||
protected void dropCheckConstraint(DdlWrite writer, AlterColumn alter, String constraintName) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropConstraint(alter.getTableName(), constraintName));
|
||||
}
|
||||
|
||||
protected void addCheckConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddCheckConstraint(alter.getTableName(), alter.getCheckConstraintName(), alter.getCheckConstraint()));
|
||||
}
|
||||
|
||||
protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isNotnull()));
|
||||
}
|
||||
|
||||
protected void alterColumnType(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
String ddl = platformDdl.alterColumnType(alter.getTableName(), alter.getColumnName(), alter.getType());
|
||||
if (hasValue(ddl)) {
|
||||
writer.apply().appendStatement(ddl);
|
||||
if (isTrue(alter.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName());
|
||||
// apply same type change to matching column in the history table
|
||||
ddl = platformDdl.alterColumnType(historyTable(alter.getTableName()), alter.getColumnName(), alter.getType());
|
||||
writer.apply().appendStatement(ddl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void alterColumnAddForeignKey(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
alterTableAddForeignKey(writer.getOptions(), writer.apply(), new WriteForeignKey(alterColumn));
|
||||
}
|
||||
|
||||
protected void alterColumnDropForeignKey(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alter.getTableName(), alter.getDropForeignKey()));
|
||||
}
|
||||
|
||||
protected void alterColumnDropUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(alter.getTableName(), alter.getDropUnique()));
|
||||
}
|
||||
|
||||
protected void alterColumnAddUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
addUniqueConstraint(writer, alter, alter.getUniqueOneToOne());
|
||||
}
|
||||
|
||||
protected void alterColumnAddUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
addUniqueConstraint(writer, alter, alter.getUnique());
|
||||
}
|
||||
|
||||
protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter, String uqName) throws IOException {
|
||||
String[] cols = {alter.getColumnName()};
|
||||
boolean notNull = alter.isNotnull() != null ? alter.isNotnull() : Boolean.TRUE.equals(alter.isNotnull());
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull ? null : cols));
|
||||
|
||||
writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, alter.getTableName()));
|
||||
}
|
||||
|
||||
|
||||
protected void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
platformDdl.alterTableDropColumn(buffer, tableName, columnName);
|
||||
}
|
||||
|
||||
protected void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, boolean withHistory) throws IOException {
|
||||
DdlMigrationHelp help = new DdlMigrationHelp(tableName, column, withHistory);
|
||||
if (!onHistoryTable) {
|
||||
help.writeBefore(buffer);
|
||||
}
|
||||
|
||||
platformDdl.alterTableAddColumn(buffer, tableName, column, onHistoryTable, help.getDefaultValue());
|
||||
final String comment = column.getComment();
|
||||
if (comment != null && !comment.isEmpty()) {
|
||||
platformDdl.addColumnComment(buffer, tableName, column.getName(), comment);
|
||||
}
|
||||
|
||||
if (!onHistoryTable) {
|
||||
help.writeAfter(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isFalse(Boolean value) {
|
||||
return value != null && !value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if null or trimmed string is empty.
|
||||
*/
|
||||
protected boolean hasValue(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Null safe Boolean true test.
|
||||
*/
|
||||
protected boolean isTrue(Boolean value) {
|
||||
return Boolean.TRUE.equals(value);
|
||||
}
|
||||
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Logical array type to ClickHouse array type conversion.
|
||||
*/
|
||||
class ClickHouseDbArray {
|
||||
|
||||
private static final Map<String, String> mapping = new HashMap<>();
|
||||
static {
|
||||
mapping.put("uuid[]", "Array(UUID)");
|
||||
mapping.put("varchar[]", "Array(String)");
|
||||
mapping.put("integer[]", "Array(UInt32)");
|
||||
mapping.put("bigint[]", "Array(UInt64)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Covert the 'logical' array type to a native one (for Postgres and Cockroach).
|
||||
*/
|
||||
static String logicalToNative(String logicalArrayType) {
|
||||
int colonPos = logicalArrayType.indexOf(':');
|
||||
if (colonPos > -1) {
|
||||
logicalArrayType = logicalArrayType.substring(0, colonPos);
|
||||
}
|
||||
String clickHouseType = mapping.get(logicalArrayType);
|
||||
if (clickHouseType == null) {
|
||||
throw new IllegalStateException("No mapping for logical array type " + logicalArrayType);
|
||||
}
|
||||
return clickHouseType;
|
||||
}
|
||||
}
|
||||
-92
@@ -1,92 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClickHouseDdl extends PlatformDdl {
|
||||
|
||||
private static final String LOG_TABLE = "ENGINE = Log()";
|
||||
|
||||
public ClickHouseDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.includeStorageEngine = true;
|
||||
this.identitySuffix = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlHandler createDdlHandler(DatabaseConfig config) {
|
||||
return new ClickHouseDdlHandler(config, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String convertArrayType(String logicalArrayType) {
|
||||
return ClickHouseDbArray.logicalToNative(logicalArrayType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an table storage engine to the create table statement.
|
||||
*/
|
||||
@Override
|
||||
public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException {
|
||||
if (storageEngine == null) {
|
||||
// default to Log() table but really should all be explicit (need arguments for MergeTree etc)
|
||||
storageEngine = LOG_TABLE;
|
||||
}
|
||||
apply.append(" ").append(storageEngine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tableInlineForeignKey(WriteForeignKey request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createIndex(WriteCreateIndex create) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createCheckConstraint(String ckName, String checkConstraint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeColumnNotNull(DdlBuffer buffer) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInlineComments() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
|
||||
public class ClickHouseDdlHandler extends BaseDdlHandler {
|
||||
|
||||
public ClickHouseDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
super(config, platformDdl, new ClickHouseTableDdl(config, platformDdl));
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||
|
||||
public class ClickHouseTableDdl extends BaseTableDdl {
|
||||
|
||||
public ClickHouseTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
super(config, platformDdl);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
/**
|
||||
* CockroachDB specific DDL handling.
|
||||
*/
|
||||
public class CockroachDdl extends PlatformDdl {
|
||||
|
||||
public CockroachDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.dropTableCascade = " cascade";
|
||||
this.columnSetType = "type ";
|
||||
this.alterTableIfExists = "if exists ";
|
||||
this.columnSetNull = "drop not null";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String convertArrayType(String logicalArrayType) {
|
||||
return NativeDbArray.logicalToNative(logicalArrayType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map bigint, integer and smallint all into serial.
|
||||
*/
|
||||
@Override
|
||||
public String asIdentityColumn(String columnDefn, DdlIdentity identity) {
|
||||
if ("bigint".equalsIgnoreCase(columnDefn)) {
|
||||
return "serial";
|
||||
}
|
||||
if ("integer".equalsIgnoreCase(columnDefn)) {
|
||||
return "serial";
|
||||
}
|
||||
if ("smallint".equalsIgnoreCase(columnDefn)) {
|
||||
return "serial";
|
||||
}
|
||||
return columnDefn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInlineComments() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
/**
|
||||
* DB2 platform specific DDL.
|
||||
*/
|
||||
public class DB2Ddl extends PlatformDdl {
|
||||
|
||||
public DB2Ddl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.dropTableIfExists = "drop table ";
|
||||
this.dropSequenceIfExists = "drop sequence ";
|
||||
this.dropConstraintIfExists = "drop constraint";
|
||||
this.dropIndexIfExists = "drop index ";
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
this.inlineUniqueWhenNullable = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
|
||||
if (nullableColumns == null || nullableColumns.length == 0) {
|
||||
return super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
|
||||
} else {
|
||||
// Hmm: Complex workaround: https://www.ibm.com/developerworks/mydeveloperworks/blogs/SQLTips4DB2LUW/entry/unique_where_not_null_indexes26?lang=en
|
||||
return "-- NOT SUPPORTED " + super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
|
||||
// do nothing, no on update clause for db2
|
||||
}
|
||||
|
||||
}
|
||||
-285
@@ -1,285 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MColumn;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Uses DB triggers to maintain a history table.
|
||||
*/
|
||||
public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
protected DbConstraintNaming constraintNaming;
|
||||
|
||||
protected PlatformDdl platformDdl;
|
||||
|
||||
protected String sysPeriod;
|
||||
protected String sysPeriodStart;
|
||||
protected String sysPeriodEnd;
|
||||
|
||||
protected String viewSuffix;
|
||||
protected String historySuffix;
|
||||
|
||||
protected String sysPeriodType = "datetime(6)";
|
||||
protected String now = "now(6)";
|
||||
protected String sysPeriodEndValue = "now(6)";
|
||||
|
||||
DbTriggerBasedHistoryDdl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
this.platformDdl = platformDdl;
|
||||
this.sysPeriod = config.getAsOfSysPeriod();
|
||||
this.viewSuffix = config.getAsOfViewSuffix();
|
||||
this.historySuffix = config.getHistoryTableSuffix();
|
||||
this.constraintNaming = config.getConstraintNaming();
|
||||
|
||||
this.sysPeriodStart = sysPeriod + "_start";
|
||||
this.sysPeriodEnd = sysPeriod + "_end";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, HistoryTableUpdate update) throws IOException {
|
||||
|
||||
MTable table = writer.getTable(update.getBaseTable());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("MTable " + update.getBaseTable() + " not found in writer? (required for history DDL)");
|
||||
}
|
||||
updateTriggers(writer, table, update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the existing triggers/stored procedures/views for history table support given the included columns.
|
||||
*/
|
||||
protected abstract void updateHistoryTriggers(DbTriggerUpdate triggerUpdate) throws IOException;
|
||||
|
||||
/**
|
||||
* Process the HistoryTableUpdate which can result in changes to the apply, rollback
|
||||
* and drop scripts.
|
||||
*/
|
||||
protected void updateTriggers(DdlWrite writer, MTable table, HistoryTableUpdate update) throws IOException {
|
||||
|
||||
writer.applyHistoryTrigger().append("-- changes: ").append(update.description()).newLine();
|
||||
|
||||
updateHistoryTriggers(createDbTriggerUpdate(writer, table));
|
||||
}
|
||||
|
||||
protected DbTriggerUpdate createDbTriggerUpdate(DdlWrite writer, MTable table) {
|
||||
|
||||
List<String> columns = columnNamesForApply(table);
|
||||
String baseTableName = table.getName();
|
||||
String historyTableName = historyTableName(baseTableName);
|
||||
return new DbTriggerUpdate(baseTableName, historyTableName, writer, columns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
|
||||
String baseTable = dropHistoryTable.getBaseTable();
|
||||
|
||||
// drop in appropriate order
|
||||
dropTriggers(writer.applyDropDependencies(), baseTable);
|
||||
dropHistoryTableEtc(writer.applyDropDependencies(), baseTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
|
||||
String baseTable = addHistoryTable.getBaseTable();
|
||||
MTable table = writer.getTable(baseTable);
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("MTable " + baseTable + " not found in writer? (required for history DDL)");
|
||||
}
|
||||
|
||||
createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTable = table.getName();
|
||||
String whenCreatedColumn = table.getWhenCreatedColumn();
|
||||
|
||||
dropTriggers(writer.dropAll(), baseTable);
|
||||
dropHistoryTableEtc(writer.dropAll(), baseTable);
|
||||
|
||||
addHistoryTable(writer, table, whenCreatedColumn);
|
||||
createStoredFunction(writer, table);
|
||||
createTriggers(writer, table);
|
||||
}
|
||||
|
||||
protected abstract void createTriggers(DdlWrite writer, MTable table) throws IOException;
|
||||
|
||||
protected abstract void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException;
|
||||
|
||||
protected void createStoredFunction(DdlWrite writer, MTable table) throws IOException {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
protected String normalise(String tableName) {
|
||||
return constraintNaming.normaliseTable(tableName);
|
||||
}
|
||||
|
||||
protected String historyTableName(String baseTableName) {
|
||||
return baseTableName + historySuffix;
|
||||
}
|
||||
|
||||
protected String procedureName(String baseTableName) {
|
||||
return baseTableName + "_history_version";
|
||||
}
|
||||
|
||||
protected String triggerName(String baseTableName) {
|
||||
return normalise(baseTableName) + "_history_upd";
|
||||
}
|
||||
|
||||
protected String updateTriggerName(String baseTableName) {
|
||||
return normalise(baseTableName) + "_history_upd";
|
||||
}
|
||||
|
||||
protected String deleteTriggerName(String baseTableName) {
|
||||
return normalise(baseTableName) + "_history_del";
|
||||
}
|
||||
|
||||
protected void addHistoryTable(DdlWrite writer, MTable table, String whenCreatedColumn) throws IOException {
|
||||
|
||||
String baseTableName = table.getName();
|
||||
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
|
||||
addSysPeriodColumns(apply, baseTableName, whenCreatedColumn);
|
||||
createHistoryTable(apply, table);
|
||||
createWithHistoryView(apply, baseTableName);
|
||||
}
|
||||
|
||||
protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
|
||||
|
||||
apply.append("alter table ").append(baseTableName).append(" add column ")
|
||||
.append(sysPeriodStart).append(" ").append(sysPeriodType).append(" default ").append(now).endOfStatement();
|
||||
apply.append("alter table ").append(baseTableName).append(" add column ")
|
||||
.append(sysPeriodEnd).append(" ").append(sysPeriodType).endOfStatement();
|
||||
|
||||
if (whenCreatedColumn != null) {
|
||||
apply.append("update ").append(baseTableName).append(" set ").append(sysPeriodStart).append(" = ").append(whenCreatedColumn).endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
|
||||
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(table.getName()).append(historySuffix).append("(").newLine();
|
||||
|
||||
Collection<MColumn> cols = table.allColumns();
|
||||
for (MColumn column : cols) {
|
||||
if (!column.isDraftOnly()) {
|
||||
writeColumnDefinition(apply, column.getName(), column.getType());
|
||||
apply.append(",").newLine();
|
||||
}
|
||||
}
|
||||
writeColumnDefinition(apply, sysPeriodStart, sysPeriodType);
|
||||
apply.append(",").newLine();
|
||||
writeColumnDefinition(apply, sysPeriodEnd, sysPeriodType);
|
||||
apply.newLine().append(")").endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the column definition to the create table statement.
|
||||
*/
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type) throws IOException {
|
||||
|
||||
String platformType = platformDdl.convert(type);
|
||||
buffer.append(" ");
|
||||
buffer.append(platformDdl.lowerColumnName(columnName), 29);
|
||||
buffer.append(platformType);
|
||||
}
|
||||
|
||||
protected void createWithHistoryView(DdlBuffer apply, String baseTableName) throws IOException {
|
||||
|
||||
apply
|
||||
.append("create view ").append(baseTableName).append(viewSuffix)
|
||||
.append(" as select * from ").append(baseTableName)
|
||||
.append(" union all select * from ").append(baseTableName).append(historySuffix)
|
||||
.endOfStatement().end();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For postgres/h2/mysql we need to drop and recreate the view. Well, we could add columns to the end of the view
|
||||
* but otherwise we need to drop and create it.
|
||||
*/
|
||||
protected void recreateHistoryView(DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer buffer = update.dropDependencyBuffer();
|
||||
// we need to drop the view early/first before any changes to the tables etc
|
||||
buffer.append("drop view if exists ").append(update.getBaseTable()).append(viewSuffix).endOfStatement();
|
||||
|
||||
// recreate the view after all ddl modifications - the view requires ALL columns, also the historyExclude ones.
|
||||
createWithHistoryView(update.historyViewBuffer(), update.getBaseTable());
|
||||
}
|
||||
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
|
||||
appendColumnName(apply, prefix, sysPeriodStart);
|
||||
appendColumnName(apply, prefix, sysPeriodEnd);
|
||||
}
|
||||
|
||||
protected void dropHistoryTableEtc(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
|
||||
buffer.append("drop view ").append(baseTableName).append(viewSuffix).endOfStatement();
|
||||
dropSysPeriodColumns(buffer, baseTableName);
|
||||
buffer.append("drop table ").append(baseTableName).append(historySuffix).endOfStatement().end();
|
||||
}
|
||||
|
||||
protected void dropSysPeriodColumns(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
platformDdl.alterTableDropColumn(buffer, baseTableName, sysPeriodStart);
|
||||
platformDdl.alterTableDropColumn(buffer, baseTableName, sysPeriodEnd);
|
||||
}
|
||||
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List<String> columns) throws IOException {
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriodStart).append(",").append(sysPeriodEnd).append(",");
|
||||
appendColumnNames(buffer, columns, "");
|
||||
buffer.append(") values (OLD.").append(sysPeriodStart).append(", ").append(sysPeriodEndValue).append(",");
|
||||
appendColumnNames(buffer, columns, "OLD.");
|
||||
buffer.append(");").newLine();
|
||||
}
|
||||
|
||||
void appendColumnNames(DdlBuffer buffer, List<String> columns, String columnPrefix) throws IOException {
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
buffer.append(columnPrefix);
|
||||
buffer.append(columns.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a single column to the buffer if it is not null.
|
||||
*/
|
||||
void appendColumnName(DdlBuffer buffer, String prefix, String columnName) throws IOException {
|
||||
if (columnName != null) {
|
||||
buffer.append(prefix).append(columnName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column names included in history for the apply script.
|
||||
* <p>
|
||||
* Note that dropped columns are actually still included at this point as they are going
|
||||
* to be removed from the history handling when the drop script runs that also deletes
|
||||
* the column.
|
||||
* </p>
|
||||
*/
|
||||
List<String> columnNamesForApply(MTable table) {
|
||||
return table.allHistoryColumns(true);
|
||||
}
|
||||
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DB trigger update when a change occurs on a table with history.
|
||||
*/
|
||||
public class DbTriggerUpdate {
|
||||
|
||||
private final String baseTableName;
|
||||
|
||||
private final String historyTableName;
|
||||
|
||||
private final DdlWrite writer;
|
||||
|
||||
private final List<String> columns;
|
||||
|
||||
public DbTriggerUpdate(String baseTableName, String historyTableName, DdlWrite writer, List<String> columns) {
|
||||
this.baseTableName = baseTableName;
|
||||
this.historyTableName = historyTableName;
|
||||
this.writer = writer;
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the appropriate buffer for the current mode.
|
||||
*/
|
||||
public DdlBuffer historyViewBuffer() {
|
||||
return writer.applyHistoryView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the appropriate buffer for the current mode.
|
||||
*/
|
||||
public DdlBuffer historyTriggerBuffer() {
|
||||
return writer.applyHistoryTrigger();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the appropriate drop dependency buffer for the current mode.
|
||||
*/
|
||||
public DdlBuffer dropDependencyBuffer() {
|
||||
return writer.applyDropDependencies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base table name.
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the history table name.
|
||||
*/
|
||||
public String getHistoryTable() {
|
||||
return historyTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the included columns.
|
||||
*/
|
||||
public List<String> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
public class DdlHelp {
|
||||
public static final String DROP_DEFAULT = "DROP DEFAULT";
|
||||
|
||||
public static final String DROP_COMMENT = "DROP COMMENT";
|
||||
|
||||
public static final String DROP_CONSTRAINT = "DROP CONSTRAINT";
|
||||
|
||||
public static final String DROP_FOREIGN_KEY = "DROP FOREIGN KEY";
|
||||
|
||||
/**
|
||||
* Return true if the default value is the special DROP DEFAULT value.
|
||||
*/
|
||||
public static boolean isDropDefault(String value) {
|
||||
return DROP_DEFAULT.equals(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the default value is the special DROP COMMENT value.
|
||||
*/
|
||||
public static boolean isDropComment(String value) {
|
||||
return DROP_COMMENT.equals(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the default value is the special DROP CONSTRAINT value.
|
||||
*/
|
||||
public static boolean isDropConstraint(String value) {
|
||||
return DROP_CONSTRAINT.equals(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the default value is the special DROP FOREIGN KEY value.
|
||||
*/
|
||||
public static boolean isDropForeignKey(String value) {
|
||||
return DROP_FOREIGN_KEY.equals(value);
|
||||
}
|
||||
}
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.IdentityGenerated;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebeaninternal.server.deploy.IdentityMode;
|
||||
|
||||
public class DdlIdentity {
|
||||
|
||||
public static final DdlIdentity NONE = new DdlIdentity();
|
||||
|
||||
private final IdType idType;
|
||||
private final IdentityMode identityMode;
|
||||
private final String sequenceName;
|
||||
|
||||
public DdlIdentity(IdType idType, IdentityMode identityMode, String sequenceName) {
|
||||
this.idType = idType;
|
||||
this.identityMode = identityMode;
|
||||
this.sequenceName = sequenceName;
|
||||
}
|
||||
|
||||
private DdlIdentity() {
|
||||
this.idType = null;
|
||||
this.identityMode = null;
|
||||
this.sequenceName = null;
|
||||
}
|
||||
|
||||
public boolean useSequence() {
|
||||
return idType == IdType.SEQUENCE;
|
||||
}
|
||||
|
||||
public boolean useIdentity() {
|
||||
return idType == IdType.IDENTITY;
|
||||
}
|
||||
|
||||
public String getSequenceName() {
|
||||
return sequenceName;
|
||||
}
|
||||
|
||||
private String generatedBy() {
|
||||
return isAlways() ? "always" : "by default";
|
||||
}
|
||||
|
||||
private boolean isAlways() {
|
||||
return IdentityGenerated.ALWAYS == identityMode.getGenerated();
|
||||
}
|
||||
|
||||
public String optionGenerated() {
|
||||
return " generated " + generatedBy() +" as identity";
|
||||
}
|
||||
|
||||
public String identityOptions(String startWith, String incrementBy, String cache) {
|
||||
return options(true, startWith, incrementBy, cache);
|
||||
}
|
||||
|
||||
public String sequenceOptions(String startWith, String incrementBy, String cache) {
|
||||
return options(false, startWith, incrementBy, cache);
|
||||
}
|
||||
|
||||
private String options(boolean brackets, String startWith, String incrementBy, String cache) {
|
||||
if (!identityMode.hasOptions()) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(40);
|
||||
if (brackets) {
|
||||
sb.append(" (");
|
||||
} else {
|
||||
sb.append(" ");
|
||||
}
|
||||
optionFor(sb, startWith, identityMode.getStart());
|
||||
optionFor(sb, incrementBy, identityMode.getIncrement());
|
||||
optionFor(sb, cache, identityMode.getCache());
|
||||
if (brackets) {
|
||||
sb.append(")");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void optionFor(StringBuilder sb, String prefix, int val) {
|
||||
if (val > 0 && prefix != null) {
|
||||
if (sb.length() > 2) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(prefix).append(" ").append(val);
|
||||
}
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return identityMode.getStart();
|
||||
}
|
||||
|
||||
public int getIncrement() {
|
||||
return identityMode.getIncrement();
|
||||
}
|
||||
|
||||
public int getCache() {
|
||||
return identityMode.getCache();
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.VowelRemover;
|
||||
|
||||
/**
|
||||
* Default implementation used to truncate or shorten db constraint names as required.
|
||||
*/
|
||||
public class DefaultConstraintMaxLength implements DbConstraintNaming.MaxLength {
|
||||
|
||||
private final int maxConstraintNameLength;
|
||||
|
||||
public DefaultConstraintMaxLength(int maxConstraintNameLength) {
|
||||
this.maxConstraintNameLength = maxConstraintNameLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a maximum length to the constraint name.
|
||||
* <p>
|
||||
* This implementation should work well apart from perhaps DB2 where the limit is 18.
|
||||
*/
|
||||
@Override
|
||||
public String maxLength(String constraintName, int count) {
|
||||
if (constraintName.length() < maxConstraintNameLength) {
|
||||
return constraintName;
|
||||
}
|
||||
if (maxConstraintNameLength < 60) {
|
||||
// trim out vowels for Oracle / DB2 with short max lengths
|
||||
constraintName = VowelRemover.trim(constraintName, 4);
|
||||
if (constraintName.length() < maxConstraintNameLength) {
|
||||
return constraintName;
|
||||
}
|
||||
}
|
||||
// add the count to ensure the constraint name is unique
|
||||
// (relying on the prefix having the table name to be globally unique)
|
||||
return constraintName.substring(0, maxConstraintNameLength - 3) + "_" + count;
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
/**
|
||||
* H2 platform specific DDL.
|
||||
*/
|
||||
public class H2Ddl extends PlatformDdl {
|
||||
|
||||
public H2Ddl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.historyDdl = new H2HistoryDdl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify and return the column definition for autoincrement or identity definition.
|
||||
*/
|
||||
@Override
|
||||
public String asIdentityColumn(String columnDefn, DdlIdentity identity) {
|
||||
return asIdentityStandardOptions(columnDefn, identity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String convertArrayType(String logicalArrayType) {
|
||||
return "array";
|
||||
}
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.h2.H2HistoryTrigger;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* H2 history support using DB triggers to maintain a history table.
|
||||
*/
|
||||
public class H2HistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
private static final String TRIGGER_CLASS = H2HistoryTrigger.class.getName();
|
||||
|
||||
H2HistoryDdl() {
|
||||
this.sysPeriodType = "timestamp";
|
||||
this.now = "now()";
|
||||
this.sysPeriodEndValue = "now()";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = table.getName();
|
||||
DdlBuffer apply = writer.applyHistoryTrigger();
|
||||
|
||||
addCreateTrigger(apply, updateTriggerName(baseTableName), baseTableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
|
||||
recreateHistoryView(update);
|
||||
|
||||
DdlBuffer buffer = update.historyTriggerBuffer();
|
||||
dropTriggers(buffer, update.getBaseTable());
|
||||
addCreateTrigger(buffer, updateTriggerName(update.getBaseTable()), update.getBaseTable());
|
||||
}
|
||||
|
||||
private void addCreateTrigger(DdlBuffer apply, String triggerName, String baseTable) throws IOException {
|
||||
|
||||
// Note that this does not take into account the historyTable name (excepts _history suffix) and
|
||||
// does not take into account excluded columns (all columns included in history)
|
||||
apply
|
||||
.append("create trigger ").append(triggerName).append(" before update,delete on ").append(baseTable)
|
||||
.append(" for each row call \"" + TRIGGER_CLASS + "\";").newLine();
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HanaColumnStoreDdl extends AbstractHanaDdl {
|
||||
|
||||
public HanaColumnStoreDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.createTable = "create column table";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createIndex(WriteCreateIndex create) {
|
||||
final String[] columns = create.getColumns();
|
||||
if (columns == null || columns.length == 0) {
|
||||
return "-- cannot create index: no columns given";
|
||||
}
|
||||
if (columns.length == 1) {
|
||||
return "-- explicit index \"" + create.getIndexName() + "\" for single column \"" + columns[0] + "\" of table \"" + create.getTableName()
|
||||
+ "\" is not necessary";
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("create inverted hash index ").append(maxConstraintName(create.getIndexName())).append(" on ").append(create.getTableName());
|
||||
appendColumns(columns, buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
DdlBuffer buffer = new BaseDdlBuffer(null);
|
||||
try {
|
||||
buffer.append("delimiter $$").newLine();
|
||||
buffer.append("do").newLine();
|
||||
buffer.append("begin").newLine();
|
||||
buffer.append("declare exit handler for sql_error_code 261 begin end").endOfStatement();
|
||||
buffer.append("exec '").append(dropIndexIfExists).append(maxConstraintName(indexName)).append("'")
|
||||
.endOfStatement();
|
||||
buffer.append("end").endOfStatement();
|
||||
buffer.append("$$");
|
||||
return buffer.getBuffer();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
|
||||
public class HanaDdlHandler extends BaseDdlHandler {
|
||||
|
||||
public HanaDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
super(config, platformDdl, new HanaTableDdl(config, platformDdl));
|
||||
}
|
||||
}
|
||||
-157
@@ -1,157 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MColumn;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
private String systemPeriodStart;
|
||||
private String systemPeriodEnd;
|
||||
private PlatformDdl platformDdl;
|
||||
private String historySuffix;
|
||||
private final AtomicInteger counter = new AtomicInteger(0);
|
||||
private Map<String, String> createdHistoryTables = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
this.systemPeriodStart = config.getAsOfSysPeriod() + "_start";
|
||||
this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end";
|
||||
this.platformDdl = platformDdl;
|
||||
this.historySuffix = config.getHistoryTableSuffix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
String tableName = table.getName();
|
||||
String historyTableName = tableName + historySuffix;
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
if (apply.isEmpty()) {
|
||||
createdHistoryTables.clear();
|
||||
}
|
||||
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName).append(" (").newLine();
|
||||
|
||||
// create history table
|
||||
Collection<MColumn> cols = table.allColumns();
|
||||
for (MColumn column : cols) {
|
||||
if (!column.isDraftOnly()) {
|
||||
writeColumnDefinition(apply, column.getName(), column.getType(), column.getDefaultValue(), column.isNotnull(),
|
||||
column.isIdentity() ? platformDdl.identitySuffix : null);
|
||||
apply.append(",").newLine();
|
||||
}
|
||||
}
|
||||
writeColumnDefinition(apply, systemPeriodStart, "TIMESTAMP", null, false, null);
|
||||
apply.append(",").newLine();
|
||||
writeColumnDefinition(apply, systemPeriodEnd, "TIMESTAMP", null, false, null);
|
||||
apply.newLine().append(")").endOfStatement();
|
||||
|
||||
// enable system versioning
|
||||
apply.append("alter table ").append(tableName).append(" add (").newLine();
|
||||
apply.append(" ").append(systemPeriodStart).append(" TIMESTAMP NOT NULL GENERATED ALWAYS AS ROW START, ").newLine();
|
||||
apply.append(" ").append(systemPeriodEnd).append(" TIMESTAMP NOT NULL GENERATED ALWAYS AS ROW END").newLine();
|
||||
apply.append(")").endOfStatement();
|
||||
|
||||
apply.append("alter table ").append(tableName).append(" add period for system_time(").append(systemPeriodStart)
|
||||
.append(",").append(systemPeriodEnd).append(")").endOfStatement();
|
||||
|
||||
enableSystemVersioning(apply, tableName, historyTableName, true, false);
|
||||
|
||||
createdHistoryTables.put(tableName, historyTableName);
|
||||
|
||||
dropHistoryTable(writer.dropAll(), tableName, historyTableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
dropHistoryTable(writer.applyDropDependencies(), dropHistoryTable.getBaseTable(),
|
||||
dropHistoryTable.getBaseTable() + historySuffix);
|
||||
}
|
||||
|
||||
protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) throws IOException {
|
||||
// disable system versioning
|
||||
disableSystemVersioning(apply, baseTable);
|
||||
|
||||
apply.append("alter table ").append(baseTable).append(" drop period for system_time").endOfStatement();
|
||||
|
||||
// drop the period columns
|
||||
apply.append("alter table ").append(baseTable).append(" drop (").append(systemPeriodStart).append(",")
|
||||
.append(systemPeriodEnd).append(")").endOfStatement();
|
||||
|
||||
// drop the history table
|
||||
apply.append("drop table ").append(historyTable).append(" cascade").endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
MTable table = writer.getTable(addHistoryTable.getBaseTable());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)");
|
||||
}
|
||||
createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type, String defaultValue,
|
||||
boolean isNotNull, String generated) throws IOException {
|
||||
|
||||
String platformType = platformDdl.convert(type);
|
||||
buffer.append(" ").append(platformDdl.lowerColumnName(columnName));
|
||||
buffer.append(" ").append(platformType);
|
||||
if (defaultValue != null) {
|
||||
buffer.append(" default ").append(defaultValue);
|
||||
}
|
||||
if (isNotNull) {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
if (generated != null) {
|
||||
buffer.append(" ").append(generated);
|
||||
}
|
||||
}
|
||||
|
||||
public void disableSystemVersioning(DdlBuffer apply, String tableName) throws IOException {
|
||||
disableSystemVersioning(apply, tableName, false);
|
||||
}
|
||||
|
||||
public void disableSystemVersioning(DdlBuffer apply, String tableName, boolean uniqueStatement) throws IOException {
|
||||
apply.append("alter table ").append(tableName).append(" drop system versioning");
|
||||
if (uniqueStatement) {
|
||||
// needed for the DB migration test to prevent the statement from being filtered
|
||||
// out as a duplicate
|
||||
apply.append(" /* ").append(String.valueOf(counter.getAndIncrement())).append(" */");
|
||||
}
|
||||
apply.endOfStatement();
|
||||
}
|
||||
|
||||
public void enableSystemVersioning(DdlBuffer apply, String tableName, String historyTableName, boolean validated,
|
||||
boolean uniqueStatement) throws IOException {
|
||||
apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(historyTableName);
|
||||
if (!validated) {
|
||||
apply.append(" not validated");
|
||||
}
|
||||
if (uniqueStatement) {
|
||||
// needed for the DB migration test to prevent the statement from being filtered
|
||||
// out as a duplicate
|
||||
apply.append(" /* ").append(String.valueOf(counter.getAndIncrement())).append(" */");
|
||||
}
|
||||
apply.endOfStatement();
|
||||
}
|
||||
|
||||
public boolean isSystemVersioningEnabled(String tableName) {
|
||||
return !createdHistoryTables.containsKey(tableName);
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
public class HanaRowStoreDdl extends AbstractHanaDdl {
|
||||
|
||||
public HanaRowStoreDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.createTable = "create row table";
|
||||
}
|
||||
}
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.PropertiesWrapper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class HanaTableDdl extends BaseTableDdl {
|
||||
|
||||
private final HanaHistoryDdl historyDdl;
|
||||
private final boolean generateUniqueDdl;
|
||||
|
||||
public HanaTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
super(config, platformDdl);
|
||||
this.historyDdl = (HanaHistoryDdl) platformDdl.historyDdl;
|
||||
if (config.getProperties() != null) {
|
||||
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "hana", config.getProperties(), config.getClassLoadConfig());
|
||||
this.generateUniqueDdl = wrapper.getBoolean("generateUniqueDdl", false);
|
||||
} else {
|
||||
this.generateUniqueDdl = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
// done in alterColumnBaseAttributes
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
String tableName = addColumn.getTableName();
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table == null) {
|
||||
super.generate(writer, addColumn);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
historyDdl.disableSystemVersioning(writer.apply(), table.getName(), this.generateUniqueDdl);
|
||||
}
|
||||
|
||||
super.generate(writer, addColumn);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
// make same changes to the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
List<Column> columns = addColumn.getColumn();
|
||||
for (Column column : columns) {
|
||||
alterTableAddColumn(writer.apply(), historyTable, column, true, true);
|
||||
}
|
||||
|
||||
historyDdl.enableSystemVersioning(writer.apply(), table.getName(), historyTable, false, this.generateUniqueDdl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
String tableName = alterColumn.getTableName();
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table == null) {
|
||||
super.generate(writer, alterColumn);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
historyDdl.disableSystemVersioning(writer.apply(), tableName, this.generateUniqueDdl);
|
||||
}
|
||||
|
||||
super.generate(writer, alterColumn);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
// make same changes to the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
if (hasValue(alterColumn.getType()) || hasValue(alterColumn.getDefaultValue()) || alterColumn.isNotnull() != null) {
|
||||
AlterColumn alterHistoryColumn = new AlterColumn();
|
||||
alterHistoryColumn.setTableName(historyTable);
|
||||
alterHistoryColumn.setColumnName(alterColumn.getColumnName());
|
||||
alterHistoryColumn.setType(alterColumn.getType());
|
||||
alterHistoryColumn.setDefaultValue(alterColumn.getDefaultValue());
|
||||
alterHistoryColumn.setNotnull(alterColumn.isNotnull());
|
||||
alterHistoryColumn.setCurrentType(alterColumn.getCurrentType());
|
||||
alterHistoryColumn.setCurrentDefaultValue(alterColumn.getCurrentDefaultValue());
|
||||
alterHistoryColumn.setCurrentNotnull(alterColumn.isCurrentNotnull());
|
||||
String histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn);
|
||||
|
||||
// write the apply to history table
|
||||
writer.apply().append(histColumnDdl).endOfStatement();
|
||||
}
|
||||
|
||||
historyDdl.enableSystemVersioning(writer.apply(), tableName, historyTable, false, this.generateUniqueDdl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
String tableName = dropColumn.getTableName();
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table == null) {
|
||||
super.generate(writer, dropColumn);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
historyDdl.disableSystemVersioning(writer.apply(), tableName, this.generateUniqueDdl);
|
||||
}
|
||||
|
||||
super.generate(writer, dropColumn);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
// also drop from the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
alterTableDropColumn(writer.apply(), historyTable, dropColumn.getColumnName());
|
||||
|
||||
historyDdl.enableSystemVersioning(writer.apply(), tableName, historyTable, false, this.generateUniqueDdl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Bean holding comments relating to a history table that needs to have it's
|
||||
* associated triggers/function updated due to columns added/dropped/included
|
||||
* or excluded.
|
||||
*/
|
||||
public class HistoryTableUpdate {
|
||||
|
||||
/**
|
||||
* Column change type.
|
||||
*/
|
||||
public enum Change {
|
||||
ADD,
|
||||
DROP,
|
||||
INCLUDE,
|
||||
EXCLUDE,
|
||||
ALTER
|
||||
}
|
||||
|
||||
private static class Column {
|
||||
|
||||
final Change change;
|
||||
|
||||
final String column;
|
||||
|
||||
public Column(Change change, String column) {
|
||||
this.change = change;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return description();
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return change.name().toLowerCase() + " " + column;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final String baseTable;
|
||||
|
||||
private final List<Column> columnChanges = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Construct with a given base table name.
|
||||
*/
|
||||
public HistoryTableUpdate(String baseTable) {
|
||||
this.baseTable = baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of the changes that cause the history trigger/function
|
||||
* to be regenerated (added, included, excluded and dropped columns).
|
||||
*/
|
||||
public String description() {
|
||||
return columnChanges.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a comment for column added, dropped, included or excluded.
|
||||
*/
|
||||
public void add(Change change, String column) {
|
||||
columnChanges.add(new Column(change, column));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base table name.
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
/**
|
||||
* Hsqldb platform specific DDL.
|
||||
*/
|
||||
public class HsqldbDdl extends PlatformDdl {
|
||||
|
||||
public HsqldbDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.identitySuffix = " generated by default as identity (start with 1) ";
|
||||
}
|
||||
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
/**
|
||||
* MariaDB platform DDL.
|
||||
*/
|
||||
public class MariaDbDdl extends MySqlDdl {
|
||||
|
||||
public MariaDbDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.historyDdl = new MariaDbHistoryDdl();
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* History DDL for MariaDB.
|
||||
*/
|
||||
public class MariaDbHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
String baseTable = table.getName();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
|
||||
private void enableSystemVersioning(DdlWrite writer, String baseTable) throws IOException {
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
apply.append("alter table ").append(baseTable).append(" add system versioning").endOfStatement();
|
||||
|
||||
DdlBuffer drop = writer.dropAll();
|
||||
drop.append("alter table ").append(baseTable).append(" drop system versioning").endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
String baseTable = dropHistoryTable.getBaseTable();
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
apply.append("alter table ").append(baseTable).append(" drop system versioning").endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
String baseTable = addHistoryTable.getBaseTable();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, HistoryTableUpdate baseTable) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
-182
@@ -1,182 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.util.StringHelper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* MySql specific DDL.
|
||||
*/
|
||||
public class MySqlDdl extends PlatformDdl {
|
||||
|
||||
// check constraint support is disabled by default. See https://groups.google.com/forum/#!topic/ebean/luFN-2xBkUw
|
||||
// this flag is for compatibility. Use it with care.
|
||||
private static final boolean USE_CHECK_CONSTRAINT = Boolean.getBoolean("ebean.mysql.useCheckConstraint");
|
||||
|
||||
public MySqlDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.alterColumn = "modify";
|
||||
this.dropUniqueConstraint = "drop index";
|
||||
this.historyDdl = new MySqlHistoryDdl();
|
||||
this.inlineComments = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop index statement.
|
||||
*/
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
return "drop index " + maxConstraintName(indexName) + " on " + tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop foreign key clause.
|
||||
*/
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return "alter table " + tableName + " drop foreign key " + maxConstraintName(fkName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createCheckConstraint(String ckName, String checkConstraint) {
|
||||
if (USE_CHECK_CONSTRAINT) {
|
||||
return super.createCheckConstraint(ckName, checkConstraint);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddCheckConstraint(String tableName, String checkConstraintName, String checkConstraint) {
|
||||
if (USE_CHECK_CONSTRAINT) {
|
||||
return super.alterTableAddCheckConstraint(tableName, checkConstraintName, checkConstraint);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
// drop constraint not supported in MySQL 5.7 and 8.0 but starting with MariaDB
|
||||
// 10.2.1 CHECK is evaluated
|
||||
if (USE_CHECK_CONSTRAINT) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// statement for MySQL >= 8.0.16
|
||||
sb.append("/*!80016 alter table ").append(tableName);
|
||||
sb.append(" drop check ").append(constraintName).append(" */;\n");
|
||||
// statement for MariaDB >= 10.2.1
|
||||
sb.append("/*M!100201 ");
|
||||
sb.append(super.alterTableDropConstraint(tableName, constraintName));
|
||||
sb.append(" */");
|
||||
return sb.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + convertDefaultValue(defaultValue);
|
||||
return "alter table " + tableName + " alter " + columnName + " " + suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
if (alter.getType() == null && alter.isNotnull() == null) {
|
||||
// No type change or notNull change
|
||||
// defaultValue change already handled in alterColumnDefaultValue
|
||||
return null;
|
||||
}
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
type = convert(type);
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String notnullClause = notnull ? " not null" : "";
|
||||
|
||||
return "alter table " + tableName + " modify " + columnName + " " + type + notnullClause;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) throws IOException {
|
||||
super.writeColumnDefinition(buffer, column, identity);
|
||||
String comment = column.getComment();
|
||||
if (!StringHelper.isNull(comment)) {
|
||||
// in mysql 5.5 column comment save in information_schema.COLUMNS.COLUMN_COMMENT(VARCHAR 1024)
|
||||
if (comment.length() > 500) {
|
||||
comment = comment.substring(0, 500);
|
||||
}
|
||||
buffer.append(String.format(" comment '%s'", comment));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inlineTableComment(DdlBuffer apply, String tableComment) throws IOException {
|
||||
if (tableComment.length() > 1000) {
|
||||
tableComment = tableComment.substring(0, 1000);
|
||||
}
|
||||
apply.append(" comment='").append(tableComment).append("'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table comment as a separate statement (from the create table statement).
|
||||
*/
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
|
||||
if (DdlHelp.isDropComment(tableComment)) {
|
||||
tableComment = "";
|
||||
}
|
||||
apply.append(String.format("alter table %s comment = '%s'", tableName, tableComment)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
|
||||
// alter comment currently not supported as it requires to repeat whole column definition
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locks all tables for triggers that have to be updated.
|
||||
*/
|
||||
@Override
|
||||
public void lockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
if (!tables.isEmpty()) {
|
||||
buffer.append("lock tables ");
|
||||
int i = 0;
|
||||
for (String table : tables) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
buffer.append(table).append(" write");
|
||||
i++;
|
||||
}
|
||||
buffer.endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks all tables for triggers that have to be updated.
|
||||
*/
|
||||
@Override
|
||||
public void unlockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
buffer.append("unlock tables").endOfStatement();
|
||||
}
|
||||
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* MySql history support using DB triggers to maintain a history table.
|
||||
*/
|
||||
public class MySqlHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
MySqlHistoryDdl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
|
||||
|
||||
addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
|
||||
addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
|
||||
recreateHistoryView(update);
|
||||
|
||||
DdlBuffer buffer = update.historyTriggerBuffer();
|
||||
String baseTable = update.getBaseTable();
|
||||
|
||||
dropTriggers(buffer, baseTable);
|
||||
addBeforeUpdate(updateTriggerName(baseTable), update);
|
||||
addBeforeDelete(deleteTriggerName(baseTable), update);
|
||||
}
|
||||
|
||||
private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
apply
|
||||
.append("delimiter $$").newLine()
|
||||
.append("create trigger ").append(triggerName).append(" before update on ").append(update.getBaseTable())
|
||||
.append(" for each row begin").newLine();
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
apply
|
||||
.append(" set NEW.").append(sysPeriod).append("_start = now(6)").endOfStatement()
|
||||
.append("end$$").newLine();
|
||||
}
|
||||
|
||||
private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
apply
|
||||
.append("delimiter $$").newLine()
|
||||
.append("create trigger ").append(triggerName).append(" before delete on ").append(update.getBaseTable())
|
||||
.append(" for each row begin").newLine();
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
apply.append("end$$").newLine();
|
||||
}
|
||||
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
/**
|
||||
* Helper for logical type conversion.
|
||||
*/
|
||||
class NativeDbArray {
|
||||
|
||||
/**
|
||||
* Covert the 'logical' array type to a native one (for Postgres and Cockroach).
|
||||
*/
|
||||
static String logicalToNative(String logicalArrayType) {
|
||||
int colonPos = logicalArrayType.lastIndexOf(']');
|
||||
if (colonPos == -1) {
|
||||
return logicalArrayType;
|
||||
} else {
|
||||
// trim of the fallback varchar length
|
||||
return logicalArrayType.substring(0, colonPos + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Default history implementation that does nothing. Needs to be replaced
|
||||
* with an appropriate implementation for the given database platform.
|
||||
*/
|
||||
public class NoHistorySupportDdl implements PlatformHistoryDdl {
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite write, HistoryTableUpdate update) {
|
||||
// does nothing
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
public class NuoDbDdl extends PlatformDdl {
|
||||
|
||||
public NuoDbDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.historyDdl = new NuoDbHistoryDdl();
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
this.dropConstraintIfExists = "drop constraint";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyOnDelete(StringBuilder buffer, ConstraintMode mode) {
|
||||
if (mode == ConstraintMode.RESTRICT) {
|
||||
// do nothing
|
||||
} else if (mode == ConstraintMode.SET_NULL) {
|
||||
// do nothing
|
||||
} else {
|
||||
super.appendForeignKeyOnDelete(buffer, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* NuoDB history support using DB triggers to maintain a history table.
|
||||
*/
|
||||
public class NuoDbHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
NuoDbHistoryDdl() {
|
||||
this.now = "now()";
|
||||
this.sysPeriodEndValue = "NEW.sys_period_start";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
|
||||
|
||||
addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
|
||||
addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
|
||||
recreateHistoryView(update);
|
||||
|
||||
DdlBuffer buffer = update.historyTriggerBuffer();
|
||||
String baseTable = update.getBaseTable();
|
||||
|
||||
dropTriggers(buffer, baseTable);
|
||||
addBeforeUpdate(updateTriggerName(baseTable), update);
|
||||
addBeforeDelete(deleteTriggerName(baseTable), update);
|
||||
}
|
||||
|
||||
private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
addTriggerStart(triggerName, update, apply, " before update for each row as ");
|
||||
apply.append(" NEW.sys_period_start = greatest(current_timestamp, date_add(OLD.sys_period_start, interval 1 microsecond))").endOfStatement();
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
addEndTrigger(apply);
|
||||
}
|
||||
|
||||
private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
addTriggerStart(triggerName, update, apply, " before delete for each row as");
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
addEndTrigger(apply);
|
||||
}
|
||||
|
||||
private void addTriggerStart(String triggerName, DbTriggerUpdate update, DdlBuffer apply, String s) throws IOException {
|
||||
apply
|
||||
.append("delimiter $$").newLine()
|
||||
.append("create or replace trigger ").append(triggerName).append(" for ").append(update.getBaseTable())
|
||||
.append(s).newLine();
|
||||
}
|
||||
|
||||
private void addEndTrigger(DdlBuffer apply) throws IOException {
|
||||
apply.append("end_trigger")
|
||||
.endOfStatement()
|
||||
.append("$$").newLine()
|
||||
.newLine();
|
||||
}
|
||||
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
/**
|
||||
* Oracle platform specific DDL.
|
||||
*/
|
||||
public class OracleDdl extends PlatformDdl {
|
||||
|
||||
public OracleDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.dropTableIfExists = "drop table ";
|
||||
this.dropSequenceIfExists = "drop sequence ";
|
||||
this.dropConstraintIfExists = "drop constraint";
|
||||
this.dropIndexIfExists = "drop index ";
|
||||
this.dropTableCascade = " cascade constraints purge";
|
||||
this.alterColumn = "modify";
|
||||
this.columnSetNotnull = "not null";
|
||||
this.columnSetNull = "null";
|
||||
this.columnSetDefault = "default";
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
|
||||
if (nullableColumns == null || nullableColumns.length == 0) {
|
||||
return super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
|
||||
} else {
|
||||
// Hmm: https://stackoverflow.com/questions/11893134/oracle-create-unique-index-but-ignore-nulls
|
||||
return "-- NOT YET IMPLEMENTED: " + super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
|
||||
// do nothing, no on update clause for oracle
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyMode(StringBuilder buffer, String onMode, ConstraintMode mode) {
|
||||
switch (mode) {
|
||||
case SET_NULL:
|
||||
case CASCADE:
|
||||
super.appendForeignKeyMode(buffer, onMode, mode);
|
||||
default:
|
||||
// do nothing, defaults to RESTRICT effectively
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify and return the column definition for autoincrement or identity definition.
|
||||
*/
|
||||
@Override
|
||||
public String asIdentityColumn(String columnDefn, DdlIdentity identity) {
|
||||
return asIdentityStandardOptions(columnDefn, identity);
|
||||
}
|
||||
|
||||
}
|
||||
-772
@@ -1,772 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.DbDefaultValue;
|
||||
import io.ebean.config.dbplatform.DbIdentity;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.util.StringHelper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.PlatformTypeConverter;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.VowelRemover;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Controls the DDL generation for a specific database platform.
|
||||
*/
|
||||
public class PlatformDdl {
|
||||
|
||||
protected final DatabasePlatform platform;
|
||||
|
||||
protected PlatformHistoryDdl historyDdl = new NoHistorySupportDdl();
|
||||
|
||||
/**
|
||||
* Converter for logical/standard types to platform specific types. (eg. clob -> text)
|
||||
*/
|
||||
private final PlatformTypeConverter typeConverter;
|
||||
|
||||
/**
|
||||
* For handling support of sequences and autoincrement.
|
||||
*/
|
||||
private final DbIdentity dbIdentity;
|
||||
|
||||
/**
|
||||
* Set to true if table and column comments are included inline with the create statements.
|
||||
*/
|
||||
protected boolean inlineComments;
|
||||
|
||||
/**
|
||||
* Default assumes if exists is supported.
|
||||
*/
|
||||
protected String dropTableIfExists = "drop table if exists ";
|
||||
|
||||
protected String dropTableCascade = "";
|
||||
|
||||
/**
|
||||
* Default assumes if exists is supported.
|
||||
*/
|
||||
protected String dropSequenceIfExists = "drop sequence if exists ";
|
||||
|
||||
protected String foreignKeyOnDelete = "on delete";
|
||||
protected String foreignKeyOnUpdate = "on update";
|
||||
|
||||
protected String identitySuffix = " auto_increment";
|
||||
protected String identityStartWith = "start with";
|
||||
protected String identityIncrementBy = "increment by";
|
||||
protected String identityCache = "cache";
|
||||
protected String sequenceStartWith = "start with";
|
||||
protected String sequenceIncrementBy = "increment by";
|
||||
protected String sequenceCache = "cache";
|
||||
|
||||
protected String alterTableIfExists = "";
|
||||
|
||||
protected String dropConstraintIfExists = "drop constraint if exists";
|
||||
|
||||
protected String dropIndexIfExists = "drop index if exists ";
|
||||
|
||||
protected String alterColumn = "alter column";
|
||||
|
||||
protected String alterColumnSuffix = "";
|
||||
|
||||
protected String dropUniqueConstraint = "drop constraint";
|
||||
|
||||
protected String addConstraint = "add constraint";
|
||||
|
||||
protected String addColumn = "add column";
|
||||
|
||||
protected String addColumnSuffix = "";
|
||||
|
||||
protected String columnSetType = "";
|
||||
|
||||
protected String columnSetDefault = "set default";
|
||||
|
||||
protected String columnDropDefault = "drop default";
|
||||
|
||||
protected String columnSetNotnull = "set not null";
|
||||
|
||||
protected String columnSetNull = "set null";
|
||||
|
||||
protected String updateNullWithDefault = "update ${table} set ${column} = ${default} where ${column} is null";
|
||||
|
||||
protected String createTable = "create table";
|
||||
|
||||
protected String dropColumn = "drop column";
|
||||
|
||||
protected String dropColumnSuffix = "";
|
||||
|
||||
protected String addForeignKeySkipCheck = "";
|
||||
|
||||
protected String uniqueIndex = "unique";
|
||||
protected String indexConcurrent = "";
|
||||
|
||||
/**
|
||||
* Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
|
||||
*/
|
||||
protected boolean inlineUniqueWhenNullable = true;
|
||||
|
||||
protected DbConstraintNaming naming;
|
||||
|
||||
/**
|
||||
* Generally not desired as then they are not named (used with SQLite).
|
||||
*/
|
||||
protected boolean inlineForeignKeys;
|
||||
|
||||
protected boolean includeStorageEngine;
|
||||
|
||||
protected final DbDefaultValue dbDefaultValue;
|
||||
|
||||
protected String fallbackArrayType = "varchar(1000)";
|
||||
|
||||
public PlatformDdl(DatabasePlatform platform) {
|
||||
this.platform = platform;
|
||||
this.dbIdentity = platform.getDbIdentity();
|
||||
this.dbDefaultValue = platform.getDbDefaultValue();
|
||||
this.typeConverter = new PlatformTypeConverter(platform.getDbTypeMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set configuration options.
|
||||
*/
|
||||
public void configure(DatabaseConfig config) {
|
||||
historyDdl.configure(config, this);
|
||||
naming = config.getConstraintNaming();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DdlHandler for the specific database platform.
|
||||
*/
|
||||
public DdlHandler createDdlHandler(DatabaseConfig config) {
|
||||
return new BaseDdlHandler(config, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the identity type to use given the support in the underlying database
|
||||
* platform for sequences and identity/autoincrement.
|
||||
*/
|
||||
public IdType useIdentityType(IdType modelIdentity) {
|
||||
if (modelIdentity == null) {
|
||||
// use the default
|
||||
return dbIdentity.getIdType();
|
||||
}
|
||||
return identityType(modelIdentity, dbIdentity.getIdType(), dbIdentity.isSupportsSequence(), dbIdentity.isSupportsIdentity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the id type to use based on requested identityType and
|
||||
* the support for that in the database platform.
|
||||
*/
|
||||
private IdType identityType(IdType modelIdentity, IdType platformIdType, boolean supportsSequence, boolean supportsIdentity) {
|
||||
switch (modelIdentity) {
|
||||
case GENERATOR:
|
||||
return IdType.GENERATOR;
|
||||
case EXTERNAL:
|
||||
return IdType.EXTERNAL;
|
||||
case SEQUENCE:
|
||||
return supportsSequence ? IdType.SEQUENCE : platformIdType;
|
||||
case IDENTITY:
|
||||
return supportsIdentity ? IdType.IDENTITY : platformIdType;
|
||||
default:
|
||||
return platformIdType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify and return the column definition for autoincrement or identity definition.
|
||||
*/
|
||||
public String asIdentityColumn(String columnDefn, DdlIdentity identity) {
|
||||
return columnDefn + identitySuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQl2003 standard identity definition.
|
||||
*/
|
||||
protected String asIdentityStandardOptions(String columnDefn, DdlIdentity identity) {
|
||||
StringBuilder sb = new StringBuilder(columnDefn.length() + 60);
|
||||
sb.append(columnDefn).append(identity.optionGenerated());
|
||||
sb.append(identity.identityOptions(identityStartWith, identityIncrementBy, identityCache));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the table and column comments are included inline.
|
||||
*/
|
||||
public boolean isInlineComments() {
|
||||
return inlineComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the platform includes storage engine clause.
|
||||
*/
|
||||
public boolean isIncludeStorageEngine() {
|
||||
return includeStorageEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if foreign key reference constraints need to inlined with create table.
|
||||
* Ideally we don't do this as then the constraints are not named. Do this for SQLite.
|
||||
*/
|
||||
public boolean isInlineForeignKeys() {
|
||||
return inlineForeignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* By default this does nothing returning null / no lock timeout.
|
||||
*/
|
||||
public String setLockTimeout(int lockTimeoutSeconds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write all the table columns converting to platform types as necessary.
|
||||
*/
|
||||
public void writeTableColumns(DdlBuffer apply, List<Column> columns, DdlIdentity identity) throws IOException {
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
apply.append(",");
|
||||
}
|
||||
apply.newLine();
|
||||
writeColumnDefinition(apply, columns.get(i), identity);
|
||||
}
|
||||
|
||||
for (Column column : columns) {
|
||||
String checkConstraint = column.getCheckConstraint();
|
||||
if (hasValue(checkConstraint)) {
|
||||
checkConstraint = createCheckConstraint(maxConstraintName(column.getCheckConstraintName()), checkConstraint);
|
||||
if (hasValue(checkConstraint)) {
|
||||
apply.append(",").newLine();
|
||||
apply.append(checkConstraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the column definition to the create table statement.
|
||||
*/
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) throws IOException {
|
||||
|
||||
String columnDefn = convert(column.getType());
|
||||
if (identity.useIdentity() && isTrue(column.isPrimaryKey())) {
|
||||
columnDefn = asIdentityColumn(columnDefn, identity);
|
||||
}
|
||||
|
||||
buffer.append(" ");
|
||||
buffer.append(lowerColumnName(column.getName()), 29);
|
||||
buffer.append(columnDefn);
|
||||
if (!Boolean.TRUE.equals(column.isPrimaryKey())) {
|
||||
String defaultValue = convertDefaultValue(column.getDefaultValue());
|
||||
if (defaultValue != null) {
|
||||
buffer.append(" default ").append(defaultValue);
|
||||
}
|
||||
}
|
||||
if (isTrue(column.isNotnull()) || isTrue(column.isPrimaryKey())) {
|
||||
writeColumnNotNull(buffer);
|
||||
}
|
||||
|
||||
// add check constraints later as we really want to give them a nice name
|
||||
// so that the database can potentially provide a nice SQL error
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow for platform overriding (e.g. ClickHouse).
|
||||
*/
|
||||
protected void writeColumnNotNull(DdlBuffer buffer) throws IOException {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the check constraint.
|
||||
*/
|
||||
public String createCheckConstraint(String ckName, String checkConstraint) {
|
||||
return " constraint " + ckName + " " + checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the DB column default literal to platform specific.
|
||||
*/
|
||||
public String convertDefaultValue(String dbDefault) {
|
||||
return dbDefaultValue.convert(dbDefault);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop foreign key clause.
|
||||
*/
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return "alter table " + alterTableIfExists + tableName + " " + dropConstraintIfExists + " " + maxConstraintName(fkName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the standard type to the platform specific type.
|
||||
*/
|
||||
public String convert(String type) {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
if (type.contains("[]")) {
|
||||
return convertArrayType(type);
|
||||
}
|
||||
return typeConverter.convert(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the logical array type to a db platform specific type to support the array data.
|
||||
*/
|
||||
protected String convertArrayType(String logicalArrayType) {
|
||||
if (logicalArrayType.endsWith("]")) {
|
||||
return fallbackArrayType;
|
||||
}
|
||||
int colonPos = logicalArrayType.lastIndexOf(']');
|
||||
return "varchar" + logicalArrayType.substring(colonPos + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add history support to this table using the platform specific mechanism.
|
||||
*/
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
historyDdl.createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop history support for a given table.
|
||||
*/
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
historyDdl.dropHistoryTable(writer, dropHistoryTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add history support to an existing table.
|
||||
*/
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
historyDdl.addHistoryTable(writer, addHistoryTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the history triggers (or function) due to a column being added/dropped/excluded or included.
|
||||
*/
|
||||
public void regenerateHistoryTriggers(DdlWrite write, HistoryTableUpdate update) throws IOException {
|
||||
historyDdl.updateTriggers(write, update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return the create sequence DDL.
|
||||
*/
|
||||
public String createSequence(String sequenceName, DdlIdentity identity) {
|
||||
StringBuilder sb = new StringBuilder("create sequence ");
|
||||
sb.append(sequenceName);
|
||||
sb.append(identity.sequenceOptions(sequenceStartWith, sequenceIncrementBy, sequenceCache));
|
||||
sb.append(";");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop sequence statement (potentially with if exists clause).
|
||||
*/
|
||||
public String dropSequence(String sequenceName) {
|
||||
return dropSequenceIfExists + sequenceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop table statement (potentially with if exists clause).
|
||||
*/
|
||||
public String dropTable(String tableName) {
|
||||
return dropTableIfExists + tableName + dropTableCascade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop index statement for known non concurrent index.
|
||||
*/
|
||||
public String dropIndex(String indexName, String tableName) {
|
||||
return dropIndex(indexName, tableName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop index statement.
|
||||
*/
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
return dropIndexIfExists + maxConstraintName(indexName);
|
||||
}
|
||||
|
||||
public String createIndex(WriteCreateIndex create) {
|
||||
if (create.useDefinition()) {
|
||||
return create.getDefinition();
|
||||
}
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("create ");
|
||||
if (create.isUnique()) {
|
||||
buffer.append(uniqueIndex).append(" ");
|
||||
}
|
||||
buffer.append("index ");
|
||||
if (create.isConcurrent()) {
|
||||
buffer.append(indexConcurrent);
|
||||
}
|
||||
buffer.append(maxConstraintName(create.getIndexName())).append(" on ").append(create.getTableName());
|
||||
appendColumns(create.getColumns(), buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key constraint when used inline with create table.
|
||||
*/
|
||||
public String tableInlineForeignKey(WriteForeignKey request) {
|
||||
|
||||
StringBuilder buffer = new StringBuilder(90);
|
||||
buffer.append("foreign key");
|
||||
appendColumns(request.cols(), buffer);
|
||||
buffer.append(" references ").append(lowerTableName(request.refTable()));
|
||||
appendColumns(request.refCols(), buffer);
|
||||
appendForeignKeySuffix(request, buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add foreign key.
|
||||
*/
|
||||
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
|
||||
|
||||
StringBuilder buffer = new StringBuilder(90);
|
||||
buffer
|
||||
.append("alter table ").append(lowerTableName(request.table()))
|
||||
.append(" add constraint ").append(maxConstraintName(request.fkName()))
|
||||
.append(" foreign key");
|
||||
appendColumns(request.cols(), buffer);
|
||||
buffer
|
||||
.append(" references ")
|
||||
.append(lowerTableName(request.refTable()));
|
||||
appendColumns(request.refCols(), buffer);
|
||||
appendForeignKeySuffix(request, buffer);
|
||||
if (options.isForeignKeySkipCheck()) {
|
||||
buffer.append(addForeignKeySkipCheck);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
protected void appendForeignKeySuffix(WriteForeignKey request, StringBuilder buffer) {
|
||||
appendForeignKeyOnDelete(buffer, withDefault(request.onDelete()));
|
||||
appendForeignKeyOnUpdate(buffer, withDefault(request.onDelete()));
|
||||
}
|
||||
|
||||
protected ConstraintMode withDefault(ConstraintMode mode) {
|
||||
return (mode == null) ? ConstraintMode.RESTRICT : mode;
|
||||
}
|
||||
|
||||
protected void appendForeignKeyOnDelete(StringBuilder buffer, ConstraintMode mode) {
|
||||
appendForeignKeyMode(buffer, foreignKeyOnDelete, mode);
|
||||
}
|
||||
|
||||
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
|
||||
appendForeignKeyMode(buffer, foreignKeyOnUpdate, mode);
|
||||
}
|
||||
|
||||
protected void appendForeignKeyMode(StringBuilder buffer, String onMode, ConstraintMode mode) {
|
||||
buffer.append(" ").append(onMode).append(" ").append(translate(mode));
|
||||
}
|
||||
|
||||
protected String translate(ConstraintMode mode) {
|
||||
switch (mode) {
|
||||
case SET_NULL:
|
||||
return "set null";
|
||||
case SET_DEFAULT:
|
||||
return "set default";
|
||||
case RESTRICT:
|
||||
return "restrict";
|
||||
case CASCADE:
|
||||
return "cascade";
|
||||
default:
|
||||
throw new IllegalStateException("Unknown mode " + mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a unique constraint from the table (Sometimes this is an index).
|
||||
*/
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
return "alter table " + tableName + " " + dropUniqueConstraint + " " + maxConstraintName(uniqueConstraintName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a unique constraint from the table.
|
||||
*/
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
return "alter table " + tableName + " " + dropConstraintIfExists + " " + maxConstraintName(constraintName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a unique constraint to the table.
|
||||
* <p>
|
||||
* Overridden by MsSqlServer for specific null handling on unique constraints.
|
||||
*/
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
|
||||
|
||||
StringBuilder buffer = new StringBuilder(90);
|
||||
buffer.append("alter table ").append(tableName).append(" add constraint ").append(maxConstraintName(uqName)).append(" unique ");
|
||||
appendColumns(columns, buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, String defaultValue) throws IOException {
|
||||
|
||||
String convertedType = convert(column.getType());
|
||||
|
||||
buffer.append("alter table ").append(tableName)
|
||||
.append(" ").append(addColumn).append(" ").append(column.getName())
|
||||
.append(" ").append(convertedType);
|
||||
|
||||
// Add default value also to history table if it is not excluded
|
||||
if (defaultValue != null) {
|
||||
if (!onHistoryTable || !isTrue(column.isHistoryExclude())) {
|
||||
buffer.append(" default ");
|
||||
buffer.append(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!onHistoryTable) {
|
||||
if (isTrue(column.isNotnull())) {
|
||||
writeColumnNotNull(buffer);
|
||||
}
|
||||
buffer.append(addColumnSuffix);
|
||||
buffer.endOfStatement();
|
||||
|
||||
// check constraints cannot be added in one statement for h2
|
||||
if (!StringHelper.isNull(column.getCheckConstraint())) {
|
||||
String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint());
|
||||
if (hasValue(ddl)) {
|
||||
buffer.append(ddl).endOfStatement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buffer.append(addColumnSuffix);
|
||||
buffer.endOfStatement();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(dropColumn).append(" ").append(columnName)
|
||||
.append(dropColumnSuffix).endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if unique constraints for nullable columns can be inlined as normal.
|
||||
* Returns false for MsSqlServer & DB2 due to it's not possible to to put a constraint
|
||||
* on a nullable column
|
||||
*/
|
||||
public boolean isInlineUniqueWhenNullable() {
|
||||
return inlineUniqueWhenNullable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter a column type.
|
||||
* <p>
|
||||
* Note that that MySql and SQL Server instead use alterColumnBaseAttributes()
|
||||
* </p>
|
||||
*/
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + columnSetType + convert(type) + alterColumnSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter a column adding or removing the not null constraint.
|
||||
* <p>
|
||||
* Note that that MySql, SQL Server, and HANA instead use alterColumnBaseAttributes()
|
||||
* </p>
|
||||
*/
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
String suffix = notnull ? columnSetNotnull : columnSetNull;
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix + alterColumnSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter table adding the check constraint.
|
||||
*/
|
||||
public String alterTableAddCheckConstraint(String tableName, String checkConstraintName, String checkConstraint) {
|
||||
return "alter table " + tableName + " " + addConstraint + " " + maxConstraintName(checkConstraintName) + " " + checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter column setting the default value.
|
||||
*/
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + convertDefaultValue(defaultValue);
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix + alterColumnSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter column setting both the type and not null constraint.
|
||||
* <p>
|
||||
* Used by MySql, SQL Server, and HANA as these require both column attributes to be set together.
|
||||
* </p>
|
||||
*/
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
// by default do nothing, only used by mysql, sql server, and HANA as they can only
|
||||
// modify the column with the full column definition
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void appendColumns(String[] columns, StringBuilder buffer) {
|
||||
buffer.append(" (");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(lowerColumnName(columns[i].trim()));
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the table to lower case.
|
||||
* <p>
|
||||
* Override as desired. Generally lower case with underscore is a good cross database
|
||||
* choice for column/table names.
|
||||
*/
|
||||
protected String lowerTableName(String name) {
|
||||
return naming.lowerTableName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the column name to lower case.
|
||||
* <p>
|
||||
* Override as desired. Generally lower case with underscore is a good cross database
|
||||
* choice for column/table names.
|
||||
*/
|
||||
protected String lowerColumnName(String name) {
|
||||
return naming.lowerColumnName(name);
|
||||
}
|
||||
|
||||
public DatabasePlatform getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public String getUpdateNullWithDefault() {
|
||||
return updateNullWithDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if null or trimmed string is empty.
|
||||
*/
|
||||
protected boolean hasValue(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Null safe Boolean true test.
|
||||
*/
|
||||
protected boolean isTrue(Boolean value) {
|
||||
return Boolean.TRUE.equals(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an inline table comment to the create table statement.
|
||||
*/
|
||||
public void inlineTableComment(DdlBuffer apply, String tableComment) throws IOException {
|
||||
// do nothing by default (MySql only)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an table storage engine to the create table statement.
|
||||
*/
|
||||
public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException {
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table comment as a separate statement (from the create table statement).
|
||||
*/
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
|
||||
if (DdlHelp.isDropComment(tableComment)) {
|
||||
tableComment = "";
|
||||
}
|
||||
apply.append(String.format("comment on table %s is '%s'", tableName, tableComment)).endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column comment as a separate statement.
|
||||
*/
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) throws IOException {
|
||||
if (DdlHelp.isDropComment(comment)) {
|
||||
comment = "";
|
||||
}
|
||||
apply.append(String.format("comment on column %s.%s is '%s'", table, column, comment)).endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to generate a prolog for each script (stored procedures)
|
||||
*/
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to generate an epilog. Will be added at the end of script
|
||||
*/
|
||||
public void generateEpilog(DdlWrite write) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortens the given name to the maximum constraint name length of the platform in a deterministic way.
|
||||
* <p>
|
||||
* First, all vowels are removed, If the string is still to long, 31 bits are taken from the hash code
|
||||
* of the string and base36 encoded (10 digits and 26 chars) string.
|
||||
* <p>
|
||||
* As 36^6 > 31^2, the resulting string is never longer as 6 chars.
|
||||
*/
|
||||
protected String maxConstraintName(String name) {
|
||||
if (name.length() > platform.getMaxConstraintNameLength()) {
|
||||
int hash = name.hashCode() & 0x7FFFFFFF;
|
||||
name = VowelRemover.trim(name, 4);
|
||||
if (name.length() > platform.getMaxConstraintNameLength()) {
|
||||
return name.substring(0, platform.getMaxConstraintNameLength() - 7) + "_" + Integer.toString(hash, 36);
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mysql-specific: Locks all tables for triggers that have to be updated.
|
||||
*/
|
||||
public void lockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mysql-specific: Unlocks all tables for triggers that have to be updated.
|
||||
*/
|
||||
public void unlockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database-specific "create table" command prefix. For HANA this is
|
||||
* either "create column table" or "create row table", for all other databases
|
||||
* it is "create table".
|
||||
*
|
||||
* @return The "create table" command prefix
|
||||
*/
|
||||
public String getCreateTableCommandPrefix() {
|
||||
return createTable;
|
||||
}
|
||||
|
||||
public boolean suppressPrimaryKeyOnPartition() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
|
||||
// only supported by postgres initially
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines the implementation for adding history support to a table.
|
||||
*/
|
||||
public interface PlatformHistoryDdl {
|
||||
|
||||
/**
|
||||
* Configure typically reading the necessary parameters from DatabaseConfig and Platform.
|
||||
*/
|
||||
void configure(DatabaseConfig config, PlatformDdl platformDdl);
|
||||
|
||||
/**
|
||||
* Creates a new table and add history support to the table using platform specific mechanism.
|
||||
*/
|
||||
void createWithHistory(DdlWrite writer, MTable table) throws IOException;
|
||||
|
||||
/**
|
||||
* Drop history support for the given table.
|
||||
*/
|
||||
void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
|
||||
|
||||
/**
|
||||
* Add history support to the given table.
|
||||
*/
|
||||
void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
|
||||
|
||||
/**
|
||||
* Regenerate the history triggers/stored function due to column added/dropped/included or excluded.
|
||||
*/
|
||||
void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) throws IOException;
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
|
||||
public class Postgres9Ddl extends PostgresDdl {
|
||||
|
||||
public Postgres9Ddl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map bigint, integer and smallint into their equivalent serial types.
|
||||
*/
|
||||
@Override
|
||||
public String asIdentityColumn(String columnDefn, DdlIdentity identity) {
|
||||
if ("bigint".equalsIgnoreCase(columnDefn)) {
|
||||
return "bigserial";
|
||||
}
|
||||
if ("integer".equalsIgnoreCase(columnDefn)) {
|
||||
return "serial";
|
||||
}
|
||||
if ("smallint".equalsIgnoreCase(columnDefn)) {
|
||||
return "smallserial";
|
||||
}
|
||||
return columnDefn;
|
||||
}
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Postgres specific DDL.
|
||||
*/
|
||||
public class PostgresDdl extends PlatformDdl {
|
||||
|
||||
private static final String dropIndexConcurrentlyIfExists = "drop index concurrently if exists ";
|
||||
|
||||
public PostgresDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.historyDdl = new PostgresHistoryDdl();
|
||||
this.dropTableCascade = " cascade";
|
||||
this.columnSetType = "type ";
|
||||
this.alterTableIfExists = "if exists ";
|
||||
this.columnSetNull = "drop not null";
|
||||
this.addForeignKeySkipCheck = " not valid";
|
||||
this.indexConcurrent = "concurrently ";
|
||||
}
|
||||
|
||||
public String setLockTimeout(int lockTimeoutSeconds) {
|
||||
return "set lock_timeout = " + (lockTimeoutSeconds * 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean suppressPrimaryKeyOnPartition() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String convertArrayType(String logicalArrayType) {
|
||||
return NativeDbArray.logicalToNative(logicalArrayType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
|
||||
apply.append(" partition by range (").append(partitionColumn).append(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
return (concurrent ? dropIndexConcurrentlyIfExists : dropIndexIfExists) + maxConstraintName(indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify and return the column definition for autoincrement or identity definition.
|
||||
*/
|
||||
@Override
|
||||
public String asIdentityColumn(String columnDefn, DdlIdentity identity) {
|
||||
return asIdentityStandardOptions(columnDefn, identity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
return super.alterColumnType(tableName, columnName, type) + " using " + columnName + "::" + convert(type);
|
||||
}
|
||||
}
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Uses DB triggers to maintain a history table.
|
||||
*/
|
||||
public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
|
||||
PostgresHistoryDdl() {
|
||||
this.now = "current_timestamp";
|
||||
this.sysPeriodEndValue = "current_timestamp";
|
||||
}
|
||||
|
||||
/**
|
||||
* Use Postgres create table like to create the history table.
|
||||
*/
|
||||
@Override
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
|
||||
|
||||
String baseTable = table.getName();
|
||||
apply
|
||||
.append("create table ").append(baseTable).append(historySuffix)
|
||||
.append("(like ").append(baseTable).append(")").endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use Postgres range type rather than start and end timestamps.
|
||||
*/
|
||||
@Override
|
||||
protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
|
||||
apply
|
||||
.append("alter table ").append(baseTableName)
|
||||
.append(" add column ").append(sysPeriod).append(" tstzrange not null default tstzrange(").append(now).append(", null)")
|
||||
.endOfStatement();
|
||||
|
||||
if (whenCreatedColumn != null) {
|
||||
apply.append("update ").append(baseTableName).append(" set ")
|
||||
.append(sysPeriod).append(" = tstzrange(").append(whenCreatedColumn).append(", null)").endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
|
||||
appendColumnName(apply, prefix, sysPeriod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropSysPeriodColumns(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
buffer.append("alter table ").append(baseTableName).append(" drop column ").append(sysPeriod).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String baseTableName = table.getName();
|
||||
String procedureName = procedureName(baseTableName);
|
||||
String triggerName = triggerName(baseTableName);
|
||||
|
||||
DdlBuffer apply = writer.applyHistoryTrigger();
|
||||
apply
|
||||
.append("create trigger ").append(triggerName).newLine()
|
||||
.append(" before update or delete on ").append(baseTableName).newLine()
|
||||
.append(" for each row execute procedure ").append(procedureName).append("();").newLine().newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
// rollback trigger then function
|
||||
buffer.append("drop trigger if exists ").append(triggerName(baseTable)).append(" on ").append(baseTable).append(" cascade").endOfStatement();
|
||||
buffer.append("drop function if exists ").append(procedureName(baseTable)).append("()").endOfStatement();
|
||||
buffer.end();
|
||||
}
|
||||
|
||||
protected void createOrReplaceFunction(DdlBuffer apply, String procedureName, String historyTable, List<String> includedColumns) throws IOException {
|
||||
apply
|
||||
.append("create or replace function ").append(procedureName).append("() returns trigger as $$").newLine();
|
||||
|
||||
apply.append("declare").newLine()
|
||||
.append(" lowerTs timestamptz;").newLine()
|
||||
.append(" upperTs timestamptz;").newLine();
|
||||
|
||||
apply.append("begin").newLine()
|
||||
.append(" lowerTs = lower(OLD.sys_period);").newLine()
|
||||
.append(" upperTs = greatest(lowerTs + '1 microsecond',current_timestamp);").newLine();
|
||||
|
||||
apply
|
||||
.append(" if (TG_OP = 'UPDATE') then").newLine();
|
||||
appendInsertIntoHistory(apply, historyTable, includedColumns);
|
||||
apply
|
||||
.append(" NEW.").append(sysPeriod).append(" = tstzrange(upperTs,null);").newLine()
|
||||
.append(" return new;").newLine();
|
||||
apply
|
||||
.append(" elsif (TG_OP = 'DELETE') then").newLine();
|
||||
appendInsertIntoHistory(apply, historyTable, includedColumns);
|
||||
apply
|
||||
.append(" return old;").newLine();
|
||||
apply
|
||||
.append(" end if;").newLine()
|
||||
.append("end;").newLine()
|
||||
.append("$$ LANGUAGE plpgsql;").newLine();
|
||||
|
||||
apply.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createStoredFunction(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
String procedureName = procedureName(table.getName());
|
||||
String historyTable = historyTableName(table.getName());
|
||||
|
||||
List<String> columnNames = columnNamesForApply(table);
|
||||
createOrReplaceFunction(writer.applyHistoryTrigger(), procedureName, historyTable, columnNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
|
||||
String procedureName = procedureName(update.getBaseTable());
|
||||
|
||||
recreateHistoryView(update);
|
||||
createOrReplaceFunction(update.historyTriggerBuffer(), procedureName, update.getHistoryTable(), update.getColumns());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List<String> columns) throws IOException {
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriod).append(",");
|
||||
appendColumnNames(buffer, columns, "");
|
||||
buffer.append(") values (tstzrange(lowerTs,upperTs), ");
|
||||
appendColumnNames(buffer, columns, "OLD.");
|
||||
buffer.append(");").newLine();
|
||||
}
|
||||
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
|
||||
/**
|
||||
* DB2 platform specific DDL.
|
||||
*/
|
||||
public class SQLiteDdl extends PlatformDdl {
|
||||
|
||||
public SQLiteDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.identitySuffix = "";
|
||||
this.inlineForeignKeys = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
// not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
|
||||
// not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
|
||||
// not supported
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
public class SplitColumns {
|
||||
|
||||
/**
|
||||
* Return as an array of string column names.
|
||||
*/
|
||||
public static String[] split(String columns) {
|
||||
if (columns == null || columns.isEmpty()) {
|
||||
return new String[0];
|
||||
}
|
||||
return columns.split(",");
|
||||
}
|
||||
|
||||
/**
|
||||
* Split returning null when columns is null or empty.
|
||||
*/
|
||||
public static String[] splitWithNull(String columns) {
|
||||
if (columns == null || columns.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return columns.split(",");
|
||||
}
|
||||
}
|
||||
-251
@@ -1,251 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.server.persist.platform.MultiValueBind;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* MS SQL Server platform specific DDL.
|
||||
*/
|
||||
public class SqlServerDdl extends PlatformDdl {
|
||||
|
||||
public SqlServerDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.identitySuffix = " identity(1,1)";
|
||||
this.alterTableIfExists = "";
|
||||
this.addColumn = "add";
|
||||
this.inlineUniqueWhenNullable = false;
|
||||
this.columnSetDefault = "add default";
|
||||
this.dropConstraintIfExists = "drop constraint";
|
||||
this.historyDdl = new SqlServerHistoryDdl();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyMode(StringBuilder buffer, String onMode, ConstraintMode mode) {
|
||||
if (mode != ConstraintMode.RESTRICT) {
|
||||
super.appendForeignKeyMode(buffer, onMode, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropTable(String tableName) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("IF OBJECT_ID('");
|
||||
buffer.append(tableName);
|
||||
buffer.append("', 'U') IS NOT NULL drop table ");
|
||||
buffer.append(tableName);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
int pos = tableName.lastIndexOf('.');
|
||||
String objectId = maxConstraintName(fkName);
|
||||
if (pos != -1) {
|
||||
objectId = tableName.substring(0, pos + 1) + fkName;
|
||||
}
|
||||
return "IF OBJECT_ID('" + objectId + "', 'F') IS NOT NULL " + super.alterTableDropForeignKey(tableName, fkName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropSequence(String sequenceName) {
|
||||
return "IF OBJECT_ID('" + sequenceName + "', 'SO') IS NOT NULL drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
return "IF EXISTS (SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('" + tableName + "','U') AND name = '"
|
||||
+ maxConstraintName(indexName) + "') drop index " + maxConstraintName(indexName) + " ON " + tableName;
|
||||
}
|
||||
/**
|
||||
* MsSqlServer specific null handling on unique constraints.
|
||||
*/
|
||||
@Override
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
|
||||
if (nullableColumns == null || nullableColumns.length == 0) {
|
||||
return super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
|
||||
}
|
||||
if (uqName == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
// issues#233
|
||||
String start = "create unique nonclustered index " + uqName + " on " + tableName + "(";
|
||||
StringBuilder sb = new StringBuilder(start);
|
||||
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(columns[i]);
|
||||
}
|
||||
sb.append(") where");
|
||||
String sep = " ";
|
||||
for (String column : nullableColumns) {
|
||||
sb.append(sep).append(column).append(" is not null");
|
||||
sep = " and ";
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("IF (OBJECT_ID('").append(constraintName).append("', 'C') IS NOT NULL) ");
|
||||
sb.append(super.alterTableDropConstraint(tableName, constraintName));
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* Drop a unique constraint from the table (Sometimes this is an index).
|
||||
*/
|
||||
@Override
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(dropIndex(uniqueConstraintName, tableName)).append(";\n");
|
||||
sb.append("IF (OBJECT_ID('").append(maxConstraintName(uniqueConstraintName)).append("', 'UQ') IS NOT NULL) ");
|
||||
sb.append(super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName));
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* Generate and return the create sequence DDL.
|
||||
*/
|
||||
@Override
|
||||
public String createSequence(String sequenceName, DdlIdentity identity) {
|
||||
StringBuilder sb = new StringBuilder(80);
|
||||
sb.append("create sequence ").append(sequenceName).append(" as bigint");
|
||||
final int start = identity.getStart();
|
||||
if (start > 1) {
|
||||
sb.append(" start with ").append(start);
|
||||
} else {
|
||||
sb.append(" start with 1");
|
||||
}
|
||||
final int increment = identity.getIncrement();
|
||||
if (increment > 1) {
|
||||
sb.append(" increment by ").append(increment);
|
||||
}
|
||||
final int cache = identity.getCache();
|
||||
if (cache > 1) {
|
||||
sb.append(" cache ").append(increment);
|
||||
}
|
||||
sb.append(";");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
// Unfortunately, the SqlServer creates default values with a random name.
|
||||
// You can specify a name in DDL, but this does not work in conjunction with
|
||||
// temporal tables in certain cases. So we have to delete the constraint with
|
||||
// a rather complex statement.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (DdlHelp.isDropDefault(defaultValue)) {
|
||||
sb.append("EXEC usp_ebean_drop_default_constraint ").append(tableName).append(", ").append(columnName);
|
||||
} else {
|
||||
sb.append("alter table ").append(tableName);
|
||||
sb.append(" add default ").append(convertDefaultValue(defaultValue)).append(" for ").append(columnName);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
if (alter.getType() == null && alter.isNotnull() == null) {
|
||||
// No type change or notNull change
|
||||
// defaultValue change already handled in alterColumnDefaultValue
|
||||
return null;
|
||||
}
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
type = convert(type);
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String notnullClause = notnull ? " not null" : "";
|
||||
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + type + notnullClause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table comment as a separate statement (from the create table statement).
|
||||
*/
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
|
||||
|
||||
// do nothing for MS SQL Server (cause it requires stored procedures etc)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column comment as a separate statement.
|
||||
*/
|
||||
@Override
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) throws IOException {
|
||||
|
||||
// do nothing for MS SQL Server (cause it requires stored procedures etc)
|
||||
}
|
||||
|
||||
/**
|
||||
* It is rather complex to delete a column on SqlServer as there must not exist any references
|
||||
* (constraints, default values, indices and foreign keys). That's why we call a user stored procedure here
|
||||
*/
|
||||
@Override
|
||||
public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
|
||||
buffer.append("EXEC usp_ebean_drop_column ").append(tableName).append(", ").append(columnName).endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* This writes the multi value datatypes needed for {@link MultiValueBind}
|
||||
*/
|
||||
@Override
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
super.generateProlog(write);
|
||||
|
||||
generateTVPDefinitions(write, "bigint");
|
||||
generateTVPDefinitions(write, "float");
|
||||
generateTVPDefinitions(write, "bit");
|
||||
generateTVPDefinitions(write, "date");
|
||||
generateTVPDefinitions(write, "time");
|
||||
//generateTVPDefinitions(write, "datetime2");
|
||||
generateTVPDefinitions(write, "uniqueidentifier");
|
||||
generateTVPDefinitions(write, "nvarchar(max)");
|
||||
|
||||
}
|
||||
|
||||
private void generateTVPDefinitions(DdlWrite write, String definition) throws IOException {
|
||||
int pos = definition.indexOf('(');
|
||||
String name = pos == -1 ? definition : definition.substring(0, pos);
|
||||
|
||||
dropTVP(write.dropAll(), name);
|
||||
//TVPs are included in "I__create_procs.sql"
|
||||
//createTVP(write.apply(), name, definition);
|
||||
}
|
||||
|
||||
private void dropTVP(DdlBuffer ddl, String name) throws IOException {
|
||||
ddl.append("if exists (select name from sys.types where name = 'ebean_").append(name)
|
||||
.append("_tvp') drop type ebean_").append(name).append("_tvp").endOfStatement();
|
||||
}
|
||||
|
||||
private void createTVP(DdlBuffer ddl, String name, String definition) throws IOException {
|
||||
ddl.append("if not exists (select name from sys.types where name = 'ebean_").append(name)
|
||||
.append("_tvp') create type ebean_").append(name).append("_tvp as table (c1 ").append(definition).append(")")
|
||||
.endOfStatement();
|
||||
}
|
||||
|
||||
}
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Vilmos Nagy <vilmos.nagy@outlook.com>
|
||||
*/
|
||||
public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
private String systemPeriodStart;
|
||||
private String systemPeriodEnd;
|
||||
private PlatformDdl platformDdl;
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
this.systemPeriodStart = config.getAsOfSysPeriod() + "From";
|
||||
this.systemPeriodEnd = config.getAsOfSysPeriod() + "To";
|
||||
this.platformDdl = platformDdl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
String baseTable = table.getName();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
|
||||
String getHistoryTable(String baseTable) {
|
||||
String historyTable = baseTable + "_history";
|
||||
if (baseTable.startsWith("[")) {
|
||||
historyTable = historyTable.replace("]", "") + "]";
|
||||
}
|
||||
if (historyTable.indexOf('.') == -1) {
|
||||
// history must contain schema, add the default schema if none was specified
|
||||
historyTable = "dbo." + historyTable;
|
||||
}
|
||||
return historyTable;
|
||||
}
|
||||
|
||||
private void enableSystemVersioning(DdlWrite writer, String baseTable) throws IOException {
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
apply.append("alter table ").append(baseTable).newLine()
|
||||
.append(" add ").append(systemPeriodStart).append(" datetime2 GENERATED ALWAYS AS ROW START NOT NULL DEFAULT SYSUTCDATETIME(),").newLine()
|
||||
.append(" ").append(systemPeriodEnd).append(" datetime2 GENERATED ALWAYS AS ROW END NOT NULL DEFAULT '9999-12-31T23:59:59.9999999',").newLine()
|
||||
.append("period for system_time (").append(systemPeriodStart).append(", ").append(systemPeriodEnd).append(")").endOfStatement();
|
||||
|
||||
apply.append("alter table ").append(baseTable).append(" set (system_versioning = on (history_table=")
|
||||
.append(getHistoryTable(baseTable)).append("))").endOfStatement();
|
||||
|
||||
DdlBuffer drop = writer.dropAll();
|
||||
drop.append("IF OBJECT_ID('").append(baseTable).append("', 'U') IS NOT NULL alter table ").append(baseTable).append(" set (system_versioning = off)").endOfStatement();
|
||||
drop.append("IF OBJECT_ID('").append(baseTable).append("_history', 'U') IS NOT NULL drop table ").append(baseTable).append("_history").endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
String baseTable = dropHistoryTable.getBaseTable();
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
apply.append("-- dropping history support for ").append(baseTable).endOfStatement();
|
||||
// drop default constraints
|
||||
|
||||
apply.append(platformDdl.alterColumnDefaultValue(baseTable, systemPeriodStart, DdlHelp.DROP_DEFAULT)).endOfStatement();
|
||||
apply.append(platformDdl.alterColumnDefaultValue(baseTable, systemPeriodEnd, DdlHelp.DROP_DEFAULT)).endOfStatement();
|
||||
// switch of versioning & period
|
||||
apply.append("alter table ").append(baseTable).append(" set (system_versioning = off)").endOfStatement();
|
||||
apply.append("alter table ").append(baseTable).append(" drop period for system_time").endOfStatement();
|
||||
// now drop tables & columns
|
||||
apply.append("alter table ").append(baseTable).append(" drop column ").append(systemPeriodStart).endOfStatement();
|
||||
apply.append("alter table ").append(baseTable).append(" drop column ").append(systemPeriodEnd).endOfStatement();
|
||||
apply.append("IF OBJECT_ID('").append(baseTable).append("_history', 'U') IS NOT NULL drop table ").append(baseTable).append("_history").endOfStatement();
|
||||
apply.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
String baseTable = addHistoryTable.getBaseTable();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, HistoryTableUpdate baseTable) throws IOException {
|
||||
// SQL Server 2016 does not need triggers
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
String baseTableName = baseTable.getBaseTable();
|
||||
apply.append("-- alter table ").append(baseTableName).append(" set (system_versioning = off (history_table=")
|
||||
.append(getHistoryTable(baseTableName)).append("))").endOfStatement();
|
||||
apply.append("-- history migration goes here").newLine();
|
||||
apply.append("-- alter table ").append(baseTableName).append(" set (system_versioning = on (history_table=")
|
||||
.append(getHistoryTable(baseTableName)).append("))").endOfStatement();
|
||||
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.CreateIndex;
|
||||
|
||||
import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.split;
|
||||
|
||||
class WriteCreateIndex {
|
||||
|
||||
private final String indexName;
|
||||
private final String tableName;
|
||||
private final String[] columns;
|
||||
private final boolean unique;
|
||||
private final boolean concurrent;
|
||||
private final String definition;
|
||||
|
||||
WriteCreateIndex(String indexName, String tableName, String[] columns, boolean unique) {
|
||||
this.indexName = indexName;
|
||||
this.tableName = tableName;
|
||||
this.columns = columns;
|
||||
this.unique = unique;
|
||||
this.concurrent = false;
|
||||
this.definition = null;
|
||||
}
|
||||
|
||||
public WriteCreateIndex(CreateIndex index) {
|
||||
this.indexName = index.getIndexName();
|
||||
this.tableName = index.getTableName();
|
||||
this.columns = split(index.getColumns());
|
||||
this.unique = Boolean.TRUE.equals(index.isUnique());
|
||||
this.concurrent = Boolean.TRUE.equals(index.isConcurrent());
|
||||
this.definition = index.getDefinition();
|
||||
}
|
||||
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public String[] getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
public boolean isConcurrent() {
|
||||
return concurrent;
|
||||
}
|
||||
|
||||
public String getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
public boolean useDefinition() {
|
||||
return definition != null && !definition.isEmpty();
|
||||
}
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.ForeignKey;
|
||||
|
||||
class WriteForeignKey {
|
||||
|
||||
private final String fkName;
|
||||
private final String tableName;
|
||||
private final String[] cols;
|
||||
private String refTableName;
|
||||
private String[] refCols;
|
||||
private final String indexName;
|
||||
private final ConstraintMode onDelete;
|
||||
private final ConstraintMode onUpdate;
|
||||
|
||||
WriteForeignKey(AlterColumn alterColumn) {
|
||||
this.tableName = alterColumn.getTableName();
|
||||
this.indexName = alterColumn.getForeignKeyIndex();
|
||||
this.fkName = alterColumn.getForeignKeyName();
|
||||
this.cols = new String[]{alterColumn.getColumnName()};
|
||||
setReferences(alterColumn.getReferences());
|
||||
this.onDelete = modeOf(alterColumn.getForeignKeyOnDelete());
|
||||
this.onUpdate = modeOf(alterColumn.getForeignKeyOnUpdate());
|
||||
}
|
||||
|
||||
WriteForeignKey(String tableName, ForeignKey key) {
|
||||
this.tableName = tableName;
|
||||
this.indexName = key.getIndexName();
|
||||
this.fkName = key.getName();
|
||||
this.cols = toCols(key.getColumnNames());
|
||||
this.refTableName = key.getRefTableName();
|
||||
this.refCols = toCols(key.getRefColumnNames());
|
||||
this.onDelete = modeOf(key.getOnDelete());
|
||||
this.onUpdate = modeOf(key.getOnUpdate());
|
||||
}
|
||||
|
||||
WriteForeignKey(AlterForeignKey key) {
|
||||
this.tableName = key.getTableName();
|
||||
this.indexName = key.getIndexName();
|
||||
this.fkName = key.getName();
|
||||
this.cols = toCols(key.getColumnNames());
|
||||
this.refTableName = key.getRefTableName();
|
||||
this.refCols = toCols(key.getRefColumnNames());
|
||||
this.onDelete = modeOf(key.getOnDelete());
|
||||
this.onUpdate = modeOf(key.getOnUpdate());
|
||||
}
|
||||
|
||||
WriteForeignKey(String tableName, Column column) {
|
||||
this.tableName = tableName;
|
||||
this.indexName = column.getForeignKeyIndex();
|
||||
this.fkName = column.getForeignKeyName();
|
||||
this.cols = new String[]{column.getName()};
|
||||
setReferences(column.getReferences());
|
||||
this.onDelete = modeOf(column.getForeignKeyOnDelete());
|
||||
this.onUpdate = modeOf(column.getForeignKeyOnUpdate());
|
||||
}
|
||||
|
||||
private void setReferences(String references) {
|
||||
int pos = references.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
throw new IllegalStateException("Expecting period '.' character for table.column split but not found in [" + references + "]");
|
||||
}
|
||||
this.refTableName = references.substring(0, pos);
|
||||
String refColumnName = references.substring(pos + 1);
|
||||
this.refCols = new String[]{refColumnName};
|
||||
}
|
||||
|
||||
private String[] toCols(String columns) {
|
||||
return SplitColumns.split(columns);
|
||||
}
|
||||
|
||||
private ConstraintMode modeOf(String value) {
|
||||
return (value == null) ? null : ConstraintMode.valueOf(value);
|
||||
}
|
||||
|
||||
public String table() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public String[] cols() {
|
||||
return cols;
|
||||
}
|
||||
|
||||
public String indexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
public String fkName() {
|
||||
return fkName;
|
||||
}
|
||||
|
||||
public String refTable() {
|
||||
return refTableName;
|
||||
}
|
||||
|
||||
public String[] refCols() {
|
||||
return refCols;
|
||||
}
|
||||
|
||||
public ConstraintMode onDelete() {
|
||||
return onDelete;
|
||||
}
|
||||
|
||||
public ConstraintMode onUpdate() {
|
||||
return onUpdate;
|
||||
}
|
||||
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class WriteUniqueConstraint {
|
||||
|
||||
private final List<Column> primaryKeys = new ArrayList<>();
|
||||
private final List<Column> uniqueKeys = new ArrayList<>();
|
||||
|
||||
WriteUniqueConstraint(List<Column> columns) {
|
||||
|
||||
// filter for unique and primary keys
|
||||
for (Column column : columns) {
|
||||
if (Boolean.TRUE.equals(column.isPrimaryKey())) {
|
||||
primaryKeys.add(column);
|
||||
}
|
||||
if (hasValue(column.getUnique()) || hasValue(column.getUniqueOneToOne())){
|
||||
uniqueKeys.add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if null or trimmed string is empty.
|
||||
*/
|
||||
boolean hasValue(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the single columns with unique constraints (that are not the primary key).
|
||||
*/
|
||||
public List<Column> uniqueKeys() {
|
||||
if (uniqueKeys.isEmpty() || primaryKeys.size() > 1) {
|
||||
// all single column unique constraints are valid
|
||||
return uniqueKeys;
|
||||
}
|
||||
// filter out PFK
|
||||
for (Column primaryKey : primaryKeys) {
|
||||
uniqueKeys.remove(primaryKey);
|
||||
}
|
||||
return uniqueKeys;
|
||||
}
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Set of columns making up a particular index (column order is important).
|
||||
*/
|
||||
public class IndexColumns {
|
||||
|
||||
List<String> columns = new ArrayList<>(4);
|
||||
|
||||
/**
|
||||
* Construct representing as a single column index.
|
||||
*/
|
||||
public IndexColumns(String column) {
|
||||
columns.add(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct representing index.
|
||||
*/
|
||||
public IndexColumns(String[] columnNames) {
|
||||
Collections.addAll(columns, columnNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this index matches (same single column).
|
||||
*/
|
||||
public boolean isMatch(String singleColumn) {
|
||||
return columns.size() == 1 && columns.get(0).equals(singleColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this index matches (same single column).
|
||||
*/
|
||||
public boolean isMatch(List<String> columnNames) {
|
||||
if (columns.size() != columnNames.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (!columns.get(i).equals(columnNames.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this index matches (same columns same order).
|
||||
*/
|
||||
public boolean isMatch(IndexColumns other) {
|
||||
return columns.equals(other.columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a unique index based on the single column.
|
||||
*/
|
||||
protected void add(String column) {
|
||||
columns.add(column);
|
||||
}
|
||||
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The indexes held on the table.
|
||||
* <p>
|
||||
* Used to detect when we don't need to add an index on the foreign key columns
|
||||
* when there is an existing unique constraint with the same columns.
|
||||
*/
|
||||
public class IndexSet {
|
||||
|
||||
private List<IndexColumns> indexes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Clear the indexes (for each table).
|
||||
*/
|
||||
public void clear() {
|
||||
indexes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index for the given column.
|
||||
*/
|
||||
public void add(String column) {
|
||||
indexes.add(new IndexColumns(column));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if an index should be added for the given columns.
|
||||
* <p>
|
||||
* Returning false indicates there is an existing index (unique constraint) with these columns
|
||||
* and that an extra index should not be added.
|
||||
* </p>
|
||||
*/
|
||||
public boolean add(String[] columns) {
|
||||
IndexColumns newIndex = new IndexColumns(columns);
|
||||
for (IndexColumns indexe : indexes) {
|
||||
if (indexe.isMatch(newIndex)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
indexes.add(newIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the externally created unique constraint here so that we check later if foreign key indexes
|
||||
* don't need to be created (as the columns match this unique constraint).
|
||||
*/
|
||||
public void add(IndexColumns index) {
|
||||
indexes.add(index);
|
||||
}
|
||||
|
||||
public boolean contains(String column) {
|
||||
|
||||
for (IndexColumns index : indexes) {
|
||||
if (index.isMatch(column)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(List<String> columns) {
|
||||
|
||||
for (IndexColumns index : indexes) {
|
||||
if (index.isMatch(columns)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<IndexColumns> getIndexes() {
|
||||
return indexes;
|
||||
}
|
||||
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform.util;
|
||||
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebean.config.dbplatform.DbPlatformTypeMapping;
|
||||
|
||||
/**
|
||||
* Converts a logical column definition into platform specific one.
|
||||
* <p>
|
||||
* This translates standard sql types into platform specific ones.
|
||||
*/
|
||||
public class PlatformTypeConverter {
|
||||
|
||||
protected final DbPlatformTypeMapping platformTypes;
|
||||
|
||||
/**
|
||||
* Construct with the platform specific types.
|
||||
*/
|
||||
public PlatformTypeConverter(DbPlatformTypeMapping platformTypes) {
|
||||
this.platformTypes = platformTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the standard type to the platform specific type.
|
||||
*/
|
||||
public String convert(String columnDefinition) {
|
||||
|
||||
int open = columnDefinition.indexOf('(');
|
||||
if (open > -1) {
|
||||
// no scale or precision
|
||||
return convertWithScale(columnDefinition, open);
|
||||
} else {
|
||||
return convertNoScale(columnDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a type that has scale and possibly precision.
|
||||
*/
|
||||
protected String convertWithScale(String columnDefinition, int open) {
|
||||
|
||||
int close = columnDefinition.lastIndexOf(')');
|
||||
if (close == -1) {
|
||||
// assume already platform specific, leave as is
|
||||
return columnDefinition;
|
||||
}
|
||||
|
||||
String suffix = close + 1 < columnDefinition.length() ? columnDefinition.substring(close + 1) : "";
|
||||
String type = columnDefinition.substring(0, open);
|
||||
try {
|
||||
DbPlatformType dbType = platformTypes.lookup(type, true);
|
||||
int comma = columnDefinition.indexOf(',', open);
|
||||
if (comma > -1) {
|
||||
// scale and precision - decimal(10,4)
|
||||
int scale = Integer.parseInt(columnDefinition.substring(open + 1, comma));
|
||||
int precision = Integer.parseInt(columnDefinition.substring(comma + 1, close));
|
||||
return dbType.renderType(scale, precision) + suffix;
|
||||
|
||||
} else {
|
||||
// scale - varchar(10)
|
||||
int scale = Integer.parseInt(columnDefinition.substring(open + 1, close));
|
||||
return dbType.renderType(scale, -1) + suffix;
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
// assume already platform specific, leave as is
|
||||
return columnDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a simple type with not scale or precision.
|
||||
*/
|
||||
protected String convertNoScale(String columnDefinition) {
|
||||
|
||||
try {
|
||||
DbPlatformType dbType = platformTypes.lookup(columnDefinition, false);
|
||||
return dbType.renderType(0, 0);
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
// assume already platform specific, leave as is
|
||||
return columnDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform.util;
|
||||
|
||||
/**
|
||||
* Utility to remove vowels (from constraint names primarily for Oracle and DB2).
|
||||
*/
|
||||
public class VowelRemover {
|
||||
|
||||
/**
|
||||
* Trim a word by removing vowels skipping some initial characters.
|
||||
*/
|
||||
public static String trim(String word, int skipChars) {
|
||||
|
||||
if (word.length() < skipChars) {
|
||||
return word;
|
||||
}
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
res.append(word.substring(0, skipChars));
|
||||
|
||||
for (int i = skipChars; i < word.length(); i++) {
|
||||
char ch = word.charAt(i);
|
||||
if (!isVowel(ch)) {
|
||||
res.append(ch);
|
||||
}
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
private static boolean isVowel(char ch) {
|
||||
ch = Character.toLowerCase(ch);
|
||||
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}column" maxOccurs="unbounded"/>
|
||||
* </sequence>
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"column"
|
||||
})
|
||||
@XmlRootElement(name = "addColumn")
|
||||
public class AddColumn {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected List<Column> column;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
|
||||
/**
|
||||
* Gets the value of the column property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the column property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getColumn().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Column }
|
||||
*/
|
||||
public List<Column> getColumn() {
|
||||
if (column == null) {
|
||||
column = new ArrayList<>();
|
||||
}
|
||||
return this.column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the withHistory property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the withHistory property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setWithHistory(Boolean value) {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="baseTable" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "addHistoryTable")
|
||||
public class AddHistoryTable {
|
||||
|
||||
@XmlAttribute(name = "baseTable", required = true)
|
||||
protected String baseTable;
|
||||
|
||||
/**
|
||||
* Gets the value of the baseTable property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the baseTable property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setBaseTable(String value) {
|
||||
this.baseTable = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="comment" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "addTableComment")
|
||||
public class AddTableComment {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "comment", required = true)
|
||||
protected String comment;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the comment property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the comment property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setComment(String value) {
|
||||
this.comment = value;
|
||||
}
|
||||
|
||||
}
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="constraintName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="oneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="nullableColumns" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="platforms" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "addUniqueConstraint")
|
||||
public class AddUniqueConstraint {
|
||||
|
||||
@XmlAttribute(name = "constraintName", required = true)
|
||||
protected String constraintName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "columnNames", required = true)
|
||||
protected String columnNames;
|
||||
@XmlAttribute(name = "oneToOne")
|
||||
protected Boolean oneToOne;
|
||||
@XmlAttribute(name = "nullableColumns")
|
||||
protected String nullableColumns;
|
||||
@XmlAttribute(name = "platforms")
|
||||
protected String platforms;
|
||||
|
||||
/**
|
||||
* Gets the value of the constraintName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getConstraintName() {
|
||||
return constraintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the constraintName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setConstraintName(String value) {
|
||||
this.constraintName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columnNames property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnNames property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setColumnNames(String value) {
|
||||
this.columnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the oneToOne property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isOneToOne() {
|
||||
return oneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oneToOne property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setOneToOne(Boolean value) {
|
||||
this.oneToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the nullableColumns property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getNullableColumns() {
|
||||
return nullableColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the nullableColumns property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setNullableColumns(String value) {
|
||||
this.nullableColumns = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the platforms property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the platforms property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPlatforms(String value) {
|
||||
this.platforms = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,647 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="before" type="{http://ebean-orm.github.io/xml/ns/dbmigration}ddl-script" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* <element name="after" type="{http://ebean-orm.github.io/xml/ns/dbmigration}ddl-script" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* <attribute name="columnName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="currentType" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="defaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="currentDefaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="currentNotnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="comment" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="checkConstraintName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropCheckConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropUnique" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="references" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyIndex" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyOnDelete" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyOnUpdate" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropForeignKey" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dropForeignKeyIndex" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"before",
|
||||
"after"
|
||||
})
|
||||
@XmlRootElement(name = "alterColumn")
|
||||
public class AlterColumn {
|
||||
|
||||
protected List<DdlScript> before;
|
||||
protected List<DdlScript> after;
|
||||
@XmlAttribute(name = "columnName", required = true)
|
||||
protected String columnName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
@XmlAttribute(name = "type")
|
||||
protected String type;
|
||||
@XmlAttribute(name = "currentType")
|
||||
protected String currentType;
|
||||
@XmlAttribute(name = "defaultValue")
|
||||
protected String defaultValue;
|
||||
@XmlAttribute(name = "currentDefaultValue")
|
||||
protected String currentDefaultValue;
|
||||
@XmlAttribute(name = "notnull")
|
||||
protected Boolean notnull;
|
||||
@XmlAttribute(name = "currentNotnull")
|
||||
protected Boolean currentNotnull;
|
||||
@XmlAttribute(name = "comment")
|
||||
protected String comment;
|
||||
@XmlAttribute(name = "historyExclude")
|
||||
protected Boolean historyExclude;
|
||||
@XmlAttribute(name = "checkConstraint")
|
||||
protected String checkConstraint;
|
||||
@XmlAttribute(name = "checkConstraintName")
|
||||
protected String checkConstraintName;
|
||||
@XmlAttribute(name = "dropCheckConstraint")
|
||||
protected String dropCheckConstraint;
|
||||
@XmlAttribute(name = "unique")
|
||||
protected String unique;
|
||||
@XmlAttribute(name = "uniqueOneToOne")
|
||||
protected String uniqueOneToOne;
|
||||
@XmlAttribute(name = "dropUnique")
|
||||
protected String dropUnique;
|
||||
@XmlAttribute(name = "references")
|
||||
protected String references;
|
||||
@XmlAttribute(name = "foreignKeyName")
|
||||
protected String foreignKeyName;
|
||||
@XmlAttribute(name = "foreignKeyIndex")
|
||||
protected String foreignKeyIndex;
|
||||
@XmlAttribute(name = "foreignKeyOnDelete")
|
||||
protected String foreignKeyOnDelete;
|
||||
@XmlAttribute(name = "foreignKeyOnUpdate")
|
||||
protected String foreignKeyOnUpdate;
|
||||
@XmlAttribute(name = "dropForeignKey")
|
||||
protected String dropForeignKey;
|
||||
@XmlAttribute(name = "dropForeignKeyIndex")
|
||||
protected String dropForeignKeyIndex;
|
||||
|
||||
/**
|
||||
* Gets the value of the before property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the before property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getBefore().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link DdlScript }
|
||||
*/
|
||||
public List<DdlScript> getBefore() {
|
||||
if (before == null) {
|
||||
before = new ArrayList<>();
|
||||
}
|
||||
return this.before;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the after property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the after property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getAfter().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link DdlScript }
|
||||
*/
|
||||
public List<DdlScript> getAfter() {
|
||||
if (after == null) {
|
||||
after = new ArrayList<>();
|
||||
}
|
||||
return this.after;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columnName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setColumnName(String value) {
|
||||
this.columnName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the withHistory property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the withHistory property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setWithHistory(Boolean value) {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the type property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the type property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setType(String value) {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the currentType property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getCurrentType() {
|
||||
return currentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the currentType property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setCurrentType(String value) {
|
||||
this.currentType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the defaultValue property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the defaultValue property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDefaultValue(String value) {
|
||||
this.defaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the currentDefaultValue property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getCurrentDefaultValue() {
|
||||
return currentDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the currentDefaultValue property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setCurrentDefaultValue(String value) {
|
||||
this.currentDefaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the notnull property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isNotnull() {
|
||||
return notnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the notnull property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setNotnull(Boolean value) {
|
||||
this.notnull = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the currentNotnull property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isCurrentNotnull() {
|
||||
return currentNotnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the currentNotnull property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setCurrentNotnull(Boolean value) {
|
||||
this.currentNotnull = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the comment property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the comment property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setComment(String value) {
|
||||
this.comment = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the historyExclude property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isHistoryExclude() {
|
||||
return historyExclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the historyExclude property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setHistoryExclude(Boolean value) {
|
||||
this.historyExclude = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraint property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraint property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setCheckConstraint(String value) {
|
||||
this.checkConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraintName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getCheckConstraintName() {
|
||||
return checkConstraintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraintName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setCheckConstraintName(String value) {
|
||||
this.checkConstraintName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dropCheckConstraint property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDropCheckConstraint() {
|
||||
return dropCheckConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dropCheckConstraint property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDropCheckConstraint(String value) {
|
||||
this.dropCheckConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the unique property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the unique property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setUnique(String value) {
|
||||
this.unique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getUniqueOneToOne() {
|
||||
return uniqueOneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setUniqueOneToOne(String value) {
|
||||
this.uniqueOneToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dropUnique property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDropUnique() {
|
||||
return dropUnique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dropUnique property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDropUnique(String value) {
|
||||
this.dropUnique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the references property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the references property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setReferences(String value) {
|
||||
this.references = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyName() {
|
||||
return foreignKeyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyName(String value) {
|
||||
this.foreignKeyName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyIndex() {
|
||||
return foreignKeyIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyIndex(String value) {
|
||||
this.foreignKeyIndex = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyOnDelete property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyOnDelete() {
|
||||
return foreignKeyOnDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyOnDelete property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyOnDelete(String value) {
|
||||
this.foreignKeyOnDelete = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyOnUpdate property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyOnUpdate() {
|
||||
return foreignKeyOnUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyOnUpdate property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyOnUpdate(String value) {
|
||||
this.foreignKeyOnUpdate = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dropForeignKey property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDropForeignKey() {
|
||||
return dropForeignKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dropForeignKey property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDropForeignKey(String value) {
|
||||
this.dropForeignKey = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dropForeignKeyIndex property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDropForeignKeyIndex() {
|
||||
return dropForeignKeyIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dropForeignKeyIndex property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDropForeignKeyIndex(String value) {
|
||||
this.dropForeignKeyIndex = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columnNames" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="refColumnNames" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="refTableName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="indexName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="onDelete" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="onUpdate" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "alterForeignKey")
|
||||
public class AlterForeignKey {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "columnNames")
|
||||
protected String columnNames;
|
||||
@XmlAttribute(name = "refColumnNames")
|
||||
protected String refColumnNames;
|
||||
@XmlAttribute(name = "refTableName")
|
||||
protected String refTableName;
|
||||
@XmlAttribute(name = "indexName")
|
||||
protected String indexName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "onDelete")
|
||||
protected String onDelete;
|
||||
@XmlAttribute(name = "onUpdate")
|
||||
protected String onUpdate;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columnNames property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnNames property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setColumnNames(String value) {
|
||||
this.columnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the refColumnNames property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getRefColumnNames() {
|
||||
return refColumnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the refColumnNames property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setRefColumnNames(String value) {
|
||||
this.refColumnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the refTableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getRefTableName() {
|
||||
return refTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the refTableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setRefTableName(String value) {
|
||||
this.refTableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the indexName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setIndexName(String value) {
|
||||
this.indexName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the onDelete property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getOnDelete() {
|
||||
return onDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the onDelete property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setOnDelete(String value) {
|
||||
this.onDelete = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the onUpdate property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getOnUpdate() {
|
||||
return onUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the onUpdate property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setOnUpdate(String value) {
|
||||
this.onUpdate = value;
|
||||
}
|
||||
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="baseTable" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "alterHistoryTable")
|
||||
public class AlterHistoryTable {
|
||||
|
||||
@XmlAttribute(name = "baseTable", required = true)
|
||||
protected String baseTable;
|
||||
|
||||
/**
|
||||
* Gets the value of the baseTable property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the baseTable property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setBaseTable(String value) {
|
||||
this.baseTable = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
* <p>
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="resourcePath" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "application")
|
||||
public class Application {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "resourcePath", required = true)
|
||||
protected String resourcePath;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the resourcePath property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getResourcePath() {
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the resourcePath property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setResourcePath(String value) {
|
||||
this.resourcePath = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
* <p>
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}application" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"application"
|
||||
})
|
||||
@XmlRootElement(name = "applications")
|
||||
public class Applications {
|
||||
|
||||
protected List<Application> application;
|
||||
|
||||
/**
|
||||
* Gets the value of the application property.
|
||||
* <p>
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the application property.
|
||||
* <p>
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getApplication().add(newItem);
|
||||
* </pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Application }
|
||||
*/
|
||||
public List<Application> getApplication() {
|
||||
if (application == null) {
|
||||
application = new ArrayList<>();
|
||||
}
|
||||
return this.application;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <simpleContent>
|
||||
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
|
||||
* </extension>
|
||||
* </simpleContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"value"
|
||||
})
|
||||
@XmlRootElement(name = "apply")
|
||||
public class Apply {
|
||||
|
||||
@XmlValue
|
||||
protected String value;
|
||||
|
||||
/**
|
||||
* Gets the value of the value property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the value property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElements;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <choice>
|
||||
* <group ref="{http://ebean-orm.github.io/xml/ns/dbmigration}changeSetChildren" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </choice>
|
||||
* </sequence>
|
||||
* <attribute name="type" use="required" type="{http://ebean-orm.github.io/xml/ns/dbmigration}changeSetType" />
|
||||
* <attribute name="dropsFor" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="suppressDropsForever" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="generated" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="author" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="comment" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"changeSetChildren"
|
||||
})
|
||||
@XmlRootElement(name = "changeSet")
|
||||
public class ChangeSet {
|
||||
|
||||
@XmlElements({
|
||||
@XmlElement(name = "configuration", type = Configuration.class),
|
||||
@XmlElement(name = "sql", type = Sql.class),
|
||||
@XmlElement(name = "createTable", type = CreateTable.class),
|
||||
@XmlElement(name = "dropTable", type = DropTable.class),
|
||||
@XmlElement(name = "renameTable", type = RenameTable.class),
|
||||
@XmlElement(name = "addTableComment", type = AddTableComment.class),
|
||||
@XmlElement(name = "addUniqueConstraint", type = AddUniqueConstraint.class),
|
||||
@XmlElement(name = "addHistoryTable", type = AddHistoryTable.class),
|
||||
@XmlElement(name = "dropHistoryTable", type = DropHistoryTable.class),
|
||||
@XmlElement(name = "alterForeignKey", type = AlterForeignKey.class),
|
||||
@XmlElement(name = "addColumn", type = AddColumn.class),
|
||||
@XmlElement(name = "dropColumn", type = DropColumn.class),
|
||||
@XmlElement(name = "alterColumn", type = AlterColumn.class),
|
||||
@XmlElement(name = "renameColumn", type = RenameColumn.class),
|
||||
@XmlElement(name = "createIndex", type = CreateIndex.class),
|
||||
@XmlElement(name = "dropIndex", type = DropIndex.class)
|
||||
})
|
||||
protected List<Object> changeSetChildren;
|
||||
@XmlAttribute(name = "type", required = true)
|
||||
protected ChangeSetType type;
|
||||
@XmlAttribute(name = "dropsFor")
|
||||
protected String dropsFor;
|
||||
@XmlAttribute(name = "suppressDropsForever")
|
||||
protected Boolean suppressDropsForever;
|
||||
@XmlAttribute(name = "generated")
|
||||
protected Boolean generated;
|
||||
@XmlAttribute(name = "author")
|
||||
protected String author;
|
||||
@XmlAttribute(name = "comment")
|
||||
protected String comment;
|
||||
|
||||
/**
|
||||
* Gets the value of the changeSetChildren property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the changeSetChildren property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getChangeSetChildren().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Configuration }
|
||||
* {@link Sql }
|
||||
* {@link CreateTable }
|
||||
* {@link DropTable }
|
||||
* {@link RenameTable }
|
||||
* {@link AddTableComment }
|
||||
* {@link AddUniqueConstraint }
|
||||
* {@link AddHistoryTable }
|
||||
* {@link DropHistoryTable }
|
||||
* {@link AlterForeignKey }
|
||||
* {@link AddColumn }
|
||||
* {@link DropColumn }
|
||||
* {@link AlterColumn }
|
||||
* {@link RenameColumn }
|
||||
* {@link CreateIndex }
|
||||
* {@link DropIndex }
|
||||
*/
|
||||
public List<Object> getChangeSetChildren() {
|
||||
if (changeSetChildren == null) {
|
||||
changeSetChildren = new ArrayList<>();
|
||||
}
|
||||
return this.changeSetChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the type property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link ChangeSetType }
|
||||
*/
|
||||
public ChangeSetType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the type property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link ChangeSetType }
|
||||
*/
|
||||
public void setType(ChangeSetType value) {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dropsFor property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDropsFor() {
|
||||
return dropsFor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dropsFor property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDropsFor(String value) {
|
||||
this.dropsFor = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the suppressDropsForever property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isSuppressDropsForever() {
|
||||
return suppressDropsForever;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the suppressDropsForever property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setSuppressDropsForever(Boolean value) {
|
||||
this.suppressDropsForever = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the generated property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isGenerated() {
|
||||
return generated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the generated property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setGenerated(Boolean value) {
|
||||
this.generated = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the author property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the author property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setAuthor(String value) {
|
||||
this.author = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the comment property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the comment property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setComment(String value) {
|
||||
this.comment = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlEnum;
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for changeSetType.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <simpleType name="changeSetType">
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
|
||||
* <enumeration value="apply"/>
|
||||
* <enumeration value="pendingDrops"/>
|
||||
* <enumeration value="baseline"/>
|
||||
* <enumeration value="drop"/>
|
||||
* </restriction>
|
||||
* </simpleType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlType(name = "changeSetType")
|
||||
@XmlEnum
|
||||
public enum ChangeSetType {
|
||||
|
||||
@XmlEnumValue("apply")
|
||||
APPLY("apply"),
|
||||
@XmlEnumValue("pendingDrops")
|
||||
PENDING_DROPS("pendingDrops"),
|
||||
@XmlEnumValue("baseline")
|
||||
BASELINE("baseline"),
|
||||
@XmlEnumValue("drop")
|
||||
DROP("drop");
|
||||
private final String value;
|
||||
|
||||
ChangeSetType(String v) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ChangeSetType fromValue(String v) {
|
||||
for (ChangeSetType c : ChangeSetType.values()) {
|
||||
if (c.value.equals(v)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(v);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,486 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="before" type="{http://ebean-orm.github.io/xml/ns/dbmigration}ddl-script" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* <element name="after" type="{http://ebean-orm.github.io/xml/ns/dbmigration}ddl-script" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="defaultValue" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="notnull" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="historyExclude" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="primaryKey" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="identity" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="checkConstraint" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="checkConstraintName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="uniqueOneToOne" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="references" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyIndex" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyOnDelete" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="foreignKeyOnUpdate" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="comment" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"before",
|
||||
"after"
|
||||
})
|
||||
@XmlRootElement(name = "column")
|
||||
public class Column {
|
||||
|
||||
protected List<DdlScript> before;
|
||||
protected List<DdlScript> after;
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "type", required = true)
|
||||
protected String type;
|
||||
@XmlAttribute(name = "defaultValue")
|
||||
protected String defaultValue;
|
||||
@XmlAttribute(name = "notnull")
|
||||
protected Boolean notnull;
|
||||
@XmlAttribute(name = "historyExclude")
|
||||
protected Boolean historyExclude;
|
||||
@XmlAttribute(name = "primaryKey")
|
||||
protected Boolean primaryKey;
|
||||
@XmlAttribute(name = "identity")
|
||||
protected Boolean identity;
|
||||
@XmlAttribute(name = "checkConstraint")
|
||||
protected String checkConstraint;
|
||||
@XmlAttribute(name = "checkConstraintName")
|
||||
protected String checkConstraintName;
|
||||
@XmlAttribute(name = "unique")
|
||||
protected String unique;
|
||||
@XmlAttribute(name = "uniqueOneToOne")
|
||||
protected String uniqueOneToOne;
|
||||
@XmlAttribute(name = "references")
|
||||
protected String references;
|
||||
@XmlAttribute(name = "foreignKeyName")
|
||||
protected String foreignKeyName;
|
||||
@XmlAttribute(name = "foreignKeyIndex")
|
||||
protected String foreignKeyIndex;
|
||||
@XmlAttribute(name = "foreignKeyOnDelete")
|
||||
protected String foreignKeyOnDelete;
|
||||
@XmlAttribute(name = "foreignKeyOnUpdate")
|
||||
protected String foreignKeyOnUpdate;
|
||||
@XmlAttribute(name = "comment")
|
||||
protected String comment;
|
||||
|
||||
/**
|
||||
* Gets the value of the before property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the before property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getBefore().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link DdlScript }
|
||||
*/
|
||||
public List<DdlScript> getBefore() {
|
||||
if (before == null) {
|
||||
before = new ArrayList<>();
|
||||
}
|
||||
return this.before;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the after property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the after property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getAfter().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link DdlScript }
|
||||
*/
|
||||
public List<DdlScript> getAfter() {
|
||||
if (after == null) {
|
||||
after = new ArrayList<>();
|
||||
}
|
||||
return this.after;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the type property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the type property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setType(String value) {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the defaultValue property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the defaultValue property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDefaultValue(String value) {
|
||||
this.defaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the notnull property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isNotnull() {
|
||||
return notnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the notnull property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setNotnull(Boolean value) {
|
||||
this.notnull = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the historyExclude property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isHistoryExclude() {
|
||||
return historyExclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the historyExclude property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setHistoryExclude(Boolean value) {
|
||||
this.historyExclude = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the primaryKey property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isPrimaryKey() {
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the primaryKey property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setPrimaryKey(Boolean value) {
|
||||
this.primaryKey = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identity property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the identity property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setIdentity(Boolean value) {
|
||||
this.identity = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraint property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraint property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setCheckConstraint(String value) {
|
||||
this.checkConstraint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the checkConstraintName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getCheckConstraintName() {
|
||||
return checkConstraintName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the checkConstraintName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setCheckConstraintName(String value) {
|
||||
this.checkConstraintName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the unique property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the unique property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setUnique(String value) {
|
||||
this.unique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getUniqueOneToOne() {
|
||||
return uniqueOneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the uniqueOneToOne property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setUniqueOneToOne(String value) {
|
||||
this.uniqueOneToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the references property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the references property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setReferences(String value) {
|
||||
this.references = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyName() {
|
||||
return foreignKeyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyName(String value) {
|
||||
this.foreignKeyName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyIndex() {
|
||||
return foreignKeyIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyIndex property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyIndex(String value) {
|
||||
this.foreignKeyIndex = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyOnDelete property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyOnDelete() {
|
||||
return foreignKeyOnDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyOnDelete property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyOnDelete(String value) {
|
||||
this.foreignKeyOnDelete = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKeyOnUpdate property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getForeignKeyOnUpdate() {
|
||||
return foreignKeyOnUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the foreignKeyOnUpdate property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setForeignKeyOnUpdate(String value) {
|
||||
this.foreignKeyOnUpdate = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the comment property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the comment property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setComment(String value) {
|
||||
this.comment = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}defaultTablespace"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"defaultTablespace"
|
||||
})
|
||||
@XmlRootElement(name = "configuration")
|
||||
public class Configuration {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected DefaultTablespace defaultTablespace;
|
||||
|
||||
/**
|
||||
* Gets the value of the defaultTablespace property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link DefaultTablespace }
|
||||
*/
|
||||
public DefaultTablespace getDefaultTablespace() {
|
||||
return defaultTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the defaultTablespace property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link DefaultTablespace }
|
||||
*/
|
||||
public void setDefaultTablespace(DefaultTablespace value) {
|
||||
this.defaultTablespace = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="indexName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columns" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="unique" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="concurrent" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="definition" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="platforms" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "createIndex")
|
||||
public class CreateIndex {
|
||||
|
||||
@XmlAttribute(name = "indexName", required = true)
|
||||
protected String indexName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "columns", required = true)
|
||||
protected String columns;
|
||||
@XmlAttribute(name = "unique")
|
||||
protected Boolean unique;
|
||||
@XmlAttribute(name = "concurrent")
|
||||
protected Boolean concurrent;
|
||||
@XmlAttribute(name = "definition")
|
||||
protected String definition;
|
||||
@XmlAttribute(name = "platforms")
|
||||
protected String platforms;
|
||||
|
||||
/**
|
||||
* Gets the value of the indexName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setIndexName(String value) {
|
||||
this.indexName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columns property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columns property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setColumns(String value) {
|
||||
this.columns = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the unique property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the unique property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setUnique(Boolean value) {
|
||||
this.unique = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the concurrent property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isConcurrent() {
|
||||
return concurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the concurrent property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setConcurrent(Boolean value) {
|
||||
this.concurrent = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the definition property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the definition property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDefinition(String value) {
|
||||
this.definition = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the platforms property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the platforms property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPlatforms(String value) {
|
||||
this.platforms = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,546 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSchemaType;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}column" maxOccurs="unbounded"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}uniqueConstraint" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}foreignKey" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* <attGroup ref="{http://ebean-orm.github.io/xml/ns/dbmigration}tablespaceAttributes"/>
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="partitionMode" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="partitionColumn" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="draft" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="identityType" type="{http://ebean-orm.github.io/xml/ns/dbmigration}identityType" />
|
||||
* <attribute name="identityStart" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="identityIncrement" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="identityCache" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="identityGenerated" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="sequenceName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="sequenceInitial" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="sequenceAllocate" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
* <attribute name="pkName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="storageEngine" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"column",
|
||||
"uniqueConstraint",
|
||||
"foreignKey"
|
||||
})
|
||||
@XmlRootElement(name = "createTable")
|
||||
public class CreateTable {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected List<Column> column;
|
||||
protected List<UniqueConstraint> uniqueConstraint;
|
||||
protected List<ForeignKey> foreignKey;
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "partitionMode")
|
||||
protected String partitionMode;
|
||||
@XmlAttribute(name = "partitionColumn")
|
||||
protected String partitionColumn;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
@XmlAttribute(name = "draft")
|
||||
protected Boolean draft;
|
||||
@XmlAttribute(name = "identityType")
|
||||
protected IdentityType identityType;
|
||||
@XmlAttribute(name = "identityStart")
|
||||
@XmlSchemaType(name = "positiveInteger")
|
||||
protected BigInteger identityStart;
|
||||
@XmlAttribute(name = "identityIncrement")
|
||||
@XmlSchemaType(name = "positiveInteger")
|
||||
protected BigInteger identityIncrement;
|
||||
@XmlAttribute(name = "identityCache")
|
||||
@XmlSchemaType(name = "positiveInteger")
|
||||
protected BigInteger identityCache;
|
||||
@XmlAttribute(name = "identityGenerated")
|
||||
protected String identityGenerated;
|
||||
@XmlAttribute(name = "sequenceName")
|
||||
protected String sequenceName;
|
||||
@XmlAttribute(name = "sequenceInitial")
|
||||
@XmlSchemaType(name = "positiveInteger")
|
||||
protected BigInteger sequenceInitial;
|
||||
@XmlAttribute(name = "sequenceAllocate")
|
||||
@XmlSchemaType(name = "positiveInteger")
|
||||
protected BigInteger sequenceAllocate;
|
||||
@XmlAttribute(name = "pkName")
|
||||
protected String pkName;
|
||||
@XmlAttribute(name = "storageEngine")
|
||||
protected String storageEngine;
|
||||
@XmlAttribute(name = "tablespace")
|
||||
protected String tablespace;
|
||||
@XmlAttribute(name = "indexTablespace")
|
||||
protected String indexTablespace;
|
||||
@XmlAttribute(name = "comment")
|
||||
protected String comment;
|
||||
|
||||
/**
|
||||
* Gets the value of the column property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the column property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getColumn().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Column }
|
||||
*/
|
||||
public List<Column> getColumn() {
|
||||
if (column == null) {
|
||||
column = new ArrayList<>();
|
||||
}
|
||||
return this.column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the uniqueConstraint property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the uniqueConstraint property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getUniqueConstraint().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link UniqueConstraint }
|
||||
*/
|
||||
public List<UniqueConstraint> getUniqueConstraint() {
|
||||
if (uniqueConstraint == null) {
|
||||
uniqueConstraint = new ArrayList<>();
|
||||
}
|
||||
return this.uniqueConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the foreignKey property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the foreignKey property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getForeignKey().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link ForeignKey }
|
||||
*/
|
||||
public List<ForeignKey> getForeignKey() {
|
||||
if (foreignKey == null) {
|
||||
foreignKey = new ArrayList<>();
|
||||
}
|
||||
return this.foreignKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the partitionMode property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPartitionMode() {
|
||||
return partitionMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the partitionMode property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPartitionMode(String value) {
|
||||
this.partitionMode = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the partitionColumn property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPartitionColumn() {
|
||||
return partitionColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the partitionColumn property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPartitionColumn(String value) {
|
||||
this.partitionColumn = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the withHistory property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the withHistory property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setWithHistory(Boolean value) {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the draft property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the draft property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setDraft(Boolean value) {
|
||||
this.draft = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identityType property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link IdentityType }
|
||||
*/
|
||||
public IdentityType getIdentityType() {
|
||||
return identityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the identityType property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link IdentityType }
|
||||
*/
|
||||
public void setIdentityType(IdentityType value) {
|
||||
this.identityType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identityStart property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public BigInteger getIdentityStart() {
|
||||
return identityStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the identityStart property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public void setIdentityStart(BigInteger value) {
|
||||
this.identityStart = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identityIncrement property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public BigInteger getIdentityIncrement() {
|
||||
return identityIncrement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the identityIncrement property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public void setIdentityIncrement(BigInteger value) {
|
||||
this.identityIncrement = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identityCache property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public BigInteger getIdentityCache() {
|
||||
return identityCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the identityCache property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public void setIdentityCache(BigInteger value) {
|
||||
this.identityCache = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identityGenerated property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getIdentityGenerated() {
|
||||
return identityGenerated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the identityGenerated property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setIdentityGenerated(String value) {
|
||||
this.identityGenerated = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the sequenceName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getSequenceName() {
|
||||
return sequenceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the sequenceName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setSequenceName(String value) {
|
||||
this.sequenceName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the sequenceInitial property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public BigInteger getSequenceInitial() {
|
||||
return sequenceInitial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the sequenceInitial property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public void setSequenceInitial(BigInteger value) {
|
||||
this.sequenceInitial = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the sequenceAllocate property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public BigInteger getSequenceAllocate() {
|
||||
return sequenceAllocate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the sequenceAllocate property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link BigInteger }
|
||||
*/
|
||||
public void setSequenceAllocate(BigInteger value) {
|
||||
this.sequenceAllocate = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the pkName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPkName() {
|
||||
return pkName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the pkName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPkName(String value) {
|
||||
this.pkName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the storageEngine property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getStorageEngine() {
|
||||
return storageEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the storageEngine property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setStorageEngine(String value) {
|
||||
this.storageEngine = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tablespace property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTablespace() {
|
||||
return tablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tablespace property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTablespace(String value) {
|
||||
this.tablespace = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the indexTablespace property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getIndexTablespace() {
|
||||
return indexTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexTablespace property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setIndexTablespace(String value) {
|
||||
this.indexTablespace = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the comment property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the comment property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setComment(String value) {
|
||||
this.comment = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for ddl-script complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType name="ddl-script">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="ddl" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
|
||||
* </sequence>
|
||||
* <attribute name="platforms" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "ddl-script", propOrder = {
|
||||
"ddl"
|
||||
})
|
||||
public class DdlScript {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected List<String> ddl;
|
||||
@XmlAttribute(name = "platforms")
|
||||
protected String platforms;
|
||||
|
||||
/**
|
||||
* Gets the value of the ddl property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the ddl property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getDdl().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link String }
|
||||
*/
|
||||
public List<String> getDdl() {
|
||||
if (ddl == null) {
|
||||
ddl = new ArrayList<>();
|
||||
}
|
||||
return this.ddl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the platforms property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the platforms property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPlatforms(String value) {
|
||||
this.platforms = value;
|
||||
}
|
||||
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="tables" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="indexes" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="history" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "defaultTablespace")
|
||||
public class DefaultTablespace {
|
||||
|
||||
@XmlAttribute(name = "tables")
|
||||
protected String tables;
|
||||
@XmlAttribute(name = "indexes")
|
||||
protected String indexes;
|
||||
@XmlAttribute(name = "history")
|
||||
protected String history;
|
||||
|
||||
/**
|
||||
* Gets the value of the tables property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTables() {
|
||||
return tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tables property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTables(String value) {
|
||||
this.tables = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the indexes property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getIndexes() {
|
||||
return indexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexes property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setIndexes(String value) {
|
||||
this.indexes = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the history property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getHistory() {
|
||||
return history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the history property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setHistory(String value) {
|
||||
this.history = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="columnName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropColumn")
|
||||
public class DropColumn {
|
||||
|
||||
@XmlAttribute(name = "columnName", required = true)
|
||||
protected String columnName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
|
||||
/**
|
||||
* Gets the value of the columnName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setColumnName(String value) {
|
||||
this.columnName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the withHistory property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isWithHistory() {
|
||||
return withHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the withHistory property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setWithHistory(Boolean value) {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="baseTable" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropHistoryTable")
|
||||
public class DropHistoryTable {
|
||||
|
||||
@XmlAttribute(name = "baseTable", required = true)
|
||||
protected String baseTable;
|
||||
|
||||
/**
|
||||
* Gets the value of the baseTable property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the baseTable property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setBaseTable(String value) {
|
||||
this.baseTable = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="indexName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="concurrent" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="platforms" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropIndex")
|
||||
public class DropIndex {
|
||||
|
||||
@XmlAttribute(name = "indexName", required = true)
|
||||
protected String indexName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "concurrent")
|
||||
protected Boolean concurrent;
|
||||
@XmlAttribute(name = "platforms")
|
||||
protected String platforms;
|
||||
|
||||
/**
|
||||
* Gets the value of the indexName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setIndexName(String value) {
|
||||
this.indexName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the concurrent property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isConcurrent() {
|
||||
return concurrent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the concurrent property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setConcurrent(Boolean value) {
|
||||
this.concurrent = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the platforms property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the platforms property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPlatforms(String value) {
|
||||
this.platforms = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="sequenceCol" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="sequenceName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "dropTable")
|
||||
public class DropTable {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "sequenceCol")
|
||||
protected String sequenceCol;
|
||||
@XmlAttribute(name = "sequenceName")
|
||||
protected String sequenceName;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the sequenceCol property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getSequenceCol() {
|
||||
return sequenceCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the sequenceCol property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setSequenceCol(String value) {
|
||||
this.sequenceCol = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the sequenceName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getSequenceName() {
|
||||
return sequenceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the sequenceName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setSequenceName(String value) {
|
||||
this.sequenceName = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="refColumnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="refTableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="indexName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="onDelete" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="onUpdate" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "foreignKey")
|
||||
public class ForeignKey {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "columnNames", required = true)
|
||||
protected String columnNames;
|
||||
@XmlAttribute(name = "refColumnNames", required = true)
|
||||
protected String refColumnNames;
|
||||
@XmlAttribute(name = "refTableName", required = true)
|
||||
protected String refTableName;
|
||||
@XmlAttribute(name = "indexName")
|
||||
protected String indexName;
|
||||
@XmlAttribute(name = "onDelete")
|
||||
protected String onDelete;
|
||||
@XmlAttribute(name = "onUpdate")
|
||||
protected String onUpdate;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columnNames property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnNames property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setColumnNames(String value) {
|
||||
this.columnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the refColumnNames property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getRefColumnNames() {
|
||||
return refColumnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the refColumnNames property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setRefColumnNames(String value) {
|
||||
this.refColumnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the refTableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getRefTableName() {
|
||||
return refTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the refTableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setRefTableName(String value) {
|
||||
this.refTableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the indexName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the indexName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setIndexName(String value) {
|
||||
this.indexName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the onDelete property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getOnDelete() {
|
||||
return onDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the onDelete property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setOnDelete(String value) {
|
||||
this.onDelete = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the onUpdate property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getOnUpdate() {
|
||||
return onUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the onUpdate property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setOnUpdate(String value) {
|
||||
this.onUpdate = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlEnum;
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for identityType.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <simpleType name="identityType">
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
|
||||
* <enumeration value="identity"/>
|
||||
* <enumeration value="sequence"/>
|
||||
* <enumeration value="generator"/>
|
||||
* <enumeration value="external"/>
|
||||
* <enumeration value="default"/>
|
||||
* </restriction>
|
||||
* </simpleType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlType(name = "identityType")
|
||||
@XmlEnum
|
||||
public enum IdentityType {
|
||||
|
||||
@XmlEnumValue("identity")
|
||||
IDENTITY("identity"),
|
||||
@XmlEnumValue("sequence")
|
||||
SEQUENCE("sequence"),
|
||||
@XmlEnumValue("generator")
|
||||
GENERATOR("generator"),
|
||||
@XmlEnumValue("external")
|
||||
EXTERNAL("external"),
|
||||
@XmlEnumValue("default")
|
||||
DEFAULT("default");
|
||||
private final String value;
|
||||
|
||||
IdentityType(String v) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static IdentityType fromValue(String v) {
|
||||
for (IdentityType c : IdentityType.values()) {
|
||||
if (c.value.equals(v)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(v);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}changeSet" maxOccurs="unbounded"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"changeSet"
|
||||
})
|
||||
@XmlRootElement(name = "migration")
|
||||
public class Migration {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected List<ChangeSet> changeSet;
|
||||
|
||||
/**
|
||||
* Gets the value of the changeSet property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the changeSet property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getChangeSet().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link ChangeSet }
|
||||
*/
|
||||
public List<ChangeSet> getChangeSet() {
|
||||
if (changeSet == null) {
|
||||
changeSet = new ArrayList<>();
|
||||
}
|
||||
return this.changeSet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRegistry;
|
||||
|
||||
|
||||
/**
|
||||
* This object contains factory methods for each
|
||||
* Java content interface and Java element interface
|
||||
* generated in the io.ebeaninternal.dbmigration.migration package.
|
||||
* <p>An ObjectFactory allows you to programatically
|
||||
* construct new instances of the Java representation
|
||||
* for XML content. The Java representation of XML
|
||||
* content can consist of schema derived interfaces
|
||||
* and classes representing the binding of schema
|
||||
* type definitions, element declarations and model
|
||||
* groups. Factory methods for each of these are
|
||||
* provided in this class.
|
||||
*/
|
||||
@XmlRegistry
|
||||
public class ObjectFactory {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: io.ebeaninternal.dbmigration.migration
|
||||
*/
|
||||
public ObjectFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AddUniqueConstraint }
|
||||
*/
|
||||
public AddUniqueConstraint createAddUniqueConstraint() {
|
||||
return new AddUniqueConstraint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link CreateTable }
|
||||
*/
|
||||
public CreateTable createCreateTable() {
|
||||
return new CreateTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Column }
|
||||
*/
|
||||
public Column createColumn() {
|
||||
return new Column();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DdlScript }
|
||||
*/
|
||||
public DdlScript createDdlScript() {
|
||||
return new DdlScript();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link UniqueConstraint }
|
||||
*/
|
||||
public UniqueConstraint createUniqueConstraint() {
|
||||
return new UniqueConstraint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ForeignKey }
|
||||
*/
|
||||
public ForeignKey createForeignKey() {
|
||||
return new ForeignKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Configuration }
|
||||
*/
|
||||
public Configuration createConfiguration() {
|
||||
return new Configuration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DefaultTablespace }
|
||||
*/
|
||||
public DefaultTablespace createDefaultTablespace() {
|
||||
return new DefaultTablespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link RenameTable }
|
||||
*/
|
||||
public RenameTable createRenameTable() {
|
||||
return new RenameTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropHistoryTable }
|
||||
*/
|
||||
public DropHistoryTable createDropHistoryTable() {
|
||||
return new DropHistoryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AlterForeignKey }
|
||||
*/
|
||||
public AlterForeignKey createAlterForeignKey() {
|
||||
return new AlterForeignKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropColumn }
|
||||
*/
|
||||
public DropColumn createDropColumn() {
|
||||
return new DropColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Sql }
|
||||
*/
|
||||
public Sql createSql() {
|
||||
return new Sql();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Apply }
|
||||
*/
|
||||
public Apply createApply() {
|
||||
return new Apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Rollback }
|
||||
*/
|
||||
public Rollback createRollback() {
|
||||
return new Rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropIndex }
|
||||
*/
|
||||
public DropIndex createDropIndex() {
|
||||
return new DropIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link RenameColumn }
|
||||
*/
|
||||
public RenameColumn createRenameColumn() {
|
||||
return new RenameColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link DropTable }
|
||||
*/
|
||||
public DropTable createDropTable() {
|
||||
return new DropTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AddColumn }
|
||||
*/
|
||||
public AddColumn createAddColumn() {
|
||||
return new AddColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AddTableComment }
|
||||
*/
|
||||
public AddTableComment createAddTableComment() {
|
||||
return new AddTableComment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AlterColumn }
|
||||
*/
|
||||
public AlterColumn createAlterColumn() {
|
||||
return new AlterColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link CreateIndex }
|
||||
*/
|
||||
public CreateIndex createCreateIndex() {
|
||||
return new CreateIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ChangeSet }
|
||||
*/
|
||||
public ChangeSet createChangeSet() {
|
||||
return new ChangeSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AddHistoryTable }
|
||||
*/
|
||||
public AddHistoryTable createAddHistoryTable() {
|
||||
return new AddHistoryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link AlterHistoryTable }
|
||||
*/
|
||||
public AlterHistoryTable createAlterHistoryTable() {
|
||||
return new AlterHistoryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Migration }
|
||||
*/
|
||||
public Migration createMigration() {
|
||||
return new Migration();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="oldName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="tableName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="dataType" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "renameColumn")
|
||||
public class RenameColumn {
|
||||
|
||||
@XmlAttribute(name = "oldName", required = true)
|
||||
protected String oldName;
|
||||
@XmlAttribute(name = "newName", required = true)
|
||||
protected String newName;
|
||||
@XmlAttribute(name = "tableName", required = true)
|
||||
protected String tableName;
|
||||
@XmlAttribute(name = "dataType")
|
||||
protected String dataType;
|
||||
|
||||
/**
|
||||
* Gets the value of the oldName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setOldName(String value) {
|
||||
this.oldName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setNewName(String value) {
|
||||
this.newName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the tableName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the tableName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setTableName(String value) {
|
||||
this.tableName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the dataType property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the dataType property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDataType(String value) {
|
||||
this.dataType = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="oldName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="newName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "renameTable")
|
||||
public class RenameTable {
|
||||
|
||||
@XmlAttribute(name = "oldName", required = true)
|
||||
protected String oldName;
|
||||
@XmlAttribute(name = "newName", required = true)
|
||||
protected String newName;
|
||||
|
||||
/**
|
||||
* Gets the value of the oldName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oldName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setOldName(String value) {
|
||||
this.oldName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the newName property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the newName property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setNewName(String value) {
|
||||
this.newName = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <simpleContent>
|
||||
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
|
||||
* </extension>
|
||||
* </simpleContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"value"
|
||||
})
|
||||
@XmlRootElement(name = "rollback")
|
||||
public class Rollback {
|
||||
|
||||
@XmlValue
|
||||
protected String value;
|
||||
|
||||
/**
|
||||
* Gets the value of the value property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the value property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}apply"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/dbmigration}rollback"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"apply",
|
||||
"rollback"
|
||||
})
|
||||
@XmlRootElement(name = "sql")
|
||||
public class Sql {
|
||||
|
||||
@XmlElement(required = true)
|
||||
protected Apply apply;
|
||||
@XmlElement(required = true)
|
||||
protected Rollback rollback;
|
||||
|
||||
/**
|
||||
* Gets the value of the apply property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Apply }
|
||||
*/
|
||||
public Apply getApply() {
|
||||
return apply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the apply property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Apply }
|
||||
*/
|
||||
public void setApply(Apply value) {
|
||||
this.apply = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the rollback property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Rollback }
|
||||
*/
|
||||
public Rollback getRollback() {
|
||||
return rollback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the rollback property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Rollback }
|
||||
*/
|
||||
public void setRollback(Rollback value) {
|
||||
this.rollback = value;
|
||||
}
|
||||
|
||||
}
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="columnNames" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="oneToOne" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="nullableColumns" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="platforms" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "")
|
||||
@XmlRootElement(name = "uniqueConstraint")
|
||||
public class UniqueConstraint {
|
||||
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
@XmlAttribute(name = "columnNames", required = true)
|
||||
protected String columnNames;
|
||||
@XmlAttribute(name = "oneToOne")
|
||||
protected Boolean oneToOne;
|
||||
@XmlAttribute(name = "nullableColumns")
|
||||
protected String nullableColumns;
|
||||
@XmlAttribute(name = "platforms")
|
||||
protected String platforms;
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the columnNames property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the columnNames property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setColumnNames(String value) {
|
||||
this.columnNames = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the oneToOne property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public Boolean isOneToOne() {
|
||||
return oneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the oneToOne property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link Boolean }
|
||||
*/
|
||||
public void setOneToOne(Boolean value) {
|
||||
this.oneToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the nullableColumns property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getNullableColumns() {
|
||||
return nullableColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the nullableColumns property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setNullableColumns(String value) {
|
||||
this.nullableColumns = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the platforms property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the platforms property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setPlatforms(String value) {
|
||||
this.platforms = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
@javax.xml.bind.annotation.XmlSchema(namespace = "http://ebean-orm.github.io/xml/ns/dbmigration", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
|
||||
package io.ebeaninternal.dbmigration.migration;
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migrationreader;
|
||||
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.Migration;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Reads a migration xml document returning the Migration.
|
||||
*/
|
||||
public class MigrationXmlReader {
|
||||
|
||||
private MigrationXmlReader() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and return a Migration from an xml document at the given resource path.
|
||||
*/
|
||||
public static Migration read(String resourcePath) {
|
||||
|
||||
try (InputStream is = MigrationXmlReader.class.getResourceAsStream(resourcePath)) {
|
||||
if (is == null) {
|
||||
throw new IllegalArgumentException("No resource found for path [" + resourcePath + "]");
|
||||
}
|
||||
return read(is);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("Failed to auto close resource " + resourcePath, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and return a Migration from a migration xml file.
|
||||
*/
|
||||
public static Migration read(File migrationFile) {
|
||||
|
||||
try (FileInputStream is = new FileInputStream(migrationFile)) {
|
||||
return read(is);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and return a Migration from an xml document.
|
||||
*/
|
||||
public static Migration read(InputStream is) {
|
||||
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(Migration.class);
|
||||
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||
return (Migration) unmarshaller.unmarshal(is);
|
||||
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.migrationreader;
|
||||
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.Migration;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Simple writer for output of the Migration/ChangeSet as an XML document.
|
||||
*/
|
||||
public class MigrationXmlWriter {
|
||||
|
||||
private final String comment;
|
||||
|
||||
public MigrationXmlWriter(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a Migration as a standalone XML document to a file.
|
||||
*/
|
||||
public void write(Migration migration, File file) {
|
||||
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
|
||||
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
|
||||
if (comment != null) {
|
||||
writer.write("<!-- ");
|
||||
writer.write(comment);
|
||||
writer.write(" -->\n");
|
||||
}
|
||||
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(Migration.class);
|
||||
Marshaller marshaller = jaxbContext.createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
|
||||
|
||||
marshaller.marshal(migration, writer);
|
||||
|
||||
} catch (IOException | JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.model;
|
||||
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.ChangeSet;
|
||||
import io.ebeaninternal.dbmigration.model.build.ModelBuildBeanVisitor;
|
||||
import io.ebeaninternal.dbmigration.model.build.ModelBuildContext;
|
||||
import io.ebeaninternal.dbmigration.model.visitor.VisitAllUsing;
|
||||
import io.ebeaninternal.extraddl.model.DdlScript;
|
||||
import io.ebeaninternal.extraddl.model.ExtraDdl;
|
||||
import io.ebeaninternal.extraddl.model.ExtraDdlXmlReader;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
|
||||
|
||||
/**
|
||||
* Reads EbeanServer bean descriptors to build the current model.
|
||||
*/
|
||||
public class CurrentModel {
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
private final DatabasePlatform databasePlatform;
|
||||
|
||||
private final DbConstraintNaming constraintNaming;
|
||||
|
||||
private final boolean platformTypes;
|
||||
|
||||
private final boolean jaxbPresent;
|
||||
|
||||
private ModelContainer model;
|
||||
|
||||
private ChangeSet changeSet;
|
||||
|
||||
private DdlWrite write;
|
||||
|
||||
private DdlOptions ddlOptions = new DdlOptions();
|
||||
|
||||
/**
|
||||
* Construct with a given EbeanServer instance for DDL create all generation, not migration.
|
||||
*/
|
||||
public CurrentModel(SpiEbeanServer server) {
|
||||
this(server, server.getServerConfig().getConstraintNaming(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a given EbeanServer, platformDdl and constraintNaming convention.
|
||||
* <p>
|
||||
* Note the EbeanServer is just used to read the BeanDescriptors and platformDdl supplies
|
||||
* the platform specific handling on
|
||||
* </p>
|
||||
*/
|
||||
public CurrentModel(SpiEbeanServer server, DbConstraintNaming constraintNaming) {
|
||||
this(server, constraintNaming, false);
|
||||
}
|
||||
|
||||
private CurrentModel(SpiEbeanServer server, DbConstraintNaming constraintNaming, boolean platformTypes) {
|
||||
this.server = server;
|
||||
this.databasePlatform = server.getDatabasePlatform();
|
||||
this.constraintNaming = constraintNaming;
|
||||
this.platformTypes = platformTypes;
|
||||
this.jaxbPresent = server.getServerConfig().getClassLoadConfig().isJavaxJAXBPresent();
|
||||
}
|
||||
|
||||
public DdlOptions getDdlOptions() {
|
||||
return ddlOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the model contains tables that are partitioned.
|
||||
*/
|
||||
public boolean isTablePartitioning() {
|
||||
return read().isTablePartitioning();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tables that have partitioning.
|
||||
*/
|
||||
public List<MTable> getPartitionedTables() {
|
||||
return read().getPartitionedTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current model by reading all the bean descriptors and properties.
|
||||
*/
|
||||
public ModelContainer read() {
|
||||
if (model == null) {
|
||||
model = new ModelContainer();
|
||||
|
||||
ModelBuildContext context = new ModelBuildContext(model, databasePlatform, constraintNaming, platformTypes);
|
||||
ModelBuildBeanVisitor visitor = new ModelBuildBeanVisitor(context);
|
||||
VisitAllUsing visit = new VisitAllUsing(visitor, server);
|
||||
visit.visitAllBeans();
|
||||
|
||||
// adjust the foreign keys on the 'draft' tables
|
||||
context.adjustDraftReferences();
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setChangeSet(ChangeSet changeSet) {
|
||||
this.changeSet = changeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return as a ChangeSet.
|
||||
*/
|
||||
public ChangeSet getChangeSet() {
|
||||
read();
|
||||
if (changeSet == null) {
|
||||
changeSet = asChangeSet();
|
||||
}
|
||||
return changeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 'Create' DDL.
|
||||
*/
|
||||
public String getCreateDdl() throws IOException {
|
||||
|
||||
createDdl();
|
||||
|
||||
StringBuilder ddl = new StringBuilder(2000);
|
||||
String header = server.getServerConfig().getMigrationConfig().getDdlHeader();
|
||||
if (header != null && !header.isEmpty()) {
|
||||
ddl.append(header).append('\n');
|
||||
}
|
||||
|
||||
if (jaxbPresent) {
|
||||
addExtraDdl(ddl, ExtraDdlXmlReader.readBuiltin(), "-- init script ");
|
||||
}
|
||||
|
||||
ddl.append(write.apply().getBuffer());
|
||||
ddl.append(write.applyForeignKeys().getBuffer());
|
||||
ddl.append(write.applyHistoryView().getBuffer());
|
||||
ddl.append(write.applyHistoryTrigger().getBuffer());
|
||||
|
||||
return ddl.toString();
|
||||
}
|
||||
|
||||
private void addExtraDdl(StringBuilder ddl, ExtraDdl extraDdl, String prefix) {
|
||||
if (extraDdl != null) {
|
||||
List<DdlScript> ddlScript = extraDdl.getDdlScript();
|
||||
for (DdlScript script : ddlScript) {
|
||||
if (script.isInit() && matchPlatform(server.getDatabasePlatform().getPlatform(), script.getPlatforms())) {
|
||||
ddl.append(prefix).append(script.getName()).append('\n');
|
||||
ddl.append(script.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 'Drop' DDL.
|
||||
*/
|
||||
public String getDropAllDdl() throws IOException {
|
||||
|
||||
createDdl();
|
||||
|
||||
StringBuilder ddl = new StringBuilder(2000);
|
||||
String header = server.getServerConfig().getMigrationConfig().getDdlHeader();
|
||||
if (header != null && !header.isEmpty()) {
|
||||
ddl.append(header).append('\n');
|
||||
}
|
||||
ddl.append(write.dropAllForeignKeys().getBuffer());
|
||||
ddl.append(write.dropAll().getBuffer());
|
||||
|
||||
return ddl.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all the DDL based on the changeSet.
|
||||
*/
|
||||
private void createDdl() throws IOException {
|
||||
|
||||
if (write == null) {
|
||||
ChangeSet createChangeSet = getChangeSet();
|
||||
|
||||
write = new DdlWrite(new MConfiguration(), model, ddlOptions);
|
||||
|
||||
DdlHandler handler = handler();
|
||||
handler.generateProlog(write);
|
||||
handler.generate(write, createChangeSet);
|
||||
handler.generateEpilog(write);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the platform specific DdlHandler (to generate DDL).
|
||||
*/
|
||||
private DdlHandler handler() {
|
||||
return PlatformDdlBuilder.create(databasePlatform).createDdlHandler(server.getServerConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the model into a ChangeSet.
|
||||
*/
|
||||
private ChangeSet asChangeSet() {
|
||||
|
||||
// empty diff so changes will effectively all be create
|
||||
ModelDiff diff = new ModelDiff();
|
||||
diff.compareTo(model);
|
||||
|
||||
return diff.getApplyChangeSet();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,549 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.model;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.DdlHelp;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.DdlScript;
|
||||
import io.ebeaninternal.server.deploy.DbMigrationInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A column in the logical model.
|
||||
*/
|
||||
public class MColumn {
|
||||
|
||||
private String name;
|
||||
private String type;
|
||||
private String checkConstraint;
|
||||
private String checkConstraintName;
|
||||
private String defaultValue;
|
||||
private String references;
|
||||
private String foreignKeyName;
|
||||
private String foreignKeyIndex;
|
||||
private ConstraintMode fkeyOnDelete;
|
||||
private ConstraintMode fkeyOnUpdate;
|
||||
private String comment;
|
||||
|
||||
private boolean historyExclude;
|
||||
private boolean notnull;
|
||||
private boolean primaryKey;
|
||||
private boolean identity;
|
||||
|
||||
private String unique;
|
||||
|
||||
/**
|
||||
* Special unique for OneToOne as we need to handle that different
|
||||
* specifically for MsSqlServer.
|
||||
*/
|
||||
private String uniqueOneToOne;
|
||||
|
||||
/**
|
||||
* Temporary variable used when building the alter column changes.
|
||||
*/
|
||||
private AlterColumn alterColumn;
|
||||
|
||||
private boolean draftOnly;
|
||||
|
||||
private List<DbMigrationInfo> dbMigrationInfos;
|
||||
|
||||
public MColumn(Column column) {
|
||||
this.name = column.getName();
|
||||
this.type = column.getType();
|
||||
this.checkConstraint = column.getCheckConstraint();
|
||||
this.checkConstraintName = column.getCheckConstraintName();
|
||||
this.defaultValue = column.getDefaultValue();
|
||||
this.comment = column.getComment();
|
||||
this.references = column.getReferences();
|
||||
this.foreignKeyName = column.getForeignKeyName();
|
||||
this.foreignKeyIndex = column.getForeignKeyIndex();
|
||||
this.fkeyOnDelete = fkeyMode(column.getForeignKeyOnDelete());
|
||||
this.fkeyOnUpdate = fkeyMode(column.getForeignKeyOnUpdate());
|
||||
this.notnull = Boolean.TRUE.equals(column.isNotnull());
|
||||
this.primaryKey = Boolean.TRUE.equals(column.isPrimaryKey());
|
||||
this.identity = Boolean.TRUE.equals(column.isIdentity());
|
||||
this.unique = column.getUnique();
|
||||
this.uniqueOneToOne = column.getUniqueOneToOne();
|
||||
this.historyExclude = Boolean.TRUE.equals(column.isHistoryExclude());
|
||||
}
|
||||
|
||||
private ConstraintMode fkeyMode(String mode) {
|
||||
return (mode == null) ? null : ConstraintMode.valueOf(mode);
|
||||
}
|
||||
|
||||
public MColumn(String name, String type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public MColumn(String name, String type, boolean notnull) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.notnull = notnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of this column used for creating the associated draft table.
|
||||
*/
|
||||
public MColumn copyForDraft() {
|
||||
MColumn copy = new MColumn(name, type);
|
||||
copy.draftOnly = draftOnly;
|
||||
copy.checkConstraint = checkConstraint;
|
||||
copy.checkConstraintName = checkConstraintName;
|
||||
copy.defaultValue = defaultValue;
|
||||
copy.dbMigrationInfos = dbMigrationInfos;
|
||||
copy.references = references;
|
||||
copy.comment = comment;
|
||||
copy.foreignKeyName = foreignKeyName;
|
||||
copy.foreignKeyIndex = foreignKeyIndex;
|
||||
copy.fkeyOnUpdate = fkeyOnUpdate;
|
||||
copy.fkeyOnDelete = fkeyOnDelete;
|
||||
copy.historyExclude = historyExclude;
|
||||
copy.notnull = notnull;
|
||||
copy.primaryKey = primaryKey;
|
||||
copy.identity = identity;
|
||||
copy.unique = unique;
|
||||
copy.uniqueOneToOne = uniqueOneToOne;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isPrimaryKey() {
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
public void setPrimaryKey(boolean primaryKey) {
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
public boolean isIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public void setIdentity(boolean identity) {
|
||||
this.identity = identity;
|
||||
}
|
||||
|
||||
public String getCheckConstraint() {
|
||||
return checkConstraint;
|
||||
}
|
||||
|
||||
public void setCheckConstraint(String checkConstraint) {
|
||||
this.checkConstraint = checkConstraint;
|
||||
}
|
||||
|
||||
public String getCheckConstraintName() {
|
||||
return checkConstraintName;
|
||||
}
|
||||
|
||||
public void setCheckConstraintName(String checkConstraintName) {
|
||||
this.checkConstraintName = checkConstraintName;
|
||||
}
|
||||
|
||||
public String getForeignKeyName() {
|
||||
return foreignKeyName;
|
||||
}
|
||||
|
||||
public void setForeignKeyName(String foreignKeyName) {
|
||||
this.foreignKeyName = foreignKeyName;
|
||||
}
|
||||
|
||||
public String getForeignKeyIndex() {
|
||||
return foreignKeyIndex;
|
||||
}
|
||||
|
||||
public void setForeignKeyIndex(String foreignKeyIndex) {
|
||||
this.foreignKeyIndex = foreignKeyIndex;
|
||||
}
|
||||
|
||||
public void setForeignKeyModes(ConstraintMode onDelete, ConstraintMode onUpdate) {
|
||||
this.fkeyOnDelete = onDelete;
|
||||
this.fkeyOnUpdate = onUpdate;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public String getReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
public void setReferences(String references) {
|
||||
this.references = references;
|
||||
}
|
||||
|
||||
public boolean isNotnull() {
|
||||
return notnull;
|
||||
}
|
||||
|
||||
public void setNotnull(boolean notnull) {
|
||||
this.notnull = notnull;
|
||||
}
|
||||
|
||||
public boolean isHistoryExclude() {
|
||||
return historyExclude;
|
||||
}
|
||||
|
||||
public void setHistoryExclude(boolean historyExclude) {
|
||||
this.historyExclude = historyExclude;
|
||||
}
|
||||
|
||||
public void setUnique(String unique) {
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
public String getUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set unique specifically for OneToOne mapping.
|
||||
* We need special DDL for this case for SqlServer.
|
||||
*/
|
||||
public void setUniqueOneToOne(String uniqueOneToOne) {
|
||||
this.uniqueOneToOne = uniqueOneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is unique for a OneToOne.
|
||||
*/
|
||||
public String getUniqueOneToOne() {
|
||||
return uniqueOneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column comment.
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the column comment.
|
||||
*/
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the draftOnly status for this column.
|
||||
*/
|
||||
public void setDraftOnly(boolean draftOnly) {
|
||||
this.draftOnly = draftOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draftOnly status for this column.
|
||||
*/
|
||||
public boolean isDraftOnly() {
|
||||
return draftOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this column should be included in History DB triggers etc.
|
||||
*/
|
||||
public boolean isIncludeInHistory() {
|
||||
return !draftOnly && !historyExclude;
|
||||
}
|
||||
|
||||
public void clearForeignKey() {
|
||||
this.references = null;
|
||||
this.foreignKeyName = null;
|
||||
this.fkeyOnDelete = null;
|
||||
this.fkeyOnUpdate = null;
|
||||
}
|
||||
|
||||
public Column createColumn() {
|
||||
|
||||
Column c = new Column();
|
||||
c.setName(name);
|
||||
c.setType(type);
|
||||
|
||||
if (notnull) c.setNotnull(true);
|
||||
if (primaryKey) c.setPrimaryKey(true);
|
||||
if (identity) c.setIdentity(true);
|
||||
if (historyExclude) c.setHistoryExclude(true);
|
||||
|
||||
c.setCheckConstraint(checkConstraint);
|
||||
c.setCheckConstraintName(checkConstraintName);
|
||||
c.setReferences(references);
|
||||
c.setForeignKeyName(foreignKeyName);
|
||||
c.setForeignKeyIndex(foreignKeyIndex);
|
||||
c.setForeignKeyOnDelete(fkeyModeOf(fkeyOnDelete));
|
||||
c.setForeignKeyOnUpdate(fkeyModeOf(fkeyOnUpdate));
|
||||
c.setDefaultValue(defaultValue);
|
||||
c.setComment(comment);
|
||||
c.setUnique(unique);
|
||||
c.setUniqueOneToOne(uniqueOneToOne);
|
||||
|
||||
if (dbMigrationInfos != null) {
|
||||
for (DbMigrationInfo info : dbMigrationInfos) {
|
||||
if (!info.getPreAdd().isEmpty()) {
|
||||
DdlScript script = new DdlScript();
|
||||
script.getDdl().addAll(info.getPreAdd());
|
||||
script.setPlatforms(info.joinPlatforms());
|
||||
c.getBefore().add(script);
|
||||
}
|
||||
|
||||
if (!info.getPostAdd().isEmpty()) {
|
||||
DdlScript script = new DdlScript();
|
||||
script.getDdl().addAll(info.getPostAdd());
|
||||
script.setPlatforms(info.joinPlatforms());
|
||||
c.getAfter().add(script);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private String fkeyModeOf(ConstraintMode mode) {
|
||||
return (mode == null) ? null : mode.name();
|
||||
}
|
||||
|
||||
protected static boolean different(String val1, String val2) {
|
||||
return !Objects.equals(val1, val2);
|
||||
}
|
||||
|
||||
private boolean hasValue(String val) {
|
||||
return val != null && !val.isEmpty();
|
||||
}
|
||||
|
||||
private boolean hasValue(Boolean val) {
|
||||
return val != null;
|
||||
}
|
||||
|
||||
private AlterColumn getAlterColumn(String tableName, boolean tableWithHistory) {
|
||||
if (alterColumn == null) {
|
||||
alterColumn = new AlterColumn();
|
||||
alterColumn.setColumnName(name);
|
||||
alterColumn.setTableName(tableName);
|
||||
if (tableWithHistory) {
|
||||
alterColumn.setWithHistory(Boolean.TRUE);
|
||||
}
|
||||
|
||||
if (dbMigrationInfos != null) {
|
||||
for (DbMigrationInfo info : dbMigrationInfos) {
|
||||
if (!info.getPreAlter().isEmpty()) {
|
||||
DdlScript script = new DdlScript();
|
||||
script.getDdl().addAll(info.getPreAlter());
|
||||
script.setPlatforms(info.joinPlatforms());
|
||||
alterColumn.getBefore().add(script);
|
||||
}
|
||||
|
||||
if (!info.getPostAlter().isEmpty()) {
|
||||
DdlScript script = new DdlScript();
|
||||
script.getDdl().addAll(info.getPostAlter());
|
||||
script.setPlatforms(info.joinPlatforms());
|
||||
alterColumn.getAfter().add(script);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return alterColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the column meta data and return true if there is a change that means
|
||||
* the history table column needs
|
||||
*/
|
||||
public void compare(ModelDiff modelDiff, MTable table, MColumn newColumn) {
|
||||
|
||||
this.dbMigrationInfos = newColumn.dbMigrationInfos;
|
||||
|
||||
boolean tableWithHistory = table.isWithHistory();
|
||||
String tableName = table.getName();
|
||||
|
||||
// set to null and check at the end
|
||||
this.alterColumn = null;
|
||||
|
||||
boolean changeBaseAttribute = false;
|
||||
|
||||
if (historyExclude != newColumn.historyExclude) {
|
||||
getAlterColumn(tableName, tableWithHistory).setHistoryExclude(newColumn.historyExclude);
|
||||
}
|
||||
|
||||
if (different(type, newColumn.type)) {
|
||||
changeBaseAttribute = true;
|
||||
getAlterColumn(tableName, tableWithHistory).setType(newColumn.type);
|
||||
}
|
||||
if (notnull != newColumn.notnull) {
|
||||
changeBaseAttribute = true;
|
||||
getAlterColumn(tableName, tableWithHistory).setNotnull(newColumn.notnull);
|
||||
}
|
||||
if (different(defaultValue, newColumn.defaultValue)) {
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (newColumn.defaultValue == null) {
|
||||
alter.setDefaultValue(DdlHelp.DROP_DEFAULT);
|
||||
} else {
|
||||
alter.setDefaultValue(newColumn.defaultValue);
|
||||
}
|
||||
}
|
||||
if (different(comment, newColumn.comment)) {
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (newColumn.comment == null) {
|
||||
alter.setComment(DdlHelp.DROP_COMMENT);
|
||||
} else {
|
||||
alter.setComment(newColumn.comment);
|
||||
}
|
||||
}
|
||||
if (different(checkConstraint, newColumn.checkConstraint)) {
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(checkConstraint) && !hasValue(newColumn.checkConstraint)) {
|
||||
alter.setDropCheckConstraint(checkConstraintName);
|
||||
}
|
||||
if (hasValue(newColumn.checkConstraint)) {
|
||||
alter.setCheckConstraintName(newColumn.checkConstraintName);
|
||||
alter.setCheckConstraint(newColumn.checkConstraint);
|
||||
}
|
||||
}
|
||||
if (different(references, newColumn.references)
|
||||
|| hasValue(newColumn.references) && fkeyOnDelete != newColumn.fkeyOnDelete
|
||||
|| hasValue(newColumn.references) && fkeyOnUpdate != newColumn.fkeyOnUpdate) {
|
||||
// foreign key change
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(foreignKeyName)) {
|
||||
alter.setDropForeignKey(foreignKeyName);
|
||||
}
|
||||
if (hasValue(foreignKeyIndex)) {
|
||||
alter.setDropForeignKeyIndex(foreignKeyIndex);
|
||||
}
|
||||
if (hasValue(newColumn.references)) {
|
||||
// add new foreign key constraint
|
||||
alter.setReferences(newColumn.references);
|
||||
alter.setForeignKeyName(newColumn.foreignKeyName);
|
||||
alter.setForeignKeyIndex(newColumn.foreignKeyIndex);
|
||||
if (newColumn.fkeyOnDelete != null) {
|
||||
alter.setForeignKeyOnDelete(fkeyModeOf(newColumn.fkeyOnDelete));
|
||||
}
|
||||
if (newColumn.fkeyOnUpdate != null) {
|
||||
alter.setForeignKeyOnUpdate(fkeyModeOf(newColumn.fkeyOnUpdate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (different(unique, newColumn.unique)) {
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(unique)) {
|
||||
alter.setDropUnique(unique);
|
||||
}
|
||||
if (hasValue(newColumn.unique)) {
|
||||
alter.setUnique(newColumn.unique);
|
||||
}
|
||||
}
|
||||
if (different(uniqueOneToOne, newColumn.uniqueOneToOne)) {
|
||||
AlterColumn alter = getAlterColumn(tableName, tableWithHistory);
|
||||
if (hasValue(uniqueOneToOne)) {
|
||||
alter.setDropUnique(uniqueOneToOne);
|
||||
}
|
||||
if (hasValue(newColumn.uniqueOneToOne)) {
|
||||
alter.setUniqueOneToOne(newColumn.uniqueOneToOne);
|
||||
}
|
||||
}
|
||||
|
||||
if (alterColumn != null) {
|
||||
modelDiff.addAlterColumn(alterColumn);
|
||||
if (changeBaseAttribute) {
|
||||
// support reverting these changes
|
||||
alterColumn.setCurrentType(type);
|
||||
alterColumn.setCurrentNotnull(notnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setDbMigrationInfos(List<DbMigrationInfo> dbMigrationInfos) {
|
||||
this.dbMigrationInfos = dbMigrationInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the column.
|
||||
*/
|
||||
public MColumn rename(String newName) {
|
||||
this.name = newName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes based on the AlterColumn request.
|
||||
*/
|
||||
public void apply(AlterColumn alterColumn) {
|
||||
|
||||
if (hasValue(alterColumn.getDropCheckConstraint())) {
|
||||
checkConstraint = null;
|
||||
}
|
||||
if (hasValue(alterColumn.getDropForeignKey())) {
|
||||
foreignKeyName = null;
|
||||
references = null;
|
||||
}
|
||||
if (hasValue(alterColumn.getDropForeignKeyIndex())) {
|
||||
foreignKeyIndex = null;
|
||||
}
|
||||
if (hasValue(alterColumn.getDropUnique())) {
|
||||
unique = null;
|
||||
uniqueOneToOne = null;
|
||||
}
|
||||
|
||||
if (hasValue(alterColumn.getType())) {
|
||||
type = alterColumn.getType();
|
||||
}
|
||||
if (hasValue(alterColumn.isNotnull())) {
|
||||
notnull = alterColumn.isNotnull();
|
||||
}
|
||||
if (hasValue(alterColumn.getDefaultValue())) {
|
||||
defaultValue = alterColumn.getDefaultValue();
|
||||
if (DdlHelp.isDropDefault(defaultValue)) {
|
||||
defaultValue = null;
|
||||
}
|
||||
}
|
||||
if (hasValue(alterColumn.getCheckConstraint())) {
|
||||
checkConstraint = alterColumn.getCheckConstraint();
|
||||
}
|
||||
if (hasValue(alterColumn.getCheckConstraintName())) {
|
||||
checkConstraintName = alterColumn.getCheckConstraintName();
|
||||
}
|
||||
if (hasValue(alterColumn.getUnique())) {
|
||||
unique = alterColumn.getUnique();
|
||||
}
|
||||
if (hasValue(alterColumn.getUniqueOneToOne())) {
|
||||
uniqueOneToOne = alterColumn.getUniqueOneToOne();
|
||||
}
|
||||
if (hasValue(alterColumn.getReferences())) {
|
||||
references = alterColumn.getReferences();
|
||||
}
|
||||
if (hasValue(alterColumn.getForeignKeyName())) {
|
||||
foreignKeyName = alterColumn.getForeignKeyName();
|
||||
}
|
||||
if (hasValue(alterColumn.getForeignKeyIndex())) {
|
||||
foreignKeyIndex = alterColumn.getForeignKeyIndex();
|
||||
}
|
||||
if (hasValue(alterColumn.getComment())) {
|
||||
comment = alterColumn.getComment();
|
||||
if (DdlHelp.isDropComment(comment)) {
|
||||
comment = null;
|
||||
}
|
||||
}
|
||||
if (hasValue(alterColumn.getForeignKeyOnDelete())) {
|
||||
fkeyOnDelete = fkeyMode(alterColumn.getForeignKeyOnDelete());
|
||||
}
|
||||
if (hasValue(alterColumn.getForeignKeyOnUpdate())) {
|
||||
fkeyOnUpdate = fkeyMode(alterColumn.getForeignKeyOnUpdate());
|
||||
}
|
||||
if (hasValue(alterColumn.isHistoryExclude())) {
|
||||
historyExclude = alterColumn.isHistoryExclude();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.model;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.DdlHelp;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.ForeignKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A unique constraint for multiple columns.
|
||||
* <p>
|
||||
* Note that unique constraint on a single column is instead
|
||||
* a boolean flag on the associated MColumn.
|
||||
* </p>
|
||||
*/
|
||||
public class MCompoundForeignKey {
|
||||
|
||||
private String name;
|
||||
private final String referenceTable;
|
||||
private final List<String> columns = new ArrayList<>();
|
||||
private final List<String> referenceColumns = new ArrayList<>();
|
||||
private String indexName;
|
||||
|
||||
public MCompoundForeignKey(String name, String referenceTable, String indexName) {
|
||||
this.name = name;
|
||||
this.referenceTable = referenceTable;
|
||||
this.indexName = indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column pair of local and referenced column.
|
||||
*/
|
||||
public void addColumnPair(String dbCol, String refColumn) {
|
||||
columns.add(dbCol);
|
||||
referenceColumns.add(refColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return an ForeignKey migration element.
|
||||
*/
|
||||
public ForeignKey createForeignKey() {
|
||||
ForeignKey fk = new ForeignKey();
|
||||
fk.setName(name);
|
||||
fk.setIndexName(indexName);
|
||||
fk.setColumnNames(toColumnNames(columns));
|
||||
fk.setRefColumnNames(toColumnNames(referenceColumns));
|
||||
fk.setRefTableName(referenceTable);
|
||||
return fk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return an AlterForeignKey migration element.
|
||||
*/
|
||||
public AlterForeignKey addForeignKey(String tableName) {
|
||||
AlterForeignKey fk = new AlterForeignKey();
|
||||
fk.setName(name);
|
||||
fk.setIndexName(indexName);
|
||||
fk.setColumnNames(toColumnNames(columns));
|
||||
fk.setRefColumnNames(toColumnNames(referenceColumns));
|
||||
fk.setRefTableName(referenceTable);
|
||||
fk.setTableName(tableName);
|
||||
return fk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return an AlterForeignKey migration element.
|
||||
*/
|
||||
public AlterForeignKey dropForeignKey(String tableName) {
|
||||
AlterForeignKey fk = new AlterForeignKey();
|
||||
fk.setName(name);
|
||||
fk.setIndexName(indexName);
|
||||
fk.setColumnNames(DdlHelp.DROP_FOREIGN_KEY);
|
||||
fk.setTableName(tableName);
|
||||
return fk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a counter to the foreign key and index names to avoid duplication.
|
||||
*/
|
||||
public void addNameSuffix(int counter) {
|
||||
this.name = name + "_" + counter;
|
||||
this.indexName = indexName + "_" + counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the foreign key name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index name.
|
||||
*/
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the columns making up the foreign key in order.
|
||||
*/
|
||||
public List<String> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the associated index name. Note that setting to null has the effect
|
||||
* of indicating an associated index should not be created for this foreign key.
|
||||
*/
|
||||
public void setIndexName(String indexName) {
|
||||
this.indexName = indexName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return as an array of string column names.
|
||||
*/
|
||||
private String toColumnNames(List<String> columns) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(40);
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(columns.get(i));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(columns, indexName, name, referenceColumns, referenceTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!(obj instanceof MCompoundForeignKey))
|
||||
return false;
|
||||
|
||||
MCompoundForeignKey other = (MCompoundForeignKey) obj;
|
||||
return Objects.equals(columns, other.columns)
|
||||
&& Objects.equals(indexName, other.indexName)
|
||||
&& Objects.equals(name, other.name)
|
||||
&& Objects.equals(referenceColumns, other.referenceColumns)
|
||||
&& Objects.equals(referenceTable, other.referenceTable);
|
||||
}
|
||||
|
||||
}
|
||||
-175
@@ -1,175 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.model;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.DdlHelp;
|
||||
import io.ebeaninternal.dbmigration.migration.AddUniqueConstraint;
|
||||
import io.ebeaninternal.dbmigration.migration.UniqueConstraint;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.split;
|
||||
import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.splitWithNull;
|
||||
|
||||
/**
|
||||
* A unique constraint for multiple columns.
|
||||
* <p>
|
||||
* Note that unique constraint on a single column is instead
|
||||
* a boolean flag on the associated MColumn.
|
||||
* </p>
|
||||
*/
|
||||
public class MCompoundUniqueConstraint {
|
||||
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Flag if true indicates this was specifically created for a OneToOne mapping.
|
||||
*/
|
||||
private final boolean oneToOne;
|
||||
|
||||
/**
|
||||
* The columns combined to be unique.
|
||||
*/
|
||||
private final String[] columns;
|
||||
|
||||
private final String platforms;
|
||||
|
||||
private String[] nullableColumns;
|
||||
|
||||
/**
|
||||
* Create for OneToOne.
|
||||
*/
|
||||
public MCompoundUniqueConstraint(String[] columns, String name) {
|
||||
this.name = name;
|
||||
this.columns = columns;
|
||||
this.oneToOne = true;
|
||||
this.platforms = null;
|
||||
}
|
||||
|
||||
public MCompoundUniqueConstraint(String[] columns, boolean oneToOne, String name, String platforms) {
|
||||
this.name = name;
|
||||
this.columns = columns;
|
||||
this.oneToOne = oneToOne;
|
||||
this.platforms = platforms;
|
||||
}
|
||||
|
||||
public MCompoundUniqueConstraint(AddUniqueConstraint change) {
|
||||
this.name = change.getConstraintName();
|
||||
this.columns = split(change.getColumnNames());
|
||||
this.oneToOne = Boolean.TRUE.equals(change.isOneToOne());
|
||||
this.platforms = change.getPlatforms();
|
||||
this.nullableColumns = splitWithNull(change.getNullableColumns());
|
||||
}
|
||||
|
||||
public MCompoundUniqueConstraint(UniqueConstraint uq) {
|
||||
this.name = uq.getName();
|
||||
this.columns = split(uq.getColumnNames());
|
||||
this.oneToOne = Boolean.TRUE.equals(uq.isOneToOne());
|
||||
this.platforms = uq.getPlatforms();
|
||||
this.nullableColumns = splitWithNull(uq.getNullableColumns());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the columns for this unique constraint.
|
||||
*/
|
||||
public String[] getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this unique constraint is specifically for OneToOne mapping.
|
||||
*/
|
||||
public boolean isOneToOne() {
|
||||
return oneToOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the constraint name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
public UniqueConstraint getUniqueConstraint() {
|
||||
UniqueConstraint uq = new UniqueConstraint();
|
||||
uq.setName(getName());
|
||||
uq.setColumnNames(join(columns));
|
||||
uq.setNullableColumns(join(nullableColumns));
|
||||
uq.setOneToOne(isOneToOne());
|
||||
uq.setPlatforms(platforms);
|
||||
return uq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AddUniqueConstraint migration for this constraint.
|
||||
*/
|
||||
public AddUniqueConstraint addUniqueConstraint(String tableName) {
|
||||
AddUniqueConstraint create = new AddUniqueConstraint();
|
||||
create.setConstraintName(getName());
|
||||
create.setTableName(tableName);
|
||||
create.setColumnNames(join(columns));
|
||||
create.setNullableColumns(join(nullableColumns));
|
||||
create.setOneToOne(isOneToOne());
|
||||
create.setPlatforms(platforms);
|
||||
return create;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a AddUniqueConstraint migration with 'DROP CONSTRAINT' set for this index.
|
||||
*/
|
||||
public AddUniqueConstraint dropUniqueConstraint(String tableName) {
|
||||
AddUniqueConstraint drop = new AddUniqueConstraint();
|
||||
drop.setConstraintName(name);
|
||||
drop.setTableName(tableName);
|
||||
drop.setColumnNames(DdlHelp.DROP_CONSTRAINT);
|
||||
drop.setNullableColumns(join(nullableColumns));
|
||||
drop.setPlatforms(platforms);
|
||||
return drop;
|
||||
}
|
||||
|
||||
public void setNullableColumns(String[] nullableColumns) {
|
||||
if (nullableColumns != null && nullableColumns.length == 0) {
|
||||
this.nullableColumns = null;
|
||||
} else {
|
||||
this.nullableColumns = nullableColumns;
|
||||
}
|
||||
}
|
||||
|
||||
private String join(String[] arr) {
|
||||
if (arr == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(arr[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(columns) + 31 * Objects.hash(name, oneToOne);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof MCompoundUniqueConstraint)) {
|
||||
return false;
|
||||
}
|
||||
MCompoundUniqueConstraint other = (MCompoundUniqueConstraint) obj;
|
||||
// not including platforms in equals check
|
||||
return oneToOne == other.oneToOne
|
||||
&& Objects.equals(name, other.name)
|
||||
&& Arrays.equals(columns, other.columns)
|
||||
&& Arrays.equals(nullableColumns, other.nullableColumns);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.model;
|
||||
|
||||
import io.ebeaninternal.dbmigration.migration.Configuration;
|
||||
import io.ebeaninternal.dbmigration.migration.DefaultTablespace;
|
||||
|
||||
/**
|
||||
* Holds configuration such as the default tablespaces to use for tables,
|
||||
* indexes, history tables etc.
|
||||
*/
|
||||
public class MConfiguration {
|
||||
|
||||
/**
|
||||
* Default tablespace for tables.
|
||||
*/
|
||||
protected String tableTablespace;
|
||||
|
||||
/**
|
||||
* Default tablespace for indexes.
|
||||
*/
|
||||
protected String indexTablespace;
|
||||
|
||||
/**
|
||||
* Default tablespace for history tables.
|
||||
*/
|
||||
protected String historyTablespace;
|
||||
|
||||
/**
|
||||
* Apply the migration configuration.
|
||||
* <p>
|
||||
* It is expected that these are applied in the correct chronological order
|
||||
* from earliest to latest.
|
||||
* </p>
|
||||
*/
|
||||
public void apply(Configuration configuration) {
|
||||
|
||||
DefaultTablespace defaultTablespace = configuration.getDefaultTablespace();
|
||||
if (defaultTablespace != null) {
|
||||
String tables = defaultTablespace.getTables();
|
||||
if (isNotEmpty(tables)) {
|
||||
this.tableTablespace = tables;
|
||||
}
|
||||
String indexes = defaultTablespace.getIndexes();
|
||||
if (isNotEmpty(indexes)) {
|
||||
this.indexTablespace = indexes;
|
||||
}
|
||||
String history = defaultTablespace.getHistory();
|
||||
if (isNotEmpty(history)) {
|
||||
this.historyTablespace = history;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default tablespace to use for tables.
|
||||
*/
|
||||
public String getTableTablespace() {
|
||||
return tableTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default tablespace to use for indexes.
|
||||
*/
|
||||
public String getIndexTablespace() {
|
||||
return indexTablespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default tablespace to use for history tables.
|
||||
*/
|
||||
public String getHistoryTablespace() {
|
||||
return historyTablespace;
|
||||
}
|
||||
|
||||
protected boolean isNotEmpty(String tables) {
|
||||
return tables != null && !tables.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
Loaded 100 of 426 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user