Initial Development #1
6
pom.xml
6
pom.xml
@ -113,6 +113,12 @@
|
||||
<version>3.46.1.2</version>
|
||||
<scope>integration-test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.7.5</version>
|
||||
<scope>integration-test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,103 +0,0 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.query.Count
|
||||
import solutions.bitbadger.documents.query.Find
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Custom` object / `custom*` connection extension functions
|
||||
*/
|
||||
@DisplayName("SQLite - Custom")
|
||||
class CustomSQLiteIT {
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with empty list")
|
||||
fun listEmpty() =
|
||||
SQLiteDB().use { db ->
|
||||
JsonDocument.load(db.conn, SQLiteDB.tableName)
|
||||
db.conn.customNonQuery("DELETE FROM ${SQLiteDB.tableName}")
|
||||
val result = db.conn.customList<JsonDocument>(Find.all(SQLiteDB.tableName), mapFunc = Results::fromData)
|
||||
assertEquals(0, result.size, "There should have been no results")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with a non-empty list")
|
||||
fun listAll() =
|
||||
SQLiteDB().use { db ->
|
||||
JsonDocument.load(db.conn, SQLiteDB.tableName)
|
||||
val result = db.conn.customList<JsonDocument>(Find.all(SQLiteDB.tableName), mapFunc = Results::fromData)
|
||||
assertEquals(5, result.size, "There should have been 5 results")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when document not found")
|
||||
fun singleNone() =
|
||||
SQLiteDB().use { db ->
|
||||
assertNull(
|
||||
db.conn.customSingle(Find.all(SQLiteDB.tableName), mapFunc = Results::fromData),
|
||||
"There should not have been a document returned"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when a document is found")
|
||||
fun singleOne() {
|
||||
SQLiteDB().use { db ->
|
||||
JsonDocument.load(db.conn, SQLiteDB.tableName)
|
||||
assertNotNull(
|
||||
db.conn.customSingle<JsonDocument>(Find.all(SQLiteDB.tableName), mapFunc = Results::fromData),
|
||||
"There should not have been a document returned"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes changes")
|
||||
fun nonQueryChanges() =
|
||||
SQLiteDB().use { db ->
|
||||
JsonDocument.load(db.conn, SQLiteDB.tableName)
|
||||
assertEquals(
|
||||
5L, db.conn.customScalar(Count.all(SQLiteDB.tableName), mapFunc = Results::toCount),
|
||||
"There should have been 5 documents in the table"
|
||||
)
|
||||
db.conn.customNonQuery("DELETE FROM ${SQLiteDB.tableName}")
|
||||
assertEquals(
|
||||
0L, db.conn.customScalar(Count.all(SQLiteDB.tableName), mapFunc = Results::toCount),
|
||||
"There should have been no documents in the table"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes no changes when where clause matches nothing")
|
||||
fun nonQueryNoChanges() =
|
||||
SQLiteDB().use { db ->
|
||||
JsonDocument.load(db.conn, SQLiteDB.tableName)
|
||||
assertEquals(
|
||||
5L, db.conn.customScalar(Count.all(SQLiteDB.tableName), mapFunc = Results::toCount),
|
||||
"There should have been 5 documents in the table"
|
||||
)
|
||||
db.conn.customNonQuery(
|
||||
"DELETE FROM ${SQLiteDB.tableName} WHERE data->>'id' = :id",
|
||||
listOf(Parameter(":id", ParameterType.STRING, "eighty-two"))
|
||||
)
|
||||
assertEquals(
|
||||
5L, db.conn.customScalar(Count.all(SQLiteDB.tableName), mapFunc = Results::toCount),
|
||||
"There should still have been 5 documents in the table"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("scalar succeeds")
|
||||
fun scalar() =
|
||||
SQLiteDB().use { db ->
|
||||
assertEquals(
|
||||
3L,
|
||||
db.conn.customScalar("SELECT 3 AS it FROM ${SQLiteDB.catalog} LIMIT 1", mapFunc = Results::toCount),
|
||||
"The number 3 should have been returned"
|
||||
)
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.fail
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||
*/
|
||||
@DisplayName("SQLite - Document")
|
||||
class DocumentSQLiteIT {
|
||||
|
||||
@Test
|
||||
@DisplayName("insert works with default values")
|
||||
fun insertDefault() =
|
||||
SQLiteDB().use { db ->
|
||||
assertEquals(0L, db.conn.countAll(SQLiteDB.tableName), "There should be no documents in the table")
|
||||
val doc = JsonDocument("turkey", "", 0, SubDocument("gobble", "gobble"))
|
||||
db.conn.insert(SQLiteDB.tableName, doc)
|
||||
val after = db.conn.findAll<JsonDocument>(SQLiteDB.tableName)
|
||||
assertEquals(1, after.size, "There should be one document in the table")
|
||||
assertEquals(doc, after[0], "The document should be what was inserted")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert fails with duplicate key")
|
||||
fun insertDupe() =
|
||||
SQLiteDB().use { db ->
|
||||
db.conn.insert(SQLiteDB.tableName, JsonDocument("a", "", 0, null))
|
||||
try {
|
||||
db.conn.insert(SQLiteDB.tableName, JsonDocument("a", "b", 22, null))
|
||||
fail("Inserting a document with a duplicate key should have thrown an exception")
|
||||
} catch (_: Exception) {
|
||||
// yay
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with numeric auto IDs")
|
||||
fun insertNumAutoId() =
|
||||
SQLiteDB().use { db ->
|
||||
try {
|
||||
Configuration.autoIdStrategy = AutoId.NUMBER
|
||||
Configuration.idField = "key"
|
||||
assertEquals(0L, db.conn.countAll(SQLiteDB.tableName), "There should be no documents in the table")
|
||||
|
||||
db.conn.insert(SQLiteDB.tableName, NumIdDocument(0, "one"))
|
||||
db.conn.insert(SQLiteDB.tableName, NumIdDocument(0, "two"))
|
||||
db.conn.insert(SQLiteDB.tableName, NumIdDocument(77, "three"))
|
||||
db.conn.insert(SQLiteDB.tableName, NumIdDocument(0, "four"))
|
||||
|
||||
val after = db.conn.findAll<NumIdDocument>(SQLiteDB.tableName, listOf(Field.named("key")))
|
||||
assertEquals(4, after.size, "There should have been 4 documents returned")
|
||||
assertEquals(
|
||||
"1|2|77|78", after.joinToString("|") { it.key.toString() },
|
||||
"The IDs were not generated correctly"
|
||||
)
|
||||
} finally {
|
||||
Configuration.autoIdStrategy = AutoId.DISABLED
|
||||
Configuration.idField = "id"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: UUID, Random String
|
||||
}
|
@ -38,3 +38,6 @@ data class JsonDocument(val id: String, val value: String, val numValue: Int, va
|
||||
testDocuments.forEach { conn.insert(tableName, it) }
|
||||
}
|
||||
}
|
||||
|
||||
/** The test table name to use for integration tests */
|
||||
val testTableName = "test_table"
|
||||
|
80
src/integration-test/kotlin/common/Custom.kt
Normal file
80
src/integration-test/kotlin/common/Custom.kt
Normal file
@ -0,0 +1,80 @@
|
||||
package solutions.bitbadger.documents.common
|
||||
|
||||
import solutions.bitbadger.documents.*
|
||||
import solutions.bitbadger.documents.query.Count
|
||||
import solutions.bitbadger.documents.query.Find
|
||||
import java.sql.Connection
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
/**
|
||||
* Integration tests for the `Custom` object
|
||||
*/
|
||||
object Custom {
|
||||
|
||||
fun listEmpty(conn: Connection) {
|
||||
JsonDocument.load(conn, testTableName)
|
||||
conn.customNonQuery("DELETE FROM $testTableName")
|
||||
val result = conn.customList<JsonDocument>(Find.all(testTableName), mapFunc = Results::fromData)
|
||||
assertEquals(0, result.size, "There should have been no results")
|
||||
}
|
||||
|
||||
fun listAll(conn: Connection) {
|
||||
JsonDocument.load(conn, testTableName)
|
||||
val result = conn.customList<JsonDocument>(Find.all(testTableName), mapFunc = Results::fromData)
|
||||
assertEquals(5, result.size, "There should have been 5 results")
|
||||
}
|
||||
|
||||
fun singleNone(conn: Connection) =
|
||||
assertNull(
|
||||
conn.customSingle(Find.all(testTableName), mapFunc = Results::fromData),
|
||||
"There should not have been a document returned"
|
||||
)
|
||||
|
||||
fun singleOne(conn: Connection) {
|
||||
JsonDocument.load(conn, testTableName)
|
||||
assertNotNull(
|
||||
conn.customSingle<JsonDocument>(Find.all(testTableName), mapFunc = Results::fromData),
|
||||
"There should not have been a document returned"
|
||||
)
|
||||
}
|
||||
|
||||
fun nonQueryChanges(conn: Connection) {
|
||||
JsonDocument.load(conn, testTableName)
|
||||
assertEquals(
|
||||
5L, conn.customScalar(Count.all(testTableName), mapFunc = Results::toCount),
|
||||
"There should have been 5 documents in the table"
|
||||
)
|
||||
conn.customNonQuery("DELETE FROM $testTableName")
|
||||
assertEquals(
|
||||
0L, conn.customScalar(Count.all(testTableName), mapFunc = Results::toCount),
|
||||
"There should have been no documents in the table"
|
||||
)
|
||||
}
|
||||
|
||||
fun nonQueryNoChanges(conn: Connection) {
|
||||
JsonDocument.load(conn, testTableName)
|
||||
assertEquals(
|
||||
5L, conn.customScalar(Count.all(testTableName), mapFunc = Results::toCount),
|
||||
"There should have been 5 documents in the table"
|
||||
)
|
||||
conn.customNonQuery(
|
||||
"DELETE FROM $testTableName WHERE data->>'id' = :id",
|
||||
listOf(Parameter(":id", ParameterType.STRING, "eighty-two"))
|
||||
)
|
||||
assertEquals(
|
||||
5L, conn.customScalar(Count.all(testTableName), mapFunc = Results::toCount),
|
||||
"There should still have been 5 documents in the table"
|
||||
)
|
||||
}
|
||||
|
||||
fun scalar(conn: Connection) {
|
||||
JsonDocument.load(conn, testTableName)
|
||||
assertEquals(
|
||||
3L,
|
||||
conn.customScalar("SELECT 3 AS it FROM $testTableName LIMIT 1", mapFunc = Results::toCount),
|
||||
"The number 3 should have been returned"
|
||||
)
|
||||
}
|
||||
}
|
59
src/integration-test/kotlin/common/Document.kt
Normal file
59
src/integration-test/kotlin/common/Document.kt
Normal file
@ -0,0 +1,59 @@
|
||||
package solutions.bitbadger.documents.common
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.*
|
||||
import solutions.bitbadger.documents.sqlite.SQLiteDB
|
||||
import java.sql.Connection
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.fail
|
||||
|
||||
/**
|
||||
* Integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||
*/
|
||||
object Document {
|
||||
|
||||
fun insertDefault(conn: Connection) {
|
||||
assertEquals(0L, conn.countAll(testTableName), "There should be no documents in the table")
|
||||
val doc = JsonDocument("turkey", "", 0, SubDocument("gobble", "gobble"))
|
||||
conn.insert(testTableName, doc)
|
||||
val after = conn.findAll<JsonDocument>(testTableName)
|
||||
assertEquals(1, after.size, "There should be one document in the table")
|
||||
assertEquals(doc, after[0], "The document should be what was inserted")
|
||||
}
|
||||
|
||||
fun insertDupe(conn: Connection) {
|
||||
conn.insert(testTableName, JsonDocument("a", "", 0, null))
|
||||
try {
|
||||
conn.insert(testTableName, JsonDocument("a", "b", 22, null))
|
||||
fail("Inserting a document with a duplicate key should have thrown an exception")
|
||||
} catch (_: Exception) {
|
||||
// yay
|
||||
}
|
||||
}
|
||||
|
||||
fun insertNumAutoId(conn: Connection) {
|
||||
try {
|
||||
Configuration.autoIdStrategy = AutoId.NUMBER
|
||||
Configuration.idField = "key"
|
||||
assertEquals(0L, conn.countAll(SQLiteDB.tableName), "There should be no documents in the table")
|
||||
|
||||
conn.insert(SQLiteDB.tableName, NumIdDocument(0, "one"))
|
||||
conn.insert(SQLiteDB.tableName, NumIdDocument(0, "two"))
|
||||
conn.insert(SQLiteDB.tableName, NumIdDocument(77, "three"))
|
||||
conn.insert(SQLiteDB.tableName, NumIdDocument(0, "four"))
|
||||
|
||||
val after = conn.findAll<NumIdDocument>(SQLiteDB.tableName, listOf(Field.named("key")))
|
||||
assertEquals(4, after.size, "There should have been 4 documents returned")
|
||||
assertEquals(
|
||||
"1|2|77|78", after.joinToString("|") { it.key.toString() },
|
||||
"The IDs were not generated correctly"
|
||||
)
|
||||
} finally {
|
||||
Configuration.autoIdStrategy = AutoId.DISABLED
|
||||
Configuration.idField = "id"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: UUID, Random String
|
||||
|
||||
}
|
48
src/integration-test/kotlin/postgresql/CustomIT.kt
Normal file
48
src/integration-test/kotlin/postgresql/CustomIT.kt
Normal file
@ -0,0 +1,48 @@
|
||||
package solutions.bitbadger.documents.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.common.Custom
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Custom` object / `custom*` connection extension functions
|
||||
*/
|
||||
@DisplayName("PostgreSQL - Custom")
|
||||
class CustomIT {
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with empty list")
|
||||
fun listEmpty() =
|
||||
PgDB().use { Custom.listEmpty(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with a non-empty list")
|
||||
fun listAll() =
|
||||
PgDB().use { Custom.listAll(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when document not found")
|
||||
fun singleNone() =
|
||||
PgDB().use { Custom.singleNone(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when a document is found")
|
||||
fun singleOne() =
|
||||
PgDB().use { Custom.singleOne(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes changes")
|
||||
fun nonQueryChanges() =
|
||||
PgDB().use { Custom.nonQueryChanges(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes no changes when where clause matches nothing")
|
||||
fun nonQueryNoChanges() =
|
||||
PgDB().use { Custom.nonQueryNoChanges(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("scalar succeeds")
|
||||
fun scalar() =
|
||||
PgDB().use { Custom.scalar(it.conn) }
|
||||
}
|
27
src/integration-test/kotlin/postgresql/DocumentIT.kt
Normal file
27
src/integration-test/kotlin/postgresql/DocumentIT.kt
Normal file
@ -0,0 +1,27 @@
|
||||
package solutions.bitbadger.documents.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.common.Document
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||
*/
|
||||
@DisplayName("PostgreSQL - Document")
|
||||
class DocumentIT {
|
||||
|
||||
@Test
|
||||
@DisplayName("insert works with default values")
|
||||
fun insertDefault() =
|
||||
PgDB().use { Document.insertDefault(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert fails with duplicate key")
|
||||
fun insertDupe() =
|
||||
PgDB().use { Document.insertDupe(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with numeric auto IDs")
|
||||
fun insertNumAutoId() =
|
||||
PgDB().use { Document.insertNumAutoId(it.conn) }
|
||||
}
|
53
src/integration-test/kotlin/postgresql/PgDB.kt
Normal file
53
src/integration-test/kotlin/postgresql/PgDB.kt
Normal file
@ -0,0 +1,53 @@
|
||||
package solutions.bitbadger.documents.postgresql
|
||||
|
||||
import solutions.bitbadger.documents.AutoId
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.customNonQuery
|
||||
import solutions.bitbadger.documents.ensureTable
|
||||
|
||||
/**
|
||||
* A wrapper for a throwaway PostgreSQL database
|
||||
*/
|
||||
class PgDB : AutoCloseable {
|
||||
|
||||
private var dbName = ""
|
||||
|
||||
init {
|
||||
dbName = "throwaway_${AutoId.generateRandomString(8)}"
|
||||
Configuration.connectionString = connString("postgres")
|
||||
Configuration.dbConn().use {
|
||||
it.customNonQuery("CREATE DATABASE $dbName")
|
||||
}
|
||||
Configuration.connectionString = connString(dbName)
|
||||
}
|
||||
|
||||
val conn = Configuration.dbConn()
|
||||
|
||||
init {
|
||||
conn.ensureTable(tableName)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
conn.close()
|
||||
Configuration.connectionString = connString("postgres")
|
||||
Configuration.dbConn().use {
|
||||
it.customNonQuery("DROP DATABASE $dbName")
|
||||
}
|
||||
Configuration.connectionString = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
/** The table used for test documents */
|
||||
val tableName = "test_table"
|
||||
|
||||
/**
|
||||
* Create a connection string for the given database
|
||||
*
|
||||
* @param database The database to which the library should connect
|
||||
* @return The connection string for the database
|
||||
*/
|
||||
private fun connString(database: String) =
|
||||
"jdbc:postgresql://localhost/$database?user=postgres&password=postgres"
|
||||
}
|
||||
}
|
47
src/integration-test/kotlin/sqlite/CustomIT.kt
Normal file
47
src/integration-test/kotlin/sqlite/CustomIT.kt
Normal file
@ -0,0 +1,47 @@
|
||||
package solutions.bitbadger.documents.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.common.Custom
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Custom` object / `custom*` connection extension functions
|
||||
*/
|
||||
@DisplayName("SQLite - Custom")
|
||||
class CustomIT {
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with empty list")
|
||||
fun listEmpty() =
|
||||
SQLiteDB().use { Custom.listEmpty(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with a non-empty list")
|
||||
fun listAll() =
|
||||
SQLiteDB().use { Custom.listAll(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when document not found")
|
||||
fun singleNone() =
|
||||
SQLiteDB().use { Custom.singleNone(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when a document is found")
|
||||
fun singleOne() =
|
||||
SQLiteDB().use { Custom.singleOne(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes changes")
|
||||
fun nonQueryChanges() =
|
||||
SQLiteDB().use { Custom.nonQueryChanges(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes no changes when where clause matches nothing")
|
||||
fun nonQueryNoChanges() =
|
||||
SQLiteDB().use { Custom.nonQueryNoChanges(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("scalar succeeds")
|
||||
fun scalar() =
|
||||
SQLiteDB().use { Custom.scalar(it.conn) }
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package solutions.bitbadger.documents
|
||||
package solutions.bitbadger.documents.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.*
|
||||
import java.sql.Connection
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFalse
|
||||
@ -10,7 +11,7 @@ import kotlin.test.assertTrue
|
||||
* SQLite integration tests for the `Definition` object / `ensure*` connection extension functions
|
||||
*/
|
||||
@DisplayName("SQLite - Definition")
|
||||
class DefinitionSQLiteIT {
|
||||
class DefinitionIT {
|
||||
|
||||
/**
|
||||
* Determine if a database item exists
|
28
src/integration-test/kotlin/sqlite/DocumentIT.kt
Normal file
28
src/integration-test/kotlin/sqlite/DocumentIT.kt
Normal file
@ -0,0 +1,28 @@
|
||||
package solutions.bitbadger.documents.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.common.Document
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||
*/
|
||||
@DisplayName("SQLite - Document")
|
||||
class DocumentIT {
|
||||
|
||||
@Test
|
||||
@DisplayName("insert works with default values")
|
||||
fun insertDefault() =
|
||||
SQLiteDB().use { Document.insertDefault(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert fails with duplicate key")
|
||||
fun insertDupe() =
|
||||
SQLiteDB().use { Document.insertDupe(it.conn) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with numeric auto IDs")
|
||||
fun insertNumAutoId() =
|
||||
SQLiteDB().use { Document.insertNumAutoId(it.conn) }
|
||||
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
package solutions.bitbadger.documents
|
||||
package solutions.bitbadger.documents.sqlite
|
||||
|
||||
import solutions.bitbadger.documents.AutoId
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.ensureTable
|
||||
import java.io.File
|
||||
|
||||
/**
|
@ -23,16 +23,22 @@ object Document {
|
||||
val idField = Configuration.idField
|
||||
val dialect = Configuration.dialect("Create auto-ID insert query")
|
||||
val dataParam = if (AutoId.needsAutoId(strategy, document, idField)) {
|
||||
when (dialect) {
|
||||
Dialect.POSTGRESQL ->
|
||||
when (strategy) {
|
||||
AutoId.NUMBER -> "' || (SELECT coalesce(max(data->>'$idField')::numeric, 0) + 1 FROM $tableName) || '"
|
||||
AutoId.UUID -> "\"${AutoId.generateUUID()}\""
|
||||
AutoId.RANDOM_STRING -> "\"${AutoId.generateRandomString()}\""
|
||||
else -> "\"' || (:data)->>'$idField' || '\""
|
||||
}.let { ":data::jsonb || ('{\"$idField\":$it}')::jsonb" }
|
||||
|
||||
Dialect.SQLITE ->
|
||||
when (strategy) {
|
||||
AutoId.NUMBER -> "(SELECT coalesce(max(data->>'$idField'), 0) + 1 FROM $tableName)"
|
||||
AutoId.UUID -> "'${AutoId.generateUUID()}'"
|
||||
AutoId.RANDOM_STRING -> "'${AutoId.generateRandomString()}'"
|
||||
else -> "(:data)->>'$idField'"
|
||||
}.let {
|
||||
when (dialect) {
|
||||
Dialect.POSTGRESQL -> ":data::jsonb || ('{\"$idField\":$it}')::jsonb"
|
||||
Dialect.SQLITE -> "json_set(:data, '$.$idField', $it)"
|
||||
}
|
||||
}.let { "json_set(:data, '$.$idField', $it)" }
|
||||
}
|
||||
} else {
|
||||
":data"
|
||||
|
@ -47,7 +47,7 @@ object Parameters {
|
||||
* @return The query, with name parameters changed to `?`s
|
||||
*/
|
||||
fun replaceNamesInQuery(query: String, parameters: Collection<Parameter<*>>) =
|
||||
parameters.sortedByDescending { it.name.length }.fold(query) { acc, param -> acc.replace(param.name, "?") }
|
||||
parameters.sortedByDescending { it.name.length }.fold(query) { acc, param -> acc.replace(param.name, "?") }.also(::println)
|
||||
|
||||
/**
|
||||
* Apply the given parameters to the given query, returning a prepared statement
|
||||
@ -103,7 +103,7 @@ object Parameters {
|
||||
}
|
||||
}
|
||||
|
||||
ParameterType.JSON -> stmt.setString(idx, param.value as String)
|
||||
ParameterType.JSON -> stmt.setObject(idx, param.value as String, Types.OTHER)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user