Skip to content

Commit 4364998

Browse files
jakubjanecekmergify[bot]
authored andcommitted
Add Flyway support (#53)
* WIP * feat: Add flyway and flyway-pureconfig modules Closes #6 * fix: compilation error * refactor: PR changes * docs: Add some Flyway documentation * docs: Add some Flyway documentation * refactor: Minor PR tweaks
1 parent 5e8b06b commit 4364998

File tree

10 files changed

+166
-1
lines changed

10 files changed

+166
-1
lines changed

build.sbt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ lazy val root = project
2323
doobieHikari,
2424
doobieHikariPureConfig,
2525
example,
26+
flyway,
27+
flywayPureConfig,
2628
http4sClientBlaze,
2729
http4sClientBlazePureConfig,
2830
http4sServer,
@@ -85,7 +87,7 @@ lazy val doobieHikariPureConfig = project
8587

8688
lazy val example = project
8789
.in(file("example"))
88-
.dependsOn(bundleZioHttp4sBlaze, doobieHikari, doobieHikariPureConfig, micrometerJmxPureConfig, sslConfig)
90+
.dependsOn(bundleZioHttp4sBlaze, doobieHikari, doobieHikariPureConfig, flyway, flywayPureConfig, micrometerJmxPureConfig, sslConfig)
8991
.enablePlugins(MdocPlugin)
9092
.settings(commonSettings)
9193
.settings(
@@ -101,6 +103,23 @@ lazy val example = project
101103
)
102104
)
103105

106+
lazy val flyway = project
107+
.in(file("flyway"))
108+
.settings(commonSettings)
109+
.settings(
110+
name := "sst-flyway",
111+
libraryDependencies += Dependencies.flywayCore
112+
)
113+
114+
lazy val flywayPureConfig = project
115+
.in(file("flyway-pureconfig"))
116+
.dependsOn(flyway)
117+
.settings(commonSettings)
118+
.settings(
119+
name := "sst-flyway-pureconfig",
120+
libraryDependencies += Dependencies.pureConfig
121+
)
122+
104123
lazy val http4sClientBlaze = project
105124
.in(file("http4s-client-blaze"))
106125
.settings(commonSettings)

docs/flyway.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Flyway
2+
3+
[![Maven Central](https://img.shields.io/maven-central/v/com.avast/sst-flyway_2.12)](https://repo1.maven.org/maven2/com/avast/sst-flyway_2.12/)
4+
5+
`libraryDependencies += "com.avast" %% "sst-flyway" % "<VERSION>"`
6+
7+
This module initializes `Flyway` which can be used to do automated SQL DB migrations. See the [documentation of Flyway](https://flywaydb.org/documentation/)
8+
on how to go about that.
9+
10+
The method `make` requires `javax.sql.DataSource` which you can for example obtain from `doobie-hikari` module:
11+
12+
```scala
13+
import cats.effect.Resource
14+
import com.avast.sst.doobie.DoobieHikariModule
15+
import com.avast.sst.flyway.FlywayModule
16+
import zio.Task
17+
import zio.interop.catz._
18+
import zio.interop.catz.implicits._
19+
20+
for {
21+
doobieTransactor <- DoobieHikariModule.make[Task](???, ???, ???, ???)
22+
flyway <- Resource.liftF(FlywayModule.make[Task](doobieTransactor.kernel, ???))
23+
} yield ()
24+
```
25+

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* [Module PureConfig](pureconfig.md)
1111
* [Module SSL Config](ssl-config.md)
1212
* [Module doobie](doobie.md)
13+
* [Module Flyway](flyway.md)
1314

1415
## Getting Started
1516

example/mdoc/flyway.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Flyway
2+
3+
[![Maven Central](https://img.shields.io/maven-central/v/com.avast/sst-flyway_2.12)](https://repo1.maven.org/maven2/com/avast/sst-flyway_2.12/)
4+
5+
`libraryDependencies += "com.avast" %% "sst-flyway" % "<VERSION>"`
6+
7+
This module initializes `Flyway` which can be used to do automated SQL DB migrations. See the [documentation of Flyway](https://flywaydb.org/documentation/)
8+
on how to go about that.
9+
10+
The method `make` requires `javax.sql.DataSource` which you can for example obtain from `doobie-hikari` module:
11+
12+
```scala
13+
import cats.effect.Resource
14+
import com.avast.sst.doobie.DoobieHikariModule
15+
import com.avast.sst.flyway.FlywayModule
16+
import zio.Task
17+
import zio.interop.catz._
18+
import zio.interop.catz.implicits._
19+
20+
for {
21+
doobieTransactor <- DoobieHikariModule.make[Task](???, ???, ???, ???)
22+
flyway <- Resource.liftF(FlywayModule.make[Task](doobieTransactor.kernel, ???))
23+
} yield ()
24+
```

example/mdoc/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* [Module PureConfig](pureconfig.md)
1111
* [Module SSL Config](ssl-config.md)
1212
* [Module doobie](doobie.md)
13+
* [Module Flyway](flyway.md)
1314

1415
## Getting Started
1516

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.avast.sst.flyway.pureconfig
2+
3+
import java.nio.charset.Charset
4+
5+
import cats.syntax.either._
6+
import com.avast.sst.flyway.FlywayConfig
7+
import org.flywaydb.core.api.MigrationVersion
8+
import pureconfig.ConfigReader
9+
import pureconfig.error.ExceptionThrown
10+
import pureconfig.generic.semiauto.deriveReader
11+
12+
trait ConfigReaders {
13+
14+
implicit private[pureconfig] val charsetReader: ConfigReader[Charset] = ConfigReader[String].emap { value =>
15+
Either.catchNonFatal(Charset.forName(value)).leftMap(ExceptionThrown.apply)
16+
}
17+
18+
implicit val migrationVersionReader: ConfigReader[MigrationVersion] = ConfigReader[String].map(MigrationVersion.fromVersion)
19+
20+
implicit val configReader: ConfigReader[FlywayConfig] = deriveReader
21+
22+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.avast.sst.flyway.pureconfig
2+
3+
object implicits extends ConfigReaders
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.avast.sst.flyway
2+
3+
import java.nio.charset.{Charset, StandardCharsets}
4+
5+
import org.flywaydb.core.api.MigrationVersion
6+
7+
final case class FlywayConfig(baselineOnMigrate: Boolean = false,
8+
baselineVersion: Option[MigrationVersion] = None,
9+
targetVersion: Option[MigrationVersion] = None,
10+
baselineDescription: Option[String] = None,
11+
batch: Boolean = false,
12+
cleanDisabled: Boolean = false,
13+
cleanOnValidationError: Boolean = false,
14+
connectRetries: Int = 0,
15+
encoding: Charset = StandardCharsets.UTF_8,
16+
group: Boolean = false,
17+
ignoreFutureMigrations: Boolean = true,
18+
ignoreIgnoredMigrations: Boolean = false,
19+
ignoreMissingMigrations: Boolean = false,
20+
ignorePendingMigrations: Boolean = false,
21+
installedBy: Option[String] = None,
22+
mixed: Boolean = false,
23+
locations: List[String] = List.empty,
24+
outOfOrder: Boolean = false,
25+
validateOnMigrate: Boolean = true,
26+
licenseKey: Option[String] = None)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.avast.sst.flyway
2+
3+
import cats.effect.Sync
4+
import javax.sql.DataSource
5+
import org.flywaydb.core.Flyway
6+
7+
object FlywayModule {
8+
9+
/** Makes [[org.flywaydb.core.Flyway]] from the given [[javax.sql.DataSource]] and config. */
10+
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
11+
def make[F[_]: Sync](dataSource: DataSource, config: FlywayConfig): F[Flyway] = {
12+
Sync[F].delay {
13+
val builder = Flyway
14+
.configure
15+
.dataSource(dataSource)
16+
.baselineOnMigrate(config.baselineOnMigrate)
17+
.batch(config.batch)
18+
.cleanDisabled(config.cleanDisabled)
19+
.cleanOnValidationError(config.cleanOnValidationError)
20+
.connectRetries(config.connectRetries)
21+
.encoding(config.encoding)
22+
.group(config.group)
23+
.ignoreFutureMigrations(config.ignoreFutureMigrations)
24+
.ignoreIgnoredMigrations(config.ignoreIgnoredMigrations)
25+
.ignoreMissingMigrations(config.ignoreMissingMigrations)
26+
.ignorePendingMigrations(config.ignorePendingMigrations)
27+
.mixed(config.mixed)
28+
.outOfOrder(config.outOfOrder)
29+
.validateOnMigrate(config.validateOnMigrate)
30+
31+
config.baselineVersion.foreach(builder.baselineVersion)
32+
config.targetVersion.foreach(builder.target)
33+
config.baselineDescription.foreach(builder.baselineDescription)
34+
config.installedBy.foreach(builder.installedBy)
35+
if (config.locations.nonEmpty) builder.locations(config.locations: _*)
36+
37+
config.licenseKey.foreach(builder.licenseKey)
38+
39+
builder.load()
40+
}
41+
}
42+
43+
}

project/Dependencies.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ object Dependencies {
55
val catsEffect = "org.typelevel" %% "cats-effect" % "2.0.0"
66
val doobie = "org.tpolecat" %% "doobie-core" % Versions.doobie
77
val doobieHikari = "org.tpolecat" %% "doobie-hikari" % Versions.doobie
8+
val flywayCore = "org.flywaydb" % "flyway-core" % "6.0.7"
89
val http4sBlazeClient = "org.http4s" %% "http4s-blaze-client" % Versions.http4s
910
val http4sBlazeServer = "org.http4s" %% "http4s-blaze-server" % Versions.http4s
1011
val http4sDsl = "org.http4s" %% "http4s-dsl" % Versions.http4s

0 commit comments

Comments
 (0)