DBスキーマはFlywayで管理する前提で、テスト中の一時的なデータをバックアップ&リストアするために、Gradleのタスクを作りました。
./gradlew backupH2 flywayClean flywayMigrate restoreH2
みたいにしたかったのですが、Flywayの管理テーブル(schema_version)やFlywayのスクリプトで管理しているデータがあるため、プライマリキー違反になってしまいダメでした。。。
とりあえず、データだけバックアップする方法としてメモを残しておこう。
バックアップとリストアのタスク
バックアップは「Backup using the Script Tool」で作成したスクリプトファイルからCREATE文とALTER文を取り除いているだけです。
build.gradle
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
runtime('com.h2database:h2:1.4.196')
}
// H2を使用するアプリのbuild.gradleが既にある場合は、ここから下を追記するだけで大丈夫なはず。
// スクリプトファイル名、DB接続URLなどは適宜変更する。
// H2のデータのバックアップ
task backupH2(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'org.h2.tools.Script'
args = ['-url', 'jdbc:h2:file:./h2/hoge', '-user', 'sa', '-password', '', '-script', 'data.sql']
doLast {
file('data.sql').text = file('data.sql').text.replaceAll(/(CREATE|ALTER)[^;]+;\s*\R*/, '')
}
}
// H2のデータのリストア
task restoreH2(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'org.h2.tools.RunScript'
args = ['-url', 'jdbc:h2:file:./h2/hoge', '-user', 'sa', '-password', '', '-script', 'data.sql']
}
(追記)改良版
バックアップとリストアの部分の改良版です。
スクリプトファイルに対して、Flywayの管理テーブル(schema_version)のINSERT文を削除し、その他のテーブルのDELETE文を追加しています。
def h2Url = 'jdbc:h2:file:./h2/hoge'
def h2User = 'sa'
def h2Password = ''
def h2ScriptFileName = 'data.sql'
// H2のデータのバックアップ
task backupH2(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'org.h2.tools.Script'
args = ['-url', h2Url, '-user', h2User, '-password', h2Password, '-script', h2ScriptFileName]
doLast {
def insertScript = file(h2ScriptFileName).text
insertScript = insertScript.replaceAll(/(CREATE|ALTER)[^;]+;\s*\R*/, '')
insertScript = insertScript.replaceAll(/(--|INSERT)[^;]+schema_version[^;]+;\s*\R*/, '')
def deleteScript = ';\n'
Set<String> tables = []
insertScript.findAll(/INSERT INTO ([^\s]+)\([^;]+;\s*\R*/){ g0, g1 -> tables.add(g1) }
tables.forEach() { table -> deleteScript += 'DELETE FROM ' + table + ';\n' }
file(h2ScriptFileName).text = deleteScript + insertScript
}
}
// H2のデータのリストア
task restoreH2(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'org.h2.tools.RunScript'
args = ['-url', h2Url, '-user', h2User, '-password', h2Password, '-script', h2ScriptFileName]
}
自分の環境では
./gradlew backupH2 flywayClean flywayMigrate restoreH2
ができたので、ひとまず良しとしよう。