Skip to content

Commit

Permalink
Since the destination is mandatory, pass it as argument to dbSetup. S…
Browse files Browse the repository at this point in the history
…o there's no way one can forget to set it, and it's more consistent with insertInto, which takes its destination table as argument.

Also add a shortcut dbSetup() method taking a DataSource as argument directly.
  • Loading branch information
jnizet committed Jun 4, 2016
1 parent f394c23 commit 0e27c24
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,11 @@ import com.ninja_squad.dbsetup.operation.Operation
/**
* A builder allowing to configure a DbSetup from a lambda expression whose receiver type is this builder.
* The intended usage is to use the [dbSetup] top level function.
*
* @param to The destination of the DbSetup
* @property binderConfiguration The binder configuration of the DbSetup. It not set, the default configuration is used
*/
class DbSetupBuilder {

/**
* The destination of the DbSetup. It is mandatory
*/
var destination: Destination? = null

/**
* The binder configuration of the DbSetup. It not set, the default configuration is used
*/
var binderConfiguration: BinderConfiguration = DefaultBinderConfiguration.INSTANCE
class DbSetupBuilder(private val to: Destination, var binderConfiguration: BinderConfiguration = DefaultBinderConfiguration.INSTANCE) {

private val operations = mutableListOf<Operation>()

Expand Down Expand Up @@ -159,7 +152,7 @@ class DbSetupBuilder {
* @throws IllegalStateException if the destination has not been set
*/
internal fun build(): DbSetup {
return DbSetup(destination ?: throw IllegalStateException("destination hasn't been set"),
return DbSetup(to,
Operations.sequenceOf(operations),
binderConfiguration)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,21 @@
package com.ninja_squad.dbsetup_kotlin

import com.ninja_squad.dbsetup.DbSetup
import com.ninja_squad.dbsetup.bind.BinderConfiguration
import com.ninja_squad.dbsetup.bind.DefaultBinderConfiguration
import com.ninja_squad.dbsetup.destination.DataSourceDestination
import com.ninja_squad.dbsetup.destination.Destination
import com.ninja_squad.dbsetup.operation.Insert
import javax.sql.DataSource

/**
* Top-level function allowing to create a DbSetup by passing a lambda expression configuring it.
* Top-level function allowing to create a DbSetup by passing a destination and a lambda expression used to configure
* the operations that must be made.
*
* Example usage:
*
* ```
* val setup = dbSetup {
* destination = DataSourceDestination(dataSource)
*
* val setup = dbSetup(to = DriverManagerDestination(url, user, password)) {
* deleteAllFrom("user", "country")
* insertInto("country") {
* ...
Expand All @@ -46,18 +50,50 @@ import com.ninja_squad.dbsetup.operation.Insert
* }
* ```
*
* @param to the destination of the DbSetup
* @param binderConfiguration a custom binder configuration. The default one is used if not specified
* @param configure the function used to configure the DbSetup
* @throws IllegalStateException if the destination has not been set by the configure function
* @return the created DbSetup
*
* @author JB Nizet
*/
fun dbSetup(configure: DbSetupBuilder.() -> Unit): DbSetup {
val builder = DbSetupBuilder()
fun dbSetup(to: Destination,
binderConfiguration: BinderConfiguration = DefaultBinderConfiguration.INSTANCE,
configure: DbSetupBuilder.() -> Unit): DbSetup {
val builder = DbSetupBuilder(to, binderConfiguration)
builder.configure()
return builder.build()
}

/**
* Top-level function allowing to create a DbSetup by passing a DataSource and a lambda expression used to configure
* the operations that must be made.
*
* Example usage:
*
* ```
* val setup = dbSetup(to = dataSource) {
* deleteAllFrom("user", "country")
* insertInto("country") {
* ...
* }
* insertInto("user") {
* ...
* }
* sql(...)
* }
* ```
*
* @param to the destination of the DbSetup
* @param binderConfiguration a custom binder configuration. The default one is used if not specified
* @param configure the function used to configure the DbSetup
* @return the created DbSetup
*
* @author JB Nizet
*/
fun dbSetup(to: DataSource,
binderConfiguration: BinderConfiguration = DefaultBinderConfiguration.INSTANCE,
configure: DbSetupBuilder.() -> Unit) = dbSetup(DataSourceDestination(to), binderConfiguration, configure)
/**
* Top-level function allowing to create an Insert operation by passing a lambda expression configuring it.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.mockito.Mockito.verify
import java.sql.Connection
import java.sql.PreparedStatement
import java.sql.Statement
import javax.sql.DataSource

class DbSetupBuilderTest {

Expand All @@ -31,9 +32,8 @@ class DbSetupBuilderTest {
}

@Test
fun `should execute an operation`() {
dbSetup {
destination = mockDestination
fun `should execute an operation with the binder configuration specified as property`() {
dbSetup(to = mockDestination) {
binderConfiguration = mockConfig
execute(mockOperation)
}.launch()
Expand All @@ -42,26 +42,37 @@ class DbSetupBuilderTest {
}

@Test
fun `should use the default binder configuration if not set`() {
dbSetup {
destination = mockDestination
fun `should execute an operation with the binder configuration specified as argument`() {
dbSetup(to = mockDestination, binderConfiguration = mockConfig) {
execute(mockOperation)
}.launch()

verify(mockOperation).execute(mockConnection, DefaultBinderConfiguration.INSTANCE)
verify(mockOperation).execute(mockConnection, mockConfig)
}

@Test(expected = IllegalStateException::class)
fun `should throw if destination not set`() {
dbSetup {
@Test
fun `should execute an operation with a DataSource specified as argument`() {
val mockDataSource = mock<DataSource>()
whenever(mockDataSource.connection).thenReturn(mockConnection)
dbSetup(to = mockDataSource, binderConfiguration = mockConfig) {
execute(mockOperation)
}.launch()

verify(mockOperation).execute(mockConnection, mockConfig)
}

@Test
fun `should use the default binder configuration if not set`() {
dbSetup(to = mockDestination) {
execute(mockOperation)
}.launch()

verify(mockOperation).execute(mockConnection, DefaultBinderConfiguration.INSTANCE)
}

@Test
fun `should delete all from one table`() {
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
deleteAllFrom("user")
}.launch()

Expand All @@ -70,8 +81,7 @@ class DbSetupBuilderTest {

@Test
fun `should delete all from multiple tables passed as vararg`() {
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
deleteAllFrom("country", "user")
}.launch()

Expand All @@ -81,8 +91,7 @@ class DbSetupBuilderTest {

@Test
fun `should delete all from multiple tables passed as list`() {
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
deleteAllFrom(listOf("country", "user"))
}.launch()

Expand All @@ -92,8 +101,7 @@ class DbSetupBuilderTest {

@Test
fun `should truncate one table`() {
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
truncate("user")
}.launch()

Expand All @@ -102,8 +110,7 @@ class DbSetupBuilderTest {

@Test
fun `should truncate multiple tables passed as vararg`() {
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
truncate("country", "user")
}.launch()

Expand All @@ -113,8 +120,7 @@ class DbSetupBuilderTest {

@Test
fun `should truncate multiple tables passed as list`() {
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
truncate(listOf("country", "user"))
}.launch()

Expand All @@ -125,8 +131,7 @@ class DbSetupBuilderTest {
@Test
fun `should execute one sql statement`() {
val query = "update foo where bar = 1"
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
sql(query)
}.launch()

Expand All @@ -137,8 +142,7 @@ class DbSetupBuilderTest {
fun `should execute multiple sql statements passed as vararg`() {
val query1 = "update foo where bar = 1"
val query2 = "update baz where qux = 1"
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
sql(query1, query2)
}.launch()

Expand All @@ -150,8 +154,7 @@ class DbSetupBuilderTest {
fun `should execute multiple sql statements passed as list`() {
val query1 = "update foo where bar = 1"
val query2 = "update baz where qux = 1"
dbSetup {
destination = mockDestination
dbSetup(to = mockDestination) {
sql(listOf(query1, query2))
}.launch()

Expand All @@ -165,9 +168,7 @@ class DbSetupBuilderTest {
whenever(mockConnection.prepareStatement("insert into user (id, name) values (?, ?)"))
.thenReturn(mockPreparedStatement)

dbSetup {
destination = mockDestination

dbSetup(to = mockDestination) {
insertInto("user") {
columns("id", "name")
values(1, "John")
Expand Down
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ subprojects { subProject ->
publish = true
pkg {
repo = 'maven'
println(subProject.name)
name = subProject.name
desc = subProject.description
websiteUrl = 'http:https://dbsetup.ninja-squad.com'
Expand Down

0 comments on commit 0e27c24

Please sign in to comment.