支持h2作为配置库

This commit is contained in:
inrgihc
2025-04-09 21:18:13 +08:00
parent 5ad1a4217e
commit 2ecc1b4db6
9 changed files with 568 additions and 178 deletions

View File

@@ -505,7 +505,7 @@ service.run();
## 八、项目推荐
SQLREST是一款SQL2API的低代码开源工具:[https://gitee.com/inrgihc/sqlrest](https://gitee.com/inrgihc/sqlrest)
一款SQL2API的低代码开源工具SQLREST:[https://gitee.com/inrgihc/sqlrest](https://gitee.com/inrgihc/sqlrest)
## 九、社区推荐
@@ -517,7 +517,7 @@ SQLREST是一款SQL2API的低代码开源工具:[https://gitee.com/inrgihc/sqlre
## 十、问题反馈
如果您看到并使用了本工具,或您觉得本工具对您有价值,请为此项目**点个赞**以表示对本项目的支持多谢如果您在使用时遇到了bug欢迎在issue中反馈。也可扫描下方二维码入群讨论加好友请注明"程序交流"
如果您看到并使用了本工具,或您觉得本工具对您有价值,请为此项目**点个赞**以表示对本项目的支持多谢如果您在使用时遇到了bug欢迎在issue中反馈。也可扫描下方二维码入群讨论加好友请注明"dbswitch程序交流"
![structure](images/weixin.PNG)

View File

@@ -56,6 +56,11 @@
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>

View File

@@ -0,0 +1,13 @@
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:~/dbswitch_db;MODE=MySQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE;DATABASE_TO_UPPER=FALSE;DATABASE_TO_LOWER=FALSE
username: root
password: 123456
validation-query: SELECT 1
test-on-borrow: true
flyway:
locations: classpath:db/h2
baseline-on-migrate: true
table: DBSWITCH_SCHEMA_HISTORY
enabled: true

View File

@@ -1,6 +1,7 @@
spring:
profiles:
include: mysql
include: h2
#include: mysql
#include: postgres
application:
name: dbswitch-admin

View File

@@ -0,0 +1,248 @@
-- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database,
-- and verifying that it works with Quartz's StdJDBCDelegate
--
-- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE
-- setting on your H2 database, or you will experience dead-locks
--
--
-- In your Quartz properties file, you'll need to set
-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
CREATE TABLE DBSWITCH_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR (200) NOT NULL ,
CALENDAR IMAGE NOT NULL
);
CREATE TABLE DBSWITCH_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
CRON_EXPRESSION VARCHAR (120) NOT NULL ,
TIME_ZONE_ID VARCHAR (80)
);
CREATE TABLE DBSWITCH_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR (95) NOT NULL ,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
INSTANCE_NAME VARCHAR (200) NOT NULL ,
FIRED_TIME BIGINT NOT NULL ,
SCHED_TIME BIGINT NOT NULL ,
PRIORITY INTEGER NOT NULL ,
STATE VARCHAR (16) NOT NULL,
JOB_NAME VARCHAR (200) NULL ,
JOB_GROUP VARCHAR (200) NULL ,
IS_NONCONCURRENT BOOLEAN NULL ,
REQUESTS_RECOVERY BOOLEAN NULL
);
CREATE TABLE DBSWITCH_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL
);
CREATE TABLE DBSWITCH_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR (200) NOT NULL ,
LAST_CHECKIN_TIME BIGINT NOT NULL ,
CHECKIN_INTERVAL BIGINT NOT NULL
);
CREATE TABLE DBSWITCH_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR (40) NOT NULL
);
CREATE TABLE DBSWITCH_JOB_DETAILS (
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR (200) NOT NULL ,
JOB_GROUP VARCHAR (200) NOT NULL ,
DESCRIPTION VARCHAR (250) NULL ,
JOB_CLASS_NAME VARCHAR (250) NOT NULL ,
IS_DURABLE BOOLEAN NOT NULL ,
IS_NONCONCURRENT BOOLEAN NOT NULL ,
IS_UPDATE_DATA BOOLEAN NOT NULL ,
REQUESTS_RECOVERY BOOLEAN NOT NULL ,
JOB_DATA IMAGE NULL
);
CREATE TABLE DBSWITCH_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
REPEAT_COUNT BIGINT NOT NULL ,
REPEAT_INTERVAL BIGINT NOT NULL ,
TIMES_TRIGGERED BIGINT NOT NULL
);
CREATE TABLE DBSWITCH_SIMPROP_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INTEGER NULL,
INT_PROP_2 INTEGER NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 BOOLEAN NULL,
BOOL_PROP_2 BOOLEAN NULL
);
CREATE TABLE DBSWITCH_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
BLOB_DATA IMAGE NULL
);
CREATE TABLE DBSWITCH_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
JOB_NAME VARCHAR (200) NOT NULL ,
JOB_GROUP VARCHAR (200) NOT NULL ,
DESCRIPTION VARCHAR (250) NULL ,
NEXT_FIRE_TIME BIGINT NULL ,
PREV_FIRE_TIME BIGINT NULL ,
PRIORITY INTEGER NULL ,
TRIGGER_STATE VARCHAR (16) NOT NULL ,
TRIGGER_TYPE VARCHAR (8) NOT NULL ,
START_TIME BIGINT NOT NULL ,
END_TIME BIGINT NULL ,
CALENDAR_NAME VARCHAR (200) NULL ,
MISFIRE_INSTR SMALLINT NULL ,
JOB_DATA IMAGE NULL
);
ALTER TABLE DBSWITCH_CALENDARS ADD
CONSTRAINT PK_DBSWITCH_CALENDARS PRIMARY KEY
(
SCHED_NAME,
CALENDAR_NAME
);
ALTER TABLE DBSWITCH_CRON_TRIGGERS ADD
CONSTRAINT PK_DBSWITCH_CRON_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE DBSWITCH_FIRED_TRIGGERS ADD
CONSTRAINT PK_DBSWITCH_FIRED_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
ENTRY_ID
);
ALTER TABLE DBSWITCH_PAUSED_TRIGGER_GRPS ADD
CONSTRAINT PK_DBSWITCH_PAUSED_TRIGGER_GRPS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_GROUP
);
ALTER TABLE DBSWITCH_SCHEDULER_STATE ADD
CONSTRAINT PK_DBSWITCH_SCHEDULER_STATE PRIMARY KEY
(
SCHED_NAME,
INSTANCE_NAME
);
ALTER TABLE DBSWITCH_LOCKS ADD
CONSTRAINT PK_DBSWITCH_LOCKS PRIMARY KEY
(
SCHED_NAME,
LOCK_NAME
);
ALTER TABLE DBSWITCH_JOB_DETAILS ADD
CONSTRAINT PK_DBSWITCH_JOB_DETAILS PRIMARY KEY
(
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
ALTER TABLE DBSWITCH_SIMPLE_TRIGGERS ADD
CONSTRAINT PK_DBSWITCH_SIMPLE_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE DBSWITCH_SIMPROP_TRIGGERS ADD
CONSTRAINT PK_DBSWITCH_SIMPROP_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE DBSWITCH_TRIGGERS ADD
CONSTRAINT PK_DBSWITCH_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE DBSWITCH_CRON_TRIGGERS ADD
CONSTRAINT FK_DBSWITCH_CRON_TRIGGERS_DBSWITCH_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES DBSWITCH_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE DBSWITCH_SIMPLE_TRIGGERS ADD
CONSTRAINT FK_DBSWITCH_SIMPLE_TRIGGERS_DBSWITCH_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES DBSWITCH_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE DBSWITCH_SIMPROP_TRIGGERS ADD
CONSTRAINT FK_DBSWITCH_SIMPROP_TRIGGERS_DBSWITCH_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES DBSWITCH_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE DBSWITCH_TRIGGERS ADD
CONSTRAINT FK_DBSWITCH_TRIGGERS_DBSWITCH_JOB_DETAILS FOREIGN KEY
(
SCHED_NAME,
JOB_NAME,
JOB_GROUP
) REFERENCES DBSWITCH_JOB_DETAILS (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
COMMIT;

View File

@@ -0,0 +1,118 @@
create table `DBSWITCH_SYSTEM_USER` (
`id` bigint(20) not null auto_increment comment '主键id',
`username` varchar(255) not null comment '登录名称',
`password` varchar(128) not null comment '登录密码',
`salt` varchar(128) not null comment '密码盐值',
`real_name` varchar(255) not null default '' comment '实际姓名',
`email` varchar(255) not null default '' comment '电子邮箱',
`address` varchar(255) not null default '' comment '所在地址',
`locked` tinyint(1) not null default 0 comment '是否锁定',
`create_time` timestamp not null default current_timestamp comment '创建时间',
`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
primary key (`id`),
unique key (`username`)
) engine = innodb auto_increment = 1 character set = utf8 comment = '系统用户表';
create table `DBSWITCH_SYSTEM_LOG` (
`id` bigint(20) unsigned not null auto_increment comment '主键',
`type` smallint not null default 0 comment '日志类型:0-访问日志;1-操作日志',
`username` varchar(64) not null default '' comment '操作用户',
`ip_address` varchar(64) not null default '' comment '客户端ip',
`module_name` varchar(64) not null default '' comment '模块名',
`content` text comment '日志描述',
`url_path` varchar(64) not null default '' comment 'path路径',
`user_agent` varchar(255) not null default '' comment '客户端agent',
`failed` tinyint(1) not null default 0 comment '是否异常(0:否 1:是)',
`exception` longtext comment '异常堆栈信息',
`elapse_seconds` bigint(20) unsigned not null default 0 comment '执行时间(单位毫秒)',
`create_time` timestamp not null default current_timestamp comment '创建时间',
primary key (`id`)
) engine=innodb auto_increment=1 default charset=utf8 comment='操作日志';
create table `DBSWITCH_DATABASE_CONNECTION` (
`id` bigint(20) unsigned not null auto_increment comment '主键',
`name` varchar(200) not null default '' comment '连接名称',
`type` varchar(200) not null default '' comment '数据库类型',
`version` varchar(255) not null default '' comment '驱动版本',
`driver` varchar(200) not null default '' comment '驱动类名称',
`address` varchar(200) not null default '' comment '连接地址',
`port` varchar(20) not null default '' comment '连接端口号',
`database_name` varchar(200) not null default '' comment '数据库名',
`character_encoding` varchar(20) not null default '' comment '编码格式',
`url` longtext comment 'jdbc-url连接串',
`username` varchar(200) not null default '' comment '连接账号',
`password` varchar(200) not null default '' comment '账号密码',
`create_time` timestamp not null default current_timestamp comment '创建时间',
`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
primary key (`id`),
unique key (`name`)
) engine=innodb auto_increment=1 default charset=utf8 comment='数据库连接';
create table `DBSWITCH_ASSIGNMENT_TASK` (
`id` bigint(20) unsigned not null auto_increment comment '主键',
`name` varchar(200) not null default '' comment '任务名称',
`description` text comment '任务描述',
`schedule_mode` varchar(50) null default null comment '调度方式(cron/无调度)',
`cron_expression` varchar(200) not null default '' comment '调度cron表达式',
`published` tinyint(1) not null default 0 comment '是否已发布(0:否 1:是)',
`content` longtext comment '发布的配置JSON格式',
`job_key` varchar(128) null default '' comment 'JOB KEY',
`create_time` timestamp not null default current_timestamp comment '创建时间',
`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
primary key (`id`)
) engine=innodb auto_increment=1 default charset=utf8 comment='任务信息表';
create table `DBSWITCH_ASSIGNMENT_CONFIG` (
`id` bigint(20) unsigned not null auto_increment comment '主键',
`assignment_id` bigint(20) unsigned not null comment '任务ID',
`source_connection_id` bigint(20) unsigned not null comment '来源端连接ID',
`source_schema` varchar(1024) not null default '' comment '来源端的schema',
`table_type` varchar(32) null default 'TABLE' COMMENT '表类型:TABLE;VIEW',
`source_tables` longtext comment '来源端的table列表',
`excluded_flag` tinyint(1) not null default 0 comment '是否排除(0:否 1:是)',
`target_connection_id` bigint(20) unsigned not null comment '目的端连接ID',
`target_schema` varchar(200) not null default '' comment '目的端的schema(一个)',
`target_only_create` tinyint(1) not null default '0' comment '是否只建表',
`target_drop_table` tinyint(1) not null default 0 comment '同步前是否先删除目的表(0:否 1:是)',
`table_name_map` longtext null comment '表名映射关系',
`column_name_map` longtext null comment '字段名映射关系',
`table_name_case` varchar(32) not null default 'none' comment '表名大小写转换策略',
`column_name_case` varchar(32) not null default 'none' comment '列名大小写转换策略',
`target_auto_increment` tinyint(1) not null default '0' comment '是否支持自增',
`target_sync_option` varchar(32) not null default 'insert_update_delete' comment '同步增删改选项',
`before_sql_scripts` varchar(4096) default null comment '目标端写入的前置执行sql脚本',
`after_sql_scripts` varchar(4096) default null comment '目标端写入的后置执行sql脚本',
`channel_size` bigint(20) unsigned not null default 100 comment '通道队列大小',
`batch_size` bigint(20) unsigned not null default 10000 comment '处理批次大小',
`first_flag` tinyint(1) not null default 1 comment '首次加载数据',
`create_time` timestamp not null default current_timestamp comment '创建时间',
primary key (`id`),
unique key (`assignment_id`),
foreign key (`assignment_id`) references `DBSWITCH_ASSIGNMENT_TASK` (`id`) on delete cascade on update cascade,
foreign key (`source_connection_id`) references `DBSWITCH_DATABASE_CONNECTION` (`id`) on delete cascade on update cascade,
foreign key (`target_connection_id`) references `DBSWITCH_DATABASE_CONNECTION` (`id`) on delete cascade on update cascade
) engine=innodb auto_increment=1 default charset=utf8 comment='任务配置表';
create table `DBSWITCH_ASSIGNMENT_JOB` (
`id` bigint(20) unsigned not null auto_increment comment '主键',
`assignment_id` bigint(20) unsigned not null default 0 comment '任务ID',
`job_key` varchar(200) not null default '' comment 'Quartz的Job名',
`start_time` timestamp not null default current_timestamp comment '执行开始时间',
`finish_time` timestamp not null default current_timestamp comment '执行结束时间',
`schedule_mode` smallint not null default 0 comment '调度模式',
`status` smallint not null default 0 comment '执行状态:0-未执行;1-执行中;2-执行失败;3-执行成功',
`error_log` longtext comment '异常日志',
`create_time` timestamp not null default current_timestamp comment '创建时间',
`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
primary key (`id`),
foreign key (`assignment_id`) references `DBSWITCH_ASSIGNMENT_TASK` (`id`) on delete cascade on update cascade
) engine=innodb auto_increment=1 default charset=utf8 comment='JOB日志表';
CREATE TABLE IF NOT EXISTS `DBSWITCH_JOB_LOGBACK` (
`id` bigint not null auto_increment comment '自增id',
`uuid` varchar(128) not null comment 'job id',
`content` longtext comment '日志内容',
`create_time` timestamp not null default current_timestamp comment '创建时间',
PRIMARY KEY (`id`),
KEY `uuid` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='JOB执行日志';

View File

@@ -0,0 +1,2 @@
insert into `DBSWITCH_SYSTEM_USER`(`username`,`password`,`salt`,`real_name`,`locked`,`email`)
values ('admin', '$2a$10$eUanVjvzV27BBxAb4zuBCugwnngHkRZ7ZB4iI5tdx9ETJ2tnXJJDy', '$2a$10$eUanVjvzV27BBxAb4zuBCu', '管理员', 0,'admin@126.com');

View File

@@ -15,6 +15,8 @@
*/
package org.flywaydb.core.internal.database.h2;
import java.sql.Connection;
import java.sql.SQLException;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.configuration.Configuration;
import org.flywaydb.core.internal.database.base.Database;
@@ -22,196 +24,191 @@ import org.flywaydb.core.internal.database.base.Table;
import org.flywaydb.core.internal.exception.FlywaySqlException;
import org.flywaydb.core.internal.jdbc.JdbcConnectionFactory;
import java.sql.Connection;
import java.sql.SQLException;
/**
* H2 database.
*/
public class H2Database extends Database<H2Connection> {
/**
* A dummy user used in Oracle mode, where USER() can return null but nulls can't be inserted into the
* schema history table
*/
private static final String DEFAULT_USER = "<< default user >>";
/**
* A dummy script marker used in Oracle mode, where a marker row is inserted with no corresponding script.
*/
private static final String DUMMY_SCRIPT_NAME = "<< history table creation script >>";
/**
* The compatibility modes supported by H2. See http://h2database.com/html/features.html#compatibility
*/
private enum CompatibilityMode {
REGULAR,
DB2,
Derby,
HSQLDB,
MSSQLServer,
MySQL,
Oracle,
PostgreSQL,
Ignite
/**
* A dummy user used in Oracle mode, where USER() can return null but nulls can't be inserted into the schema history
* table
*/
private static final String DEFAULT_USER = "<< default user >>";
/**
* A dummy script marker used in Oracle mode, where a marker row is inserted with no corresponding script.
*/
private static final String DUMMY_SCRIPT_NAME = "<< history table creation script >>";
/**
* The compatibility modes supported by H2. See http://h2database.com/html/features.html#compatibility
*/
private enum CompatibilityMode {
REGULAR,
DB2,
Derby,
HSQLDB,
MSSQLServer,
MySQL,
Oracle,
PostgreSQL,
Ignite
}
/**
* Whether this version supports DROP SCHEMA ... CASCADE.
*/
boolean supportsDropSchemaCascade;
/**
* The compatibility mode of the database
*/
CompatibilityMode compatibilityMode;
/**
* Creates a new instance.
*
* @param configuration The Flyway configuration.
*/
public H2Database(Configuration configuration, JdbcConnectionFactory jdbcConnectionFactory) {
super(configuration, jdbcConnectionFactory);
compatibilityMode = determineCompatibilityMode();
}
@Override
protected H2Connection doGetConnection(Connection connection) {
return new H2Connection(this, connection);
}
@Override
protected MigrationVersion determineVersion() {
boolean requiresV2MetadataColumnNames = super.determineVersion().isAtLeast("2.0.0");
String query = requiresV2MetadataColumnNames
? "SELECT SETTING_VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE SETTING_NAME = 'info.BUILD_ID'"
: "SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'info.BUILD_ID'";
try {
int buildId = getMainConnection().getJdbcTemplate().queryForInt(query);
return MigrationVersion.fromVersion(super.determineVersion().getVersion() + "." + buildId);
} catch (SQLException e) {
throw new FlywaySqlException("Unable to determine H2 build ID", e);
}
}
/**
* Whether this version supports DROP SCHEMA ... CASCADE.
*/
boolean supportsDropSchemaCascade;
/**
* The compatibility mode of the database
*/
CompatibilityMode compatibilityMode;
/**
* Creates a new instance.
*
* @param configuration The Flyway configuration.
*/
public H2Database(Configuration configuration, JdbcConnectionFactory jdbcConnectionFactory
) {
super(configuration, jdbcConnectionFactory
);
compatibilityMode = determineCompatibilityMode();
private CompatibilityMode determineCompatibilityMode() {
boolean requiresV2MetadataColumnNames = super.determineVersion().isAtLeast("2.0.0");
String query = requiresV2MetadataColumnNames
? "SELECT SETTING_VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE SETTING_NAME = 'MODE'"
: "SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'MODE'";
try {
String mode = getMainConnection().getJdbcTemplate().queryForString(query);
if (mode == null || "".equals(mode)) {
return CompatibilityMode.REGULAR;
}
return CompatibilityMode.valueOf(mode);
} catch (SQLException e) {
throw new FlywaySqlException("Unable to determine H2 compatibility mode", e);
}
}
@Override
protected H2Connection doGetConnection(Connection connection) {
return new H2Connection(this, connection);
@Override
public final void ensureSupported() {
ensureDatabaseIsRecentEnough("1.2.137");
// ensureDatabaseNotOlderThanOtherwiseRecommendUpgradeToFlywayEdition("1.4",
// org.flywaydb.core.internal.license.Edition.ENTERPRISE);
recommendFlywayUpgradeIfNecessary("2.3.232");
supportsDropSchemaCascade = getVersion().isAtLeast("1.4.200");
}
@Override
public String getRawCreateScript(Table table, boolean baseline) {
// In Oracle mode, empty strings in the marker row would be converted to NULLs. As the script column is
// defined as NOT NULL, we insert a dummy value when required.
String script = (compatibilityMode == CompatibilityMode.Oracle)
? DUMMY_SCRIPT_NAME : "";
return "CREATE TABLE IF NOT EXISTS " + table + " (\n" +
" \"installed_rank\" INT NOT NULL,\n" +
" \"version\" VARCHAR(50),\n" +
" \"description\" VARCHAR(200) NOT NULL,\n" +
" \"type\" VARCHAR(20) NOT NULL,\n" +
" \"script\" VARCHAR(1000) NOT NULL,\n" +
" \"checksum\" INT,\n" +
" \"installed_by\" VARCHAR(100) NOT NULL,\n" +
" \"installed_on\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n" +
" \"execution_time\" INT NOT NULL,\n" +
" \"success\" BOOLEAN NOT NULL,\n" +
" CONSTRAINT \"" + table.getName() + "_pk\" PRIMARY KEY (\"installed_rank\")\n" +
")" +
// Add special table created marker to compensate for the inability of H2 to lock empty tables
" AS SELECT -1, NULL, '<< Flyway Schema History table created >>', 'TABLE', '" + script + "', NULL, '"
+ getInstalledBy() + "', CURRENT_TIMESTAMP, 0, TRUE;\n" +
(baseline ? getBaselineStatement(table) + ";\n" : "") +
"CREATE INDEX \"" + table.getSchema().getName() + "\".\"" + table.getName() + "_s_idx\" ON " + table
+ " (\"success\");";
}
@Override
public String getSelectStatement(Table table) {
return "SELECT " + quote("installed_rank")
+ "," + quote("version")
+ "," + quote("description")
+ "," + quote("type")
+ "," + quote("script")
+ "," + quote("checksum")
+ "," + quote("installed_on")
+ "," + quote("installed_by")
+ "," + quote("execution_time")
+ "," + quote("success")
+ " FROM " + table
// Ignore special table created marker
+ " WHERE " + quote("type") + " != 'TABLE'"
+ " AND " + quote("installed_rank") + " > ?"
+ " ORDER BY " + quote("installed_rank");
}
@Override
protected String doGetCurrentUser() throws SQLException {
// In Oracle mode, empty strings in the installed_by column of the history table would be converted to NULLs.
// As H2 supports a null user, we use a dummy value when required.
String user = getMainConnection().getJdbcTemplate().queryForString("SELECT USER()");
if (compatibilityMode == CompatibilityMode.Oracle && (user == null || "".equals(user))) {
return DEFAULT_USER;
}
return user;
}
@Override
protected MigrationVersion determineVersion() {
try {
int buildId = getMainConnection().getJdbcTemplate().queryForInt(
"SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'info.BUILD_ID'");
return MigrationVersion.fromVersion(super.determineVersion().getVersion() + "." + buildId);
} catch (SQLException e) {
throw new FlywaySqlException("Unable to determine H2 build ID", e);
}
}
@Override
public boolean supportsDdlTransactions() {
return false;
}
private CompatibilityMode determineCompatibilityMode() {
try {
String mode = getMainConnection().getJdbcTemplate().queryForString(
"SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'MODE'");
if (mode == null || "".equals(mode))
return CompatibilityMode.REGULAR;
return CompatibilityMode.valueOf(mode);
} catch (SQLException e) {
throw new FlywaySqlException("Unable to determine H2 compatibility mode", e);
}
}
@Override
public boolean supportsChangingCurrentSchema() {
return true;
}
@Override
public String getBooleanTrue() {
return "1";
}
@Override
public String getBooleanFalse() {
return "0";
}
@Override
public String doQuote(String identifier) {
return "\"" + identifier + "\"";
}
@Override
public final void ensureSupported() {
ensureDatabaseIsRecentEnough("1.2.137");
ensureDatabaseNotOlderThanOtherwiseRecommendUpgradeToFlywayEdition("1.4", org.flywaydb.core.internal.license.Edition.ENTERPRISE);
recommendFlywayUpgradeIfNecessary("1.4.200");
supportsDropSchemaCascade = getVersion().isAtLeast("1.4.200");
}
@Override
public String getRawCreateScript(Table table, boolean baseline) {
// In Oracle mode, empty strings in the marker row would be converted to NULLs. As the script column is
// defined as NOT NULL, we insert a dummy value when required.
String script = (compatibilityMode == CompatibilityMode.Oracle)
? DUMMY_SCRIPT_NAME : "";
return "CREATE TABLE IF NOT EXISTS " + table + " (\n" +
" \"installed_rank\" INT NOT NULL,\n" +
" \"version\" VARCHAR(50),\n" +
" \"description\" VARCHAR(200) NOT NULL,\n" +
" \"type\" VARCHAR(20) NOT NULL,\n" +
" \"script\" VARCHAR(1000) NOT NULL,\n" +
" \"checksum\" INT,\n" +
" \"installed_by\" VARCHAR(100) NOT NULL,\n" +
" \"installed_on\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n" +
" \"execution_time\" INT NOT NULL,\n" +
" \"success\" BOOLEAN NOT NULL,\n" +
" CONSTRAINT \"" + table.getName() + "_pk\" PRIMARY KEY (\"installed_rank\")\n" +
")" +
// Add special table created marker to compensate for the inability of H2 to lock empty tables
" AS SELECT -1, NULL, '<< Flyway Schema History table created >>', 'TABLE', '" + script + "', NULL, '" + getInstalledBy() + "', CURRENT_TIMESTAMP, 0, TRUE;\n" +
(baseline ? getBaselineStatement(table) + ";\n" : "") +
"CREATE INDEX \"" + table.getSchema().getName() + "\".\"" + table.getName() + "_s_idx\" ON " + table + " (\"success\");";
}
@Override
public String getSelectStatement(Table table) {
return "SELECT " + quote("installed_rank")
+ "," + quote("version")
+ "," + quote("description")
+ "," + quote("type")
+ "," + quote("script")
+ "," + quote("checksum")
+ "," + quote("installed_on")
+ "," + quote("installed_by")
+ "," + quote("execution_time")
+ "," + quote("success")
+ " FROM " + table
// Ignore special table created marker
+ " WHERE " + quote("type") + " != 'TABLE'"
+ " AND " + quote("installed_rank") + " > ?"
+ " ORDER BY " + quote("installed_rank");
}
@Override
protected String doGetCurrentUser() throws SQLException {
// In Oracle mode, empty strings in the installed_by column of the history table would be converted to NULLs.
// As H2 supports a null user, we use a dummy value when required.
String user = getMainConnection().getJdbcTemplate().queryForString("SELECT USER()");
if (compatibilityMode == CompatibilityMode.Oracle && (user == null || "".equals(user)))
return DEFAULT_USER;
return user;
}
@Override
public boolean supportsDdlTransactions() {
return false;
}
@Override
public boolean supportsChangingCurrentSchema() {
return true;
}
@Override
public String getBooleanTrue() {
return "1";
}
@Override
public String getBooleanFalse() {
return "0";
}
@Override
public String doQuote(String identifier) {
return "\"" + identifier + "\"";
}
@Override
public boolean catalogIsSchema() {
return false;
}
@Override
public boolean catalogIsSchema() {
return false;
}
}

View File

@@ -127,6 +127,12 @@
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>