@@ -20,7 +20,7 @@ import slick.jdbc.JdbcProfile
20
20
21
21
import scala .collection .JavaConverters ._
22
22
import scala .concurrent .{ ExecutionContext , Future , blocking }
23
- import scala .util .Try
23
+ import scala .util .control . NonFatal
24
24
25
25
/**
26
26
* Runs Liquibase based database schema and data migrations. This is the only place for all related
@@ -41,7 +41,7 @@ trait BaseSchemaMigrationImpl extends SchemaMigration {
41
41
protected val defaultSchemaName = " hat"
42
42
protected val liquibaseSchemaName = " public"
43
43
44
- def run (evolutionsConfig : String = " db.default.evolutions" ): Future [Unit ] = {
44
+ def run (evolutionsConfig : String = " db.default.evolutions" ): Future [Unit ] =
45
45
Option (configuration.getStringList(evolutionsConfig))
46
46
.map(_.asScala)
47
47
.map { migrations =>
@@ -51,118 +51,76 @@ trait BaseSchemaMigrationImpl extends SchemaMigration {
51
51
logger.warn(" No evolutions configured" )
52
52
Future .successful(())
53
53
}
54
- }
55
54
56
55
/**
57
56
* Invoke this method to apply all DB migrations.
58
57
*/
59
58
def run (changeLogFiles : Seq [String ]): Future [Unit ] = {
60
- logger.error(s " Running schema migrations: ${changeLogFiles.mkString(" , " )}" )
61
- Future (db.createSession().conn).map { dbConnection ⇒
62
- changeLogFiles.foldLeft(Future .successful(())) { (execution, evolution) ⇒
63
- execution.flatMap { _ ⇒
64
- logger.error(s " Running evolution $evolution" )
65
- updateDb(evolution, dbConnection)
66
- }
67
- } onComplete {
68
- _ ⇒ dbConnection.close()
59
+ logger.info(s " Running schema migrations: ${changeLogFiles.mkString(" , " )}" )
60
+ Future (db.createSession().conn).flatMap { dbConnection =>
61
+ val sequencedEvolutions : Future [Unit ] = changeLogFiles.foldLeft(Future .successful(())) { (execution, evolution) =>
62
+ execution.flatMap(_ => updateDb(evolution, dbConnection))
69
63
}
64
+ sequencedEvolutions.onComplete(_ => dbConnection.close())
65
+ sequencedEvolutions
70
66
} recover {
71
- case e ⇒ logger.error(s " Running database evolutions failed: ${e.getMessage} " , e)
67
+ case e => logger.error(" Running database evolutions failed" , e)
72
68
}
73
69
}
74
70
75
- def resetDatabase (): Future [Unit ] = {
76
- val eventuallyEvolved = Future {
77
- val dbConnection = db.createSession().conn
78
-
79
- val liquibase = blocking {
80
- createLiquibase(dbConnection, " " )
81
- }
71
+ def resetDatabase (): Future [Unit ] =
72
+ Future {
82
73
blocking {
83
- Try (liquibase.dropAll())
84
- .recover {
85
- case e =>
86
- liquibase.forceReleaseLocks()
87
- logger.error( s " Error dropping all database information " )
88
- throw e
89
- }
90
- liquibase.forceReleaseLocks()
74
+ val dbConnection = db.createSession().conn
75
+ val liquibase = createLiquibase(dbConnection, " " )
76
+ try liquibase.dropAll()
77
+ catch {
78
+ case NonFatal (th) =>
79
+ logger.error( " Error dropping all database information " , th)
80
+ throw th
81
+ } finally liquibase.forceReleaseLocks()
91
82
}
92
83
}
93
84
94
- eventuallyEvolved.failed.foreach { e =>
95
- logger.error(s " Error updating database: ${e.getMessage}" )
96
- }
97
-
98
- eventuallyEvolved
99
- }
100
-
101
85
def rollback (changeLogFiles : Seq [String ]): Future [Unit ] = {
102
86
logger.info(s " Rolling back schema migrations: ${changeLogFiles.mkString(" , " )}" )
103
87
changeLogFiles.foldLeft(Future .successful(())) { (execution, evolution) => execution.flatMap { _ => rollbackDb(evolution) } }
104
88
}
105
89
106
- private def updateDb (diffFilePath : String , dbConnection : Connection ): Future [Unit ] = {
107
- val eventuallyEvolved = Future {
108
-
109
- logger.info(s " Liquibase running evolutions $diffFilePath on db: [ ${dbConnection.getMetaData.getURL}] " )
110
- val liquibase = blocking {
111
- createLiquibase(dbConnection, diffFilePath)
112
- }
90
+ private def updateDb (diffFilePath : String , dbConnection : Connection ): Future [Unit ] =
91
+ Future {
113
92
blocking {
93
+ logger.info(s " Liquibase running evolutions $diffFilePath on db: [ ${dbConnection.getMetaData.getURL}] " )
94
+ val liquibase = createLiquibase(dbConnection, diffFilePath)
114
95
listChangesets(liquibase, new Contexts (changeContexts))
115
- Try (liquibase.update(changeContexts))
116
- .recover {
117
- case e =>
118
- liquibase.forceReleaseLocks()
119
- logger.error(s " Error executing schema evolutions: ${e.getMessage}" )
120
- throw e
121
- }
122
- liquibase.forceReleaseLocks()
96
+ try liquibase.update(changeContexts)
97
+ catch {
98
+ case NonFatal (th) =>
99
+ logger.error(s " Error executing schema evolutions: ${th.getMessage}" )
100
+ throw th
101
+ } finally liquibase.forceReleaseLocks()
123
102
}
124
103
}
125
104
126
- eventuallyEvolved.failed.foreach { e =>
127
- logger.error(s " Error updating database: ${e.getMessage}" )
128
- }
129
-
130
- eventuallyEvolved
131
- }
132
-
133
- private def rollbackDb (diffFilePath : String ): Future [Unit ] = {
134
- val eventuallyEvolved = Future {
135
-
136
- val dbConnection = db.createSession().conn
137
-
138
- logger.info(s " Liquibase rolling back evolutions $diffFilePath on db: [ ${dbConnection.getMetaData.getURL}] " )
139
- val liquibase = blocking {
140
- createLiquibase(dbConnection, diffFilePath)
141
- }
105
+ private def rollbackDb (diffFilePath : String ): Future [Unit ] =
106
+ Future {
142
107
blocking {
108
+ val dbConnection = db.createSession().conn
109
+ logger.info(s " Liquibase rolling back evolutions $diffFilePath on db: [ ${dbConnection.getMetaData.getURL}] " )
110
+ val liquibase = createLiquibase(dbConnection, diffFilePath)
143
111
val contexts = new Contexts (changeContexts)
144
112
val changesetsExecuted = liquibase.getChangeSetStatuses(contexts, new LabelExpression ()).asScala.filterNot(_.getWillRun)
145
- Try (liquibase.rollback(changesetsExecuted.length, contexts, new LabelExpression ()))
146
- .recover {
147
- case e =>
148
- liquibase.forceReleaseLocks()
149
- logger.error(s " Error executing schema evolutions: ${e.getMessage}" )
150
- throw e
151
- }
152
- liquibase.forceReleaseLocks()
113
+ try liquibase.rollback(changesetsExecuted.length, contexts, new LabelExpression ())
114
+ catch {
115
+ case NonFatal (th) =>
116
+ logger.error(s " Error rolling back schema evolutions: ${th.getMessage}" )
117
+ throw th
118
+ } finally liquibase.forceReleaseLocks()
153
119
}
154
120
}
155
121
156
- eventuallyEvolved.failed.foreach { e =>
157
- logger.error(s " Error updating database: ${e.getMessage}" )
158
- }
159
-
160
- eventuallyEvolved
161
- }
162
-
163
122
private def listChangesets (liquibase : Liquibase , contexts : Contexts ): Unit = {
164
123
val changesetStatuses = liquibase.getChangeSetStatuses(contexts, new LabelExpression ()).asScala
165
-
166
124
logger.info(" Existing changesets:" )
167
125
changesetStatuses.foreach { cs =>
168
126
if (cs.getWillRun) {
@@ -176,7 +134,6 @@ trait BaseSchemaMigrationImpl extends SchemaMigration {
176
134
protected def createLiquibase (dbConnection : Connection , diffFilePath : String ): Liquibase = {
177
135
val classLoader = configuration.getClass.getClassLoader
178
136
val resourceAccessor = new ClassLoaderResourceAccessor (classLoader)
179
-
180
137
val database = DatabaseFactory .getInstance()
181
138
.findCorrectDatabaseImplementation(new JdbcConnection (dbConnection))
182
139
database.setDefaultSchemaName(defaultSchemaName)
0 commit comments