Nearly all compile errors resolved

This commit is contained in:
Daniel J. Summers 2025-03-12 23:08:52 -04:00
parent 14f0178b63
commit 5bcbc5cffc
37 changed files with 487 additions and 372 deletions

View File

@ -2,7 +2,6 @@ package solutions.bitbadger.documents.common
import java.sql.Connection
import java.sql.DriverManager
import kotlin.jvm.Throws
/**
* Configuration for the document library

View File

@ -71,18 +71,6 @@
</configuration>
</execution>
</executions>
<configuration>
<compilerPlugins>
<plugin>kotlinx-serialization</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-serialization</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>

View File

@ -1,11 +1,8 @@
@file:JvmName("ConnExt")
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.Custom
import solutions.bitbadger.documents.common.DocumentIndex
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.common.FieldMatch
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.common.*
import java.sql.Connection
import java.sql.ResultSet
@ -16,24 +13,32 @@ import java.sql.ResultSet
*
* @param query The query to retrieve the results
* @param parameters Parameters to use for the query
* @param clazz The class of the document to be returned
* @param mapFunc The mapping function between the document and the domain item
* @return A list of results for the given query
*/
inline fun <reified TDoc> Connection.customList(
query: String, parameters: Collection<Parameter<*>> = listOf(), noinline mapFunc: (ResultSet, Class<TDoc>) -> TDoc
) = Custom.list(query, parameters, this, mapFunc)
fun <TDoc> Connection.customList(
query: String,
parameters: Collection<Parameter<*>> = listOf(),
clazz: Class<TDoc>,
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
) = Custom.list(query, parameters, clazz, this, mapFunc)
/**
* Execute a query that returns one or no results
*
* @param query The query to retrieve the results
* @param parameters Parameters to use for the query
* @param clazz The class of the document to be returned
* @param mapFunc The mapping function between the document and the domain item
* @return The document if one matches the query, `null` otherwise
*/
inline fun <reified TDoc> Connection.customSingle(
query: String, parameters: Collection<Parameter<*>> = listOf(), noinline mapFunc: (ResultSet, Class<TDoc>) -> TDoc
) = Custom.single(query, parameters, this, mapFunc)
fun <TDoc> Connection.customSingle(
query: String,
parameters: Collection<Parameter<*>> = listOf(),
clazz: Class<TDoc>,
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
) = Custom.single(query, parameters, clazz, this, mapFunc)
/**
* Execute a query that returns no results
@ -49,14 +54,16 @@ fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>
*
* @param query The query to retrieve the result
* @param parameters Parameters to use for the query
* @param clazz The class of the document to be returned
* @param mapFunc The mapping function between the document and the domain item
* @return The scalar value from the query
*/
inline fun <reified T : Any> Connection.customScalar(
fun <T : Any> Connection.customScalar(
query: String,
parameters: Collection<Parameter<*>> = listOf(),
noinline mapFunc: (ResultSet, Class<T>) -> T
) = Custom.scalar(query, parameters, this, mapFunc)
clazz: Class<T>,
mapFunc: (ResultSet, Class<T>) -> T
) = Custom.scalar(query, parameters, clazz, this, mapFunc)
// ~~~ DEFINITION QUERIES ~~~
@ -66,7 +73,7 @@ inline fun <reified T : Any> Connection.customScalar(
* @param tableName The table whose existence should be ensured (may include schema)
*/
fun Connection.ensureTable(tableName: String) =
solutions.bitbadger.documents.java.Definition.ensureTable(tableName, this)
Definition.ensureTable(tableName, this)
/**
* Create an index on field(s) within documents in the specified table if necessary
@ -76,7 +83,7 @@ fun Connection.ensureTable(tableName: String) =
* @param fields One or more fields to be indexed<
*/
fun Connection.ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>) =
solutions.bitbadger.documents.java.Definition.ensureFieldIndex(tableName, indexName, fields, this)
Definition.ensureFieldIndex(tableName, indexName, fields, this)
/**
* Create a document index on a table (PostgreSQL only)
@ -85,8 +92,9 @@ fun Connection.ensureFieldIndex(tableName: String, indexName: String, fields: Co
* @param indexType The type of index to ensure
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
fun Connection.ensureDocumentIndex(tableName: String, indexType: DocumentIndex) =
solutions.bitbadger.documents.java.Definition.ensureDocumentIndex(tableName, indexType, this)
Definition.ensureDocumentIndex(tableName, indexType, this)
// ~~~ DOCUMENT MANIPULATION QUERIES ~~~
@ -96,7 +104,7 @@ fun Connection.ensureDocumentIndex(tableName: String, indexType: DocumentIndex)
* @param tableName The table into which the document should be inserted (may include schema)
* @param document The document to be inserted
*/
inline fun <reified TDoc> Connection.insert(tableName: String, document: TDoc) =
fun <TDoc> Connection.insert(tableName: String, document: TDoc) =
Document.insert(tableName, document, this)
/**
@ -105,7 +113,7 @@ inline fun <reified TDoc> Connection.insert(tableName: String, document: TDoc) =
* @param tableName The table in which the document should be saved (may include schema)
* @param document The document to be saved
*/
inline fun <reified TDoc> Connection.save(tableName: String, document: TDoc) =
fun <TDoc> Connection.save(tableName: String, document: TDoc) =
Document.save(tableName, document, this)
/**
@ -115,7 +123,7 @@ inline fun <reified TDoc> Connection.save(tableName: String, document: TDoc) =
* @param docId The ID of the document to be replaced
* @param document The document to be replaced
*/
inline fun <TKey, reified TDoc> Connection.update(tableName: String, docId: TKey, document: TDoc) =
fun <TKey, TDoc> Connection.update(tableName: String, docId: TKey, document: TDoc) =
Document.update(tableName, docId, document, this)
// ~~~ DOCUMENT COUNT QUERIES ~~~
@ -148,7 +156,8 @@ fun Connection.countByFields(tableName: String, fields: Collection<Field<*>>, ho
* @return A count of the matching documents in the table
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> Connection.countByContains(tableName: String, criteria: TContains) =
@Throws(DocumentException::class)
fun <TContains> Connection.countByContains(tableName: String, criteria: TContains) =
Count.byContains(tableName, criteria, this)
/**
@ -159,6 +168,7 @@ inline fun <reified TContains> Connection.countByContains(tableName: String, cri
* @return A count of the matching documents in the table
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
fun Connection.countByJsonPath(tableName: String, path: String) =
Count.byJsonPath(tableName, path, this)
@ -193,7 +203,8 @@ fun Connection.existsByFields(tableName: String, fields: Collection<Field<*>>, h
* @return True if any matching documents exist, false if not
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> Connection.existsByContains(tableName: String, criteria: TContains) =
@Throws(DocumentException::class)
fun <TContains> Connection.existsByContains(tableName: String, criteria: TContains) =
Exists.byContains(tableName, criteria, this)
/**
@ -204,6 +215,7 @@ inline fun <reified TContains> Connection.existsByContains(tableName: String, cr
* @return True if any matching documents exist, false if not
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
fun Connection.existsByJsonPath(tableName: String, path: String) =
Exists.byJsonPath(tableName, path, this)
@ -213,119 +225,145 @@ fun Connection.existsByJsonPath(tableName: String, path: String) =
* Retrieve all documents in the given table, ordering results by the optional given fields
*
* @param tableName The table from which documents should be retrieved
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents from the given table
*/
inline fun <reified TDoc> Connection.findAll(tableName: String, orderBy: Collection<Field<*>>? = null) =
solutions.bitbadger.documents.java.Find.all<TDoc>(tableName, orderBy, this)
@JvmOverloads
fun <TDoc> Connection.findAll(tableName: String, clazz: Class<TDoc>, orderBy: Collection<Field<*>>? = null) =
Find.all(tableName, clazz, orderBy, this)
/**
* Retrieve a document by its ID
*
* @param tableName The table from which the document should be retrieved
* @param docId The ID of the document to retrieve
* @param clazz The class of the document to be returned
* @return The document if it is found, `null` otherwise
*/
inline fun <TKey, reified TDoc> Connection.findById(tableName: String, docId: TKey) =
solutions.bitbadger.documents.java.Find.byId<TKey, TDoc>(tableName, docId, this)
fun <TKey, TDoc> Connection.findById(tableName: String, docId: TKey, clazz: Class<TDoc>) =
Find.byId(tableName, docId, clazz, this)
/**
* Retrieve documents using a field comparison, ordering results by the optional given fields
*
* @param tableName The table from which the document should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents matching the field comparison
*/
inline fun <reified TDoc> Connection.findByFields(
@JvmOverloads
fun <TDoc> Connection.findByFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
orderBy: Collection<Field<*>>? = null
) =
solutions.bitbadger.documents.java.Find.byFields<TDoc>(tableName, fields, howMatched, orderBy, this)
Find.byFields(tableName, fields, clazz, howMatched, orderBy, this)
/**
* Retrieve documents using a JSON containment query, ordering results by the optional given fields (PostgreSQL only)
*
* @param tableName The name of the table in which document existence should be checked
* @param criteria The object for which JSON containment should be checked
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents matching the JSON containment query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> Connection.findByContains(
@Throws(DocumentException::class)
@JvmOverloads
fun <TDoc, TContains> Connection.findByContains(
tableName: String,
criteria: TContains,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null
) =
solutions.bitbadger.documents.java.Find.byContains<TDoc, TContains>(tableName, criteria, orderBy, this)
Find.byContains(tableName, criteria, clazz, orderBy, this)
/**
* Retrieve documents using a JSON Path match query, ordering results by the optional given fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents matching the JSON Path match query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> Connection.findByJsonPath(
@Throws(DocumentException::class)
@JvmOverloads
fun <TDoc> Connection.findByJsonPath(
tableName: String,
path: String,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null
) =
solutions.bitbadger.documents.java.Find.byJsonPath<TDoc>(tableName, path, orderBy, this)
Find.byJsonPath(tableName, path, clazz, orderBy, this)
/**
* Retrieve the first document using a field comparison and optional ordering fields
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched (optional, defaults to `FieldMatch.ALL`)
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return The first document matching the field comparison, or `null` if no matches are found
*/
inline fun <reified TDoc> Connection.findFirstByFields(
@Throws(DocumentException::class)
@JvmOverloads
fun <TDoc> Connection.findFirstByFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
orderBy: Collection<Field<*>>? = null
) =
solutions.bitbadger.documents.java.Find.firstByFields<TDoc>(tableName, fields, howMatched, orderBy, this)
Find.firstByFields(tableName, fields, clazz, howMatched, orderBy, this)
/**
* Retrieve the first document using a JSON containment query and optional ordering fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param criteria The object for which JSON containment should be checked
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return The first document matching the JSON containment query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> Connection.findFirstByContains(
@Throws(DocumentException::class)
@JvmOverloads
fun <TDoc, TContains> Connection.findFirstByContains(
tableName: String,
criteria: TContains,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null
) =
solutions.bitbadger.documents.java.Find.firstByContains<TDoc, TContains>(tableName, criteria, orderBy, this)
Find.firstByContains(tableName, criteria, clazz, orderBy, this)
/**
* Retrieve the first document using a JSON Path match query and optional ordering fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return The first document matching the JSON Path match query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> Connection.findFirstByJsonPath(
@Throws(DocumentException::class)
@JvmOverloads
fun <TDoc> Connection.findFirstByJsonPath(
tableName: String,
path: String,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null
) =
solutions.bitbadger.documents.java.Find.firstByJsonPath<TDoc>(tableName, path, orderBy, this)
Find.firstByJsonPath(tableName, path, clazz, orderBy, this)
// ~~~ DOCUMENT PATCH (PARTIAL UPDATE) QUERIES ~~~
@ -336,7 +374,7 @@ inline fun <reified TDoc> Connection.findFirstByJsonPath(
* @param docId The ID of the document to be patched
* @param patch The object whose properties should be replaced in the document
*/
inline fun <TKey, reified TPatch> Connection.patchById(tableName: String, docId: TKey, patch: TPatch) =
fun <TKey, TPatch> Connection.patchById(tableName: String, docId: TKey, patch: TPatch) =
Patch.byId(tableName, docId, patch, this)
/**
@ -347,7 +385,7 @@ inline fun <TKey, reified TPatch> Connection.patchById(tableName: String, docId:
* @param patch The object whose properties should be replaced in the document
* @param howMatched How the fields should be matched
*/
inline fun <reified TPatch> Connection.patchByFields(
fun <TPatch> Connection.patchByFields(
tableName: String,
fields: Collection<Field<*>>,
patch: TPatch,
@ -363,7 +401,8 @@ inline fun <reified TPatch> Connection.patchByFields(
* @param patch The object whose properties should be replaced in the document
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains, reified TPatch> Connection.patchByContains(
@Throws(DocumentException::class)
fun <TContains, TPatch> Connection.patchByContains(
tableName: String,
criteria: TContains,
patch: TPatch
@ -378,7 +417,8 @@ inline fun <reified TContains, reified TPatch> Connection.patchByContains(
* @param patch The object whose properties should be replaced in the document
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TPatch> Connection.patchByJsonPath(tableName: String, path: String, patch: TPatch) =
@Throws(DocumentException::class)
fun <TPatch> Connection.patchByJsonPath(tableName: String, path: String, patch: TPatch) =
Patch.byJsonPath(tableName, path, patch, this)
// ~~~ DOCUMENT FIELD REMOVAL QUERIES ~~~
@ -417,7 +457,8 @@ fun Connection.removeFieldsByFields(
* @param toRemove The names of the fields to be removed
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> Connection.removeFieldsByContains(
@Throws(DocumentException::class)
fun <TContains> Connection.removeFieldsByContains(
tableName: String,
criteria: TContains,
toRemove: Collection<String>
@ -432,6 +473,7 @@ inline fun <reified TContains> Connection.removeFieldsByContains(
* @param toRemove The names of the fields to be removed
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
fun Connection.removeFieldsByJsonPath(tableName: String, path: String, toRemove: Collection<String>) =
RemoveFields.byJsonPath(tableName, path, toRemove, this)
@ -463,7 +505,8 @@ fun Connection.deleteByFields(tableName: String, fields: Collection<Field<*>>, h
* @param criteria The object for which JSON containment should be checked
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> Connection.deleteByContains(tableName: String, criteria: TContains) =
@Throws(DocumentException::class)
fun <TContains> Connection.deleteByContains(tableName: String, criteria: TContains) =
Delete.byContains(tableName, criteria, this)
/**

View File

@ -1,10 +1,7 @@
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.Results
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.common.FieldMatch
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.common.ParameterType
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.common.query.Count
import java.sql.Connection
/**
@ -21,7 +18,7 @@ object Count {
*/
@JvmStatic
fun all(tableName: String, conn: Connection) =
conn.customScalar(all(tableName), mapFunc = Results::toCount)
conn.customScalar(Count.all(tableName), listOf(), Long::class.java, Results::toCount)
/**
* Count all documents in the table
@ -52,8 +49,9 @@ object Count {
): Long {
val named = Parameters.nameFields(fields)
return conn.customScalar(
byFields(tableName, named, howMatched),
Count.byFields(tableName, named, howMatched),
Parameters.addFields(named),
Long::class.java,
Results::toCount
)
}
@ -81,8 +79,13 @@ object Count {
* @throws DocumentException If called on a SQLite connection
*/
@JvmStatic
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
conn.customScalar(Count.byContains(tableName), listOf(Parameters.json(":criteria", criteria)), Results::toCount)
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
conn.customScalar(
Count.byContains(tableName),
listOf(Parameters.json(":criteria", criteria)),
Long::class.java,
Results::toCount
)
/**
* Count documents using a JSON containment query (PostgreSQL only)
@ -93,7 +96,7 @@ object Count {
* @throws DocumentException If called on a SQLite connection
*/
@JvmStatic
inline fun <reified TContains> byContains(tableName: String, criteria: TContains) =
fun <TContains> byContains(tableName: String, criteria: TContains) =
Configuration.dbConn().use { byContains(tableName, criteria, it) }
/**
@ -110,6 +113,7 @@ object Count {
conn.customScalar(
Count.byJsonPath(tableName),
listOf(Parameter(":path", ParameterType.STRING, path)),
Long::class.java,
Results::toCount
)

View File

@ -1,6 +1,9 @@
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.common.Configuration
import solutions.bitbadger.documents.common.DocumentException
import solutions.bitbadger.documents.common.DocumentIndex
import solutions.bitbadger.documents.common.query.Definition
import java.sql.Connection
/**
@ -14,6 +17,7 @@ object Definition {
* @param tableName The table whose existence should be ensured (may include schema)
* @param conn The connection on which the query should be executed
*/
@JvmStatic
fun ensureTable(tableName: String, conn: Connection) =
Configuration.dialect("ensure $tableName exists").let {
conn.customNonQuery(Definition.ensureTable(tableName, it))
@ -25,6 +29,7 @@ object Definition {
*
* @param tableName The table whose existence should be ensured (may include schema)
*/
@JvmStatic
fun ensureTable(tableName: String) =
Configuration.dbConn().use { ensureTable(tableName, it) }
@ -33,9 +38,10 @@ object Definition {
*
* @param tableName The table to be indexed (may include schema)
* @param indexName The name of the index to create
* @param fields One or more fields to be indexed<
* @param fields One or more fields to be indexed
* @param conn The connection on which the query should be executed
*/
@JvmStatic
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>, conn: Connection) =
conn.customNonQuery(Definition.ensureIndexOn(tableName, indexName, fields))
@ -44,8 +50,9 @@ object Definition {
*
* @param tableName The table to be indexed (may include schema)
* @param indexName The name of the index to create
* @param fields One or more fields to be indexed<
* @param fields One or more fields to be indexed
*/
@JvmStatic
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>) =
Configuration.dbConn().use { ensureFieldIndex(tableName, indexName, fields, it) }
@ -57,6 +64,8 @@ object Definition {
* @param conn The connection on which the query should be executed
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun ensureDocumentIndex(tableName: String, indexType: DocumentIndex, conn: Connection) =
conn.customNonQuery(Definition.ensureDocumentIndexOn(tableName, indexType))
@ -67,6 +76,8 @@ object Definition {
* @param indexType The type of index to ensure
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun ensureDocumentIndex(tableName: String, indexType: DocumentIndex) =
Configuration.dbConn().use { ensureDocumentIndex(tableName, indexType, it) }
}

View File

@ -1,9 +1,7 @@
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.common.FieldMatch
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.common.ParameterType
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.common.query.Delete
import java.sql.Connection
/**
@ -18,9 +16,10 @@ object Delete {
* @param docId The ID of the document to be deleted
* @param conn The connection on which the deletion should be executed
*/
@JvmStatic
fun <TKey> byId(tableName: String, docId: TKey, conn: Connection) =
conn.customNonQuery(
byId(tableName, docId),
Delete.byId(tableName, docId),
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id")))
)
@ -30,6 +29,7 @@ object Delete {
* @param tableName The name of the table from which documents should be deleted
* @param docId The ID of the document to be deleted
*/
@JvmStatic
fun <TKey> byId(tableName: String, docId: TKey) =
Configuration.dbConn().use { byId(tableName, docId, it) }
@ -41,9 +41,11 @@ object Delete {
* @param howMatched How the fields should be matched
* @param conn The connection on which the deletion should be executed
*/
@JvmStatic
@JvmOverloads
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null, conn: Connection) {
val named = Parameters.nameFields(fields)
conn.customNonQuery(byFields(tableName, named, howMatched), Parameters.addFields(named))
conn.customNonQuery(Delete.byFields(tableName, named, howMatched), Parameters.addFields(named))
}
/**
@ -53,6 +55,8 @@ object Delete {
* @param fields The fields which should be compared
* @param howMatched How the fields should be matched
*/
@JvmStatic
@JvmOverloads
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
Configuration.dbConn().use { byFields(tableName, fields, howMatched, it) }
@ -64,7 +68,9 @@ object Delete {
* @param conn The connection on which the deletion should be executed
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
@Throws(DocumentException::class)
@JvmStatic
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
conn.customNonQuery(Delete.byContains(tableName), listOf(Parameters.json(":criteria", criteria)))
/**
@ -74,7 +80,9 @@ object Delete {
* @param criteria The object for which JSON containment should be checked
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> byContains(tableName: String, criteria: TContains) =
@Throws(DocumentException::class)
@JvmStatic
fun <TContains> byContains(tableName: String, criteria: TContains) =
Configuration.dbConn().use { byContains(tableName, criteria, it) }
/**
@ -85,6 +93,8 @@ object Delete {
* @param conn The connection on which the deletion should be executed
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun byJsonPath(tableName: String, path: String, conn: Connection) =
conn.customNonQuery(Delete.byJsonPath(tableName), listOf(Parameter(":path", ParameterType.STRING, path)))
@ -95,6 +105,8 @@ object Delete {
* @param path The JSON path comparison to match
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun byJsonPath(tableName: String, path: String) =
Configuration.dbConn().use { byJsonPath(tableName, path, it) }
}

View File

@ -1,10 +1,7 @@
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.Results
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.common.FieldMatch
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.common.ParameterType
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.common.query.Exists
import java.sql.Connection
/**
@ -20,10 +17,12 @@ object Exists {
* @param conn The connection on which the existence check should be executed
* @return True if the document exists, false if not
*/
@JvmStatic
fun <TKey> byId(tableName: String, docId: TKey, conn: Connection) =
conn.customScalar(
byId(tableName, docId),
Exists.byId(tableName, docId),
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
Boolean::class.java,
Results::toExists
)
@ -34,6 +33,7 @@ object Exists {
* @param docId The ID of the document to be checked
* @return True if the document exists, false if not
*/
@JvmStatic
fun <TKey> byId(tableName: String, docId: TKey) =
Configuration.dbConn().use { byId(tableName, docId, it) }
@ -46,6 +46,8 @@ object Exists {
* @param conn The connection on which the existence check should be executed
* @return True if any matching documents exist, false if not
*/
@JvmStatic
@JvmOverloads
fun byFields(
tableName: String,
fields: Collection<Field<*>>,
@ -54,8 +56,9 @@ object Exists {
): Boolean {
val named = Parameters.nameFields(fields)
return conn.customScalar(
byFields(tableName, named, howMatched),
Exists.byFields(tableName, named, howMatched),
Parameters.addFields(named),
Boolean::class.java,
Results::toExists
)
}
@ -68,6 +71,8 @@ object Exists {
* @param howMatched How the fields should be matched
* @return True if any matching documents exist, false if not
*/
@JvmStatic
@JvmOverloads
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
Configuration.dbConn().use { byFields(tableName, fields, howMatched, it) }
@ -80,10 +85,13 @@ object Exists {
* @return True if any matching documents exist, false if not
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
@Throws(DocumentException::class)
@JvmStatic
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
conn.customScalar(
Exists.byContains(tableName),
listOf(Parameters.json(":criteria", criteria)),
Boolean::class.java,
Results::toExists
)
@ -95,7 +103,9 @@ object Exists {
* @return True if any matching documents exist, false if not
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> byContains(tableName: String, criteria: TContains) =
@Throws(DocumentException::class)
@JvmStatic
fun <TContains> byContains(tableName: String, criteria: TContains) =
Configuration.dbConn().use { byContains(tableName, criteria, it) }
/**
@ -107,10 +117,13 @@ object Exists {
* @return True if any matching documents exist, false if not
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun byJsonPath(tableName: String, path: String, conn: Connection) =
conn.customScalar(
Exists.byJsonPath(tableName),
listOf(Parameter(":path", ParameterType.STRING, path)),
Boolean::class.java,
Results::toExists
)
@ -122,6 +135,8 @@ object Exists {
* @return True if any matching documents exist, false if not
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun byJsonPath(tableName: String, path: String) =
Configuration.dbConn().use { byJsonPath(tableName, path, it) }
}

View File

@ -1,12 +1,9 @@
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.Results
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.common.FieldMatch
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.common.ParameterType
import java.sql.Connection
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.common.query.Find
import solutions.bitbadger.documents.common.query.orderBy
import java.sql.Connection
/**
* Functions to find and retrieve documents
@ -17,45 +14,55 @@ object Find {
* Retrieve all documents in the given table, ordering results by the optional given fields
*
* @param tableName The table from which documents should be retrieved
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @param conn The connection over which documents should be retrieved
* @return A list of documents from the given table
*/
inline fun <reified TDoc> all(tableName: String, orderBy: Collection<Field<*>>? = null, conn: Connection) =
conn.customList<TDoc>(all(tableName) + (orderBy?.let(::orderBy) ?: ""), mapFunc = Results::fromData)
@JvmStatic
fun <TDoc> all(tableName: String, clazz: Class<TDoc>, orderBy: Collection<Field<*>>? = null, conn: Connection) =
conn.customList(Find.all(tableName) + (orderBy?.let(::orderBy) ?: ""), listOf(), clazz, Results::fromData)
/**
* Retrieve all documents in the given table
*
* @param tableName The table from which documents should be retrieved
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents from the given table
*/
inline fun <reified TDoc> all(tableName: String, orderBy: Collection<Field<*>>? = null) =
Configuration.dbConn().use { all<TDoc>(tableName, orderBy, it) }
@JvmStatic
@JvmOverloads
fun <TDoc> all(tableName: String, clazz: Class<TDoc>, orderBy: Collection<Field<*>>? = null) =
Configuration.dbConn().use { all(tableName, clazz, orderBy, it) }
/**
* Retrieve all documents in the given table
*
* @param tableName The table from which documents should be retrieved
* @param clazz The class of the document to be returned
* @param conn The connection over which documents should be retrieved
* @return A list of documents from the given table
*/
inline fun <reified TDoc> all(tableName: String, conn: Connection) =
all<TDoc>(tableName, null, conn)
@JvmStatic
fun <TDoc> all(tableName: String, clazz: Class<TDoc>, conn: Connection) =
all(tableName, clazz, null, conn)
/**
* Retrieve a document by its ID
*
* @param tableName The table from which the document should be retrieved
* @param docId The ID of the document to retrieve
* @param clazz The class of the document to be returned
* @param conn The connection over which documents should be retrieved
* @return The document if it is found, `null` otherwise
*/
inline fun <TKey, reified TDoc> byId(tableName: String, docId: TKey, conn: Connection) =
conn.customSingle<TDoc>(
byId(tableName, docId),
@JvmStatic
fun <TKey, TDoc> byId(tableName: String, docId: TKey, clazz: Class<TDoc>, conn: Connection) =
conn.customSingle(
Find.byId(tableName, docId),
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
clazz,
Results::fromData
)
@ -64,32 +71,38 @@ object Find {
*
* @param tableName The table from which the document should be retrieved
* @param docId The ID of the document to retrieve
* @param clazz The class of the document to be returned
* @return The document if it is found, `null` otherwise
*/
inline fun <TKey, reified TDoc> byId(tableName: String, docId: TKey) =
Configuration.dbConn().use { byId<TKey, TDoc>(tableName, docId, it) }
@JvmStatic
fun <TKey, TDoc> byId(tableName: String, docId: TKey, clazz: Class<TDoc>) =
Configuration.dbConn().use { byId(tableName, docId, clazz, it) }
/**
* Retrieve documents using a field comparison, ordering results by the given fields
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @param conn The connection over which documents should be retrieved
* @return A list of documents matching the field comparison
*/
inline fun <reified TDoc> byFields(
@JvmStatic
fun <TDoc> byFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
orderBy: Collection<Field<*>>? = null,
conn: Connection
): List<TDoc> {
val named = Parameters.nameFields(fields)
return conn.customList<TDoc>(
byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
return conn.customList(
Find.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
Parameters.addFields(named),
clazz,
Results::fromData
)
}
@ -99,69 +112,66 @@ object Find {
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents matching the field comparison
*/
inline fun <reified TDoc> byFields(
@JvmStatic
@JvmOverloads
fun <TDoc> byFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
orderBy: Collection<Field<*>>? = null
) =
Configuration.dbConn().use { byFields<TDoc>(tableName, fields, howMatched, orderBy, it) }
Configuration.dbConn().use { byFields(tableName, fields, clazz, howMatched, orderBy, it) }
/**
* Retrieve documents using a field comparison
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched
* @param conn The connection over which documents should be retrieved
* @return A list of documents matching the field comparison
*/
inline fun <reified TDoc> byFields(
@JvmStatic
fun <TDoc> byFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
conn: Connection
) =
byFields<TDoc>(tableName, fields, howMatched, null, conn)
/**
* Retrieve documents using a field comparison
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param howMatched How the fields should be matched
* @return A list of documents matching the field comparison
*/
inline fun <reified TDoc> byFields(
tableName: String,
fields: Collection<Field<*>>,
howMatched: FieldMatch? = null
) =
Configuration.dbConn().use { byFields<TDoc>(tableName, fields, howMatched, null, it) }
byFields(tableName, fields, clazz, howMatched, null, conn)
/**
* Retrieve documents using a JSON containment query, ordering results by the given fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param criteria The object for which JSON containment should be checked
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @param conn The connection over which documents should be retrieved
* @return A list of documents matching the JSON containment query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> byContains(
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc, TContains> byContains(
tableName: String,
criteria: TContains,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null,
conn: Connection
) =
conn.customList<TDoc>(
conn.customList(
Find.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
listOf(Parameters.json(":criteria", criteria)),
clazz,
Results::fromData
)
@ -170,59 +180,61 @@ object Find {
*
* @param tableName The table from which documents should be retrieved
* @param criteria The object for which JSON containment should be checked
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents matching the JSON containment query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> byContains(
@Throws(DocumentException::class)
@JvmStatic
@JvmOverloads
fun <TDoc, TContains> byContains(
tableName: String,
criteria: TContains,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null
) =
Configuration.dbConn().use { byContains<TDoc, TContains>(tableName, criteria, orderBy, it) }
Configuration.dbConn().use { byContains(tableName, criteria, clazz, orderBy, it) }
/**
* Retrieve documents using a JSON containment query (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param criteria The object for which JSON containment should be checked
* @param clazz The class of the document to be returned
* @param conn The connection over which documents should be retrieved
* @return A list of documents matching the JSON containment query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
byContains<TDoc, TContains>(tableName, criteria, null, conn)
/**
* Retrieve documents using a JSON containment query (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param criteria The object for which JSON containment should be checked
* @return A list of documents matching the JSON containment query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> byContains(tableName: String, criteria: TContains) =
Configuration.dbConn().use { byContains<TDoc, TContains>(tableName, criteria, it) }
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc, TContains> byContains(tableName: String, criteria: TContains, clazz: Class<TDoc>, conn: Connection) =
byContains(tableName, criteria, clazz, null, conn)
/**
* Retrieve documents using a JSON Path match query, ordering results by the given fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @param conn The connection over which documents should be retrieved
* @return A list of documents matching the JSON Path match query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> byJsonPath(
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc> byJsonPath(
tableName: String,
path: String,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null,
conn: Connection
) =
conn.customList<TDoc>(
byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
conn.customList(
Find.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
listOf(Parameter(":path", ParameterType.STRING, path)),
clazz,
Results::fromData
)
@ -231,46 +243,57 @@ object Find {
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return A list of documents matching the JSON Path match query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> byJsonPath(tableName: String, path: String, orderBy: Collection<Field<*>>? = null) =
Configuration.dbConn().use { byJsonPath<TDoc>(tableName, path, orderBy, it) }
@Throws(DocumentException::class)
@JvmStatic
@JvmOverloads
fun <TDoc> byJsonPath(tableName: String, path: String, clazz: Class<TDoc>, orderBy: Collection<Field<*>>? = null) =
Configuration.dbConn().use { byJsonPath(tableName, path, clazz, orderBy, it) }
/**
* Retrieve documents using a JSON Path match query (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param conn The connection over which documents should be retrieved
* @return A list of documents matching the JSON Path match query
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> byJsonPath(tableName: String, path: String, conn: Connection) =
byJsonPath<TDoc>(tableName, path, null, conn)
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc> byJsonPath(tableName: String, path: String, clazz: Class<TDoc>, conn: Connection) =
byJsonPath(tableName, path, clazz, null, conn)
/**
* Retrieve the first document using a field comparison and optional ordering fields
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched (optional, defaults to `FieldMatch.ALL`)
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @param conn The connection over which documents should be retrieved
* @return The first document matching the field comparison, or `null` if no matches are found
*/
inline fun <reified TDoc> firstByFields(
@JvmStatic
fun <TDoc> firstByFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
orderBy: Collection<Field<*>>? = null,
conn: Connection
): TDoc? {
val named = Parameters.nameFields(fields)
return conn.customSingle<TDoc>(
byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
return conn.customSingle(
Find.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
Parameters.addFields(named),
clazz,
Results::fromData
)
}
@ -280,34 +303,41 @@ object Find {
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched (optional, defaults to `FieldMatch.ALL`)
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return The first document matching the field comparison, or `null` if no matches are found
*/
inline fun <reified TDoc> firstByFields(
@JvmStatic
@JvmOverloads
fun <TDoc> firstByFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
orderBy: Collection<Field<*>>? = null
) =
Configuration.dbConn().use { firstByFields<TDoc>(tableName, fields, howMatched, orderBy, it) }
Configuration.dbConn().use { firstByFields(tableName, fields, clazz, howMatched, orderBy, it) }
/**
* Retrieve the first document using a field comparison
*
* @param tableName The table from which documents should be retrieved
* @param fields The fields which should be compared
* @param clazz The class of the document to be returned
* @param howMatched How the fields should be matched (optional, defaults to `FieldMatch.ALL`)
* @param conn The connection over which documents should be retrieved
* @return The first document matching the field comparison, or `null` if no matches are found
*/
inline fun <reified TDoc> firstByFields(
@JvmStatic
fun <TDoc> firstByFields(
tableName: String,
fields: Collection<Field<*>>,
clazz: Class<TDoc>,
howMatched: FieldMatch? = null,
conn: Connection
) =
firstByFields<TDoc>(tableName, fields, howMatched, null, conn)
firstByFields(tableName, fields, clazz, howMatched, null, conn)
/**
* Retrieve the first document using a JSON containment query and optional ordering fields (PostgreSQL only)
@ -319,15 +349,19 @@ object Find {
* @return The first document matching the JSON containment query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> firstByContains(
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc, TContains> firstByContains(
tableName: String,
criteria: TContains,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null,
conn: Connection
) =
conn.customSingle<TDoc>(
conn.customSingle(
Find.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
listOf(Parameters.json(":criteria", criteria)),
clazz,
Results::fromData
)
@ -336,44 +370,66 @@ object Find {
*
* @param tableName The table from which documents should be retrieved
* @param criteria The object for which JSON containment should be checked
* @param clazz The class of the document to be returned
* @param conn The connection over which documents should be retrieved
* @return The first document matching the JSON containment query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> firstByContains(tableName: String, criteria: TContains, conn: Connection) =
firstByContains<TDoc, TContains>(tableName, criteria, null, conn)
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc, TContains> firstByContains(
tableName: String,
criteria: TContains,
clazz: Class<TDoc>,
conn: Connection
) =
firstByContains(tableName, criteria, clazz, null, conn)
/**
* Retrieve the first document using a JSON containment query and optional ordering fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param criteria The object for which JSON containment should be checked
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return The first document matching the JSON containment query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc, reified TContains> firstByContains(tableName: String, criteria: TContains, orderBy: Collection<Field<*>>? = null) =
Configuration.dbConn().use { firstByContains<TDoc, TContains>(tableName, criteria, orderBy, it) }
@Throws(DocumentException::class)
@JvmStatic
@JvmOverloads
fun <TDoc, TContains> firstByContains(
tableName: String,
criteria: TContains,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null
) =
Configuration.dbConn().use { firstByContains(tableName, criteria, clazz, orderBy, it) }
/**
* Retrieve the first document using a JSON Path match query and optional ordering fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @param conn The connection over which documents should be retrieved
* @return The first document matching the JSON Path match query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> firstByJsonPath(
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc> firstByJsonPath(
tableName: String,
path: String,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null,
conn: Connection
) =
conn.customSingle<TDoc>(
byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
conn.customSingle(
Find.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
listOf(Parameter(":path", ParameterType.STRING, path)),
clazz,
Results::fromData
)
@ -382,22 +438,34 @@ object Find {
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param conn The connection over which documents should be retrieved
* @return The first document matching the JSON Path match query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> firstByJsonPath(tableName: String, path: String, conn: Connection) =
firstByJsonPath<TDoc>(tableName, path, null, conn)
@Throws(DocumentException::class)
@JvmStatic
fun <TDoc> firstByJsonPath(tableName: String, path: String, clazz: Class<TDoc>, conn: Connection) =
firstByJsonPath(tableName, path, clazz, null, conn)
/**
* Retrieve the first document using a JSON Path match query and optional ordering fields (PostgreSQL only)
*
* @param tableName The table from which documents should be retrieved
* @param path The JSON path comparison to match
* @param clazz The class of the document to be returned
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
* @return The first document matching the JSON Path match query, or `null` if no matches are found
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TDoc> firstByJsonPath(tableName: String, path: String, orderBy: Collection<Field<*>>? = null) =
Configuration.dbConn().use { firstByJsonPath<TDoc>(tableName, path, orderBy, it) }
@Throws(DocumentException::class)
@JvmStatic
@JvmOverloads
fun <TDoc> firstByJsonPath(
tableName: String,
path: String,
clazz: Class<TDoc>,
orderBy: Collection<Field<*>>? = null
) =
Configuration.dbConn().use { firstByJsonPath(tableName, path, clazz, orderBy, it) }
}

View File

@ -1,9 +1,7 @@
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.common.FieldMatch
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.common.ParameterType
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.common.query.Patch
import java.sql.Connection
/**
@ -19,7 +17,8 @@ object Patch {
* @param patch The object whose properties should be replaced in the document
* @param conn The connection on which the update should be executed
*/
inline fun <TKey, reified TPatch> byId(tableName: String, docId: TKey, patch: TPatch, conn: Connection) =
@JvmStatic
fun <TKey, TPatch> byId(tableName: String, docId: TKey, patch: TPatch, conn: Connection) =
conn.customNonQuery(
Patch.byId(tableName, docId),
Parameters.addFields(
@ -35,7 +34,8 @@ object Patch {
* @param docId The ID of the document to be patched
* @param patch The object whose properties should be replaced in the document
*/
inline fun <TKey, reified TPatch> byId(tableName: String, docId: TKey, patch: TPatch) =
@JvmStatic
fun <TKey, TPatch> byId(tableName: String, docId: TKey, patch: TPatch) =
Configuration.dbConn().use { byId(tableName, docId, patch, it) }
/**
@ -47,7 +47,8 @@ object Patch {
* @param howMatched How the fields should be matched
* @param conn The connection on which the update should be executed
*/
inline fun <reified TPatch> byFields(
@JvmStatic
fun <TPatch> byFields(
tableName: String,
fields: Collection<Field<*>>,
patch: TPatch,
@ -56,7 +57,7 @@ object Patch {
) {
val named = Parameters.nameFields(fields)
conn.customNonQuery(
byFields(tableName, named, howMatched), Parameters.addFields(
Patch.byFields(tableName, named, howMatched), Parameters.addFields(
named,
mutableListOf(Parameters.json(":data", patch))
)
@ -71,7 +72,9 @@ object Patch {
* @param patch The object whose properties should be replaced in the document
* @param howMatched How the fields should be matched
*/
inline fun <reified TPatch> byFields(
@JvmStatic
@JvmOverloads
fun <TPatch> byFields(
tableName: String,
fields: Collection<Field<*>>,
patch: TPatch,
@ -88,12 +91,9 @@ object Patch {
* @param conn The connection on which the update should be executed
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains, reified TPatch> byContains(
tableName: String,
criteria: TContains,
patch: TPatch,
conn: Connection
) =
@Throws(DocumentException::class)
@JvmStatic
fun <TContains, TPatch> byContains(tableName: String, criteria: TContains, patch: TPatch, conn: Connection) =
conn.customNonQuery(
Patch.byContains(tableName),
listOf(Parameters.json(":criteria", criteria), Parameters.json(":data", patch))
@ -107,7 +107,9 @@ object Patch {
* @param patch The object whose properties should be replaced in the document
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains, reified TPatch> byContains(tableName: String, criteria: TContains, patch: TPatch) =
@Throws(DocumentException::class)
@JvmStatic
fun <TContains, TPatch> byContains(tableName: String, criteria: TContains, patch: TPatch) =
Configuration.dbConn().use { byContains(tableName, criteria, patch, it) }
/**
@ -119,7 +121,9 @@ object Patch {
* @param conn The connection on which the update should be executed
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TPatch> byJsonPath(tableName: String, path: String, patch: TPatch, conn: Connection) =
@Throws(DocumentException::class)
@JvmStatic
fun <TPatch> byJsonPath(tableName: String, path: String, patch: TPatch, conn: Connection) =
conn.customNonQuery(
Patch.byJsonPath(tableName),
listOf(Parameter(":path", ParameterType.STRING, path), Parameters.json(":data", patch))
@ -133,6 +137,8 @@ object Patch {
* @param patch The object whose properties should be replaced in the document
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TPatch> byJsonPath(tableName: String, path: String, patch: TPatch) =
@Throws(DocumentException::class)
@JvmStatic
fun <TPatch> byJsonPath(tableName: String, path: String, patch: TPatch) =
Configuration.dbConn().use { byJsonPath(tableName, path, patch, it) }
}

View File

@ -1,6 +1,7 @@
package solutions.bitbadger.documents.java
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.common.query.RemoveFields
import java.sql.Connection
/**
@ -18,7 +19,7 @@ object RemoveFields {
val dialect = Configuration.dialect("remove fields")
return when (dialect) {
Dialect.POSTGRESQL -> parameters
Dialect.SQLITE -> parameters.map { Parameter(it.name, it.type, "$.${it.value}") }.toMutableList()
Dialect.SQLITE -> parameters.map { Parameter(it.name, it.type, "$.${it.value}") }.toMutableList()
}
}
@ -30,10 +31,11 @@ object RemoveFields {
* @param toRemove The names of the fields to be removed
* @param conn The connection on which the update should be executed
*/
@JvmStatic
fun <TKey> byId(tableName: String, docId: TKey, toRemove: Collection<String>, conn: Connection) {
val nameParams = Parameters.fieldNames(toRemove)
conn.customNonQuery(
byId(tableName, nameParams, docId),
RemoveFields.byId(tableName, nameParams, docId),
Parameters.addFields(
listOf(Field.equal(Configuration.idField, docId, ":id")),
translatePath(nameParams)
@ -48,6 +50,7 @@ object RemoveFields {
* @param docId The ID of the document to have fields removed
* @param toRemove The names of the fields to be removed
*/
@JvmStatic
fun <TKey> byId(tableName: String, docId: TKey, toRemove: Collection<String>) =
Configuration.dbConn().use { byId(tableName, docId, toRemove, it) }
@ -60,6 +63,7 @@ object RemoveFields {
* @param howMatched How the fields should be matched
* @param conn The connection on which the update should be executed
*/
@JvmStatic
fun byFields(
tableName: String,
fields: Collection<Field<*>>,
@ -70,7 +74,7 @@ object RemoveFields {
val named = Parameters.nameFields(fields)
val nameParams = Parameters.fieldNames(toRemove)
conn.customNonQuery(
byFields(tableName, nameParams, named, howMatched),
RemoveFields.byFields(tableName, nameParams, named, howMatched),
Parameters.addFields(named, translatePath(nameParams))
)
}
@ -83,6 +87,8 @@ object RemoveFields {
* @param toRemove The names of the fields to be removed
* @param howMatched How the fields should be matched
*/
@JvmStatic
@JvmOverloads
fun byFields(
tableName: String,
fields: Collection<Field<*>>,
@ -100,7 +106,9 @@ object RemoveFields {
* @param conn The connection on which the update should be executed
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> byContains(
@Throws(DocumentException::class)
@JvmStatic
fun <TContains> byContains(
tableName: String,
criteria: TContains,
toRemove: Collection<String>,
@ -121,7 +129,9 @@ object RemoveFields {
* @param toRemove The names of the fields to be removed
* @throws DocumentException If called on a SQLite connection
*/
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, toRemove: Collection<String>) =
@Throws(DocumentException::class)
@JvmStatic
fun <TContains> byContains(tableName: String, criteria: TContains, toRemove: Collection<String>) =
Configuration.dbConn().use { byContains(tableName, criteria, toRemove, it) }
/**
@ -133,6 +143,8 @@ object RemoveFields {
* @param conn The connection on which the update should be executed
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun byJsonPath(tableName: String, path: String, toRemove: Collection<String>, conn: Connection) {
val nameParams = Parameters.fieldNames(toRemove)
conn.customNonQuery(
@ -149,6 +161,8 @@ object RemoveFields {
* @param toRemove The names of the fields to be removed
* @throws DocumentException If called on a SQLite connection
*/
@Throws(DocumentException::class)
@JvmStatic
fun byJsonPath(tableName: String, path: String, toRemove: Collection<String>) =
Configuration.dbConn().use { byJsonPath(tableName, path, toRemove, it) }
}

View File

@ -63,12 +63,13 @@ object Results {
* Extract a count from the first column
*
* @param rs A `ResultSet` set to the row with the count to retrieve
* @param clazz The type parameter (ignored; this always returns `Long`)
* @return The count from the row
* @throws DocumentException If the dialect has not been set
*/
@Throws(DocumentException::class)
@JvmStatic
fun toCount(rs: ResultSet) =
fun toCount(rs: ResultSet, clazz: Class<*>) =
when (Configuration.dialect()) {
Dialect.POSTGRESQL -> rs.getInt("it").toLong()
Dialect.SQLITE -> rs.getLong("it")
@ -78,14 +79,15 @@ object Results {
* Extract a true/false value from the first column
*
* @param rs A `ResultSet` set to the row with the true/false value to retrieve
* @param clazz The type parameter (ignored; this always returns `Boolean`)
* @return The true/false value from the row
* @throws DocumentException If the dialect has not been set
*/
@Throws(DocumentException::class)
@JvmStatic
fun toExists(rs: ResultSet) =
fun toExists(rs: ResultSet, clazz: Class<*>) =
when (Configuration.dialect()) {
Dialect.POSTGRESQL -> rs.getBoolean("it")
Dialect.SQLITE -> toCount(rs) > 0L
Dialect.SQLITE -> toCount(rs, Long::class.java) > 0L
}
}

View File

@ -1,9 +1,12 @@
package solutions.bitbadger.documents.java.integration.common
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.common.query.Count
import solutions.bitbadger.documents.common.query.Delete
import solutions.bitbadger.documents.common.query.Find
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.java.integration.JsonDocument
import solutions.bitbadger.documents.java.integration.TEST_TABLE
import solutions.bitbadger.documents.java.Results
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
@ -17,26 +20,26 @@ object Custom {
fun listEmpty(db: ThrowawayDatabase) {
JsonDocument.load(db)
db.conn.deleteByFields(TEST_TABLE, listOf(Field.exists(Configuration.idField)))
val result = db.conn.customList<JsonDocument>(Find.all(TEST_TABLE), mapFunc = Results::fromData)
val result = db.conn.customList(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData)
assertEquals(0, result.size, "There should have been no results")
}
fun listAll(db: ThrowawayDatabase) {
JsonDocument.load(db)
val result = db.conn.customList<JsonDocument>(Find.all(TEST_TABLE), mapFunc = Results::fromData)
val result = db.conn.customList(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData)
assertEquals(5, result.size, "There should have been 5 results")
}
fun singleNone(db: ThrowawayDatabase) =
assertNull(
db.conn.customSingle(Find.all(TEST_TABLE), mapFunc = Results::fromData),
db.conn.customSingle(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData),
"There should not have been a document returned"
)
fun singleOne(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertNotNull(
db.conn.customSingle<JsonDocument>(Find.all(TEST_TABLE), mapFunc = Results::fromData),
db.conn.customSingle(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData),
"There should not have been a document returned"
)
}
@ -44,12 +47,12 @@ object Custom {
fun nonQueryChanges(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertEquals(
5L, db.conn.customScalar(Count.all(TEST_TABLE), mapFunc = Results::toCount),
5L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
"There should have been 5 documents in the table"
)
db.conn.customNonQuery("DELETE FROM $TEST_TABLE")
assertEquals(
0L, db.conn.customScalar(Count.all(TEST_TABLE), mapFunc = Results::toCount),
0L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
"There should have been no documents in the table"
)
}
@ -57,7 +60,7 @@ object Custom {
fun nonQueryNoChanges(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertEquals(
5L, db.conn.customScalar(Count.all(TEST_TABLE), mapFunc = Results::toCount),
5L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
"There should have been 5 documents in the table"
)
db.conn.customNonQuery(
@ -65,7 +68,7 @@ object Custom {
listOf(Parameter(":id", ParameterType.STRING, "eighty-two"))
)
assertEquals(
5L, db.conn.customScalar(Count.all(TEST_TABLE), mapFunc = Results::toCount),
5L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
"There should still have been 5 documents in the table"
)
}
@ -74,7 +77,12 @@ object Custom {
JsonDocument.load(db)
assertEquals(
3L,
db.conn.customScalar("SELECT 3 AS it FROM $TEST_TABLE LIMIT 1", mapFunc = Results::toCount),
db.conn.customScalar(
"SELECT 3 AS it FROM $TEST_TABLE LIMIT 1",
listOf(),
Long::class.java,
Results::toCount
),
"The number 3 should have been returned"
)
}

View File

@ -1,8 +1,6 @@
package solutions.bitbadger.documents.java.integration.common
import solutions.bitbadger.documents.*
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.integration.*
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.java.integration.*
import kotlin.test.*
@ -16,7 +14,7 @@ object Document {
assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table")
val doc = JsonDocument("turkey", "", 0, SubDocument("gobble", "gobble"))
db.conn.insert(TEST_TABLE, doc)
val after = db.conn.findAll<JsonDocument>(TEST_TABLE)
val after = db.conn.findAll(TEST_TABLE, JsonDocument::class.java)
assertEquals(1, after.size, "There should be one document in the table")
assertEquals(doc, after[0], "The document should be what was inserted")
}
@ -42,7 +40,7 @@ object Document {
db.conn.insert(TEST_TABLE, NumIdDocument(77, "three"))
db.conn.insert(TEST_TABLE, NumIdDocument(0, "four"))
val after = db.conn.findAll<NumIdDocument>(TEST_TABLE, listOf(Field.named("key")))
val after = db.conn.findAll(TEST_TABLE, NumIdDocument::class.java, 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() },
@ -61,7 +59,7 @@ object Document {
db.conn.insert(TEST_TABLE, JsonDocument(""))
val after = db.conn.findAll<JsonDocument>(TEST_TABLE)
val after = db.conn.findAll(TEST_TABLE, JsonDocument::class.java)
assertEquals(1, after.size, "There should have been 1 document returned")
assertEquals(32, after[0].id.length, "The ID was not generated correctly")
} finally {
@ -79,7 +77,7 @@ object Document {
Configuration.idStringLength = 21
db.conn.insert(TEST_TABLE, JsonDocument(""))
val after = db.conn.findAll<JsonDocument>(TEST_TABLE)
val after = db.conn.findAll(TEST_TABLE, JsonDocument::class.java)
assertEquals(2, after.size, "There should have been 2 documents returned")
assertEquals(16, after[0].id.length, "The first document's ID was not generated correctly")
assertEquals(21, after[1].id.length, "The second document's ID was not generated correctly")
@ -92,7 +90,7 @@ object Document {
fun saveMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
db.conn.save(TEST_TABLE, JsonDocument("two", numValue = 44))
val doc = db.conn.findById<String, JsonDocument>(TEST_TABLE, "two")
val doc = db.conn.findById(TEST_TABLE, "two", JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("two", doc.id, "An incorrect document was returned")
assertEquals("", doc.value, "The \"value\" field was not updated")
@ -104,7 +102,7 @@ object Document {
JsonDocument.load(db)
db.conn.save(TEST_TABLE, JsonDocument("test", sub = SubDocument("a", "b")))
assertNotNull(
db.conn.findById<String, JsonDocument>(TEST_TABLE, "test"),
db.conn.findById(TEST_TABLE, "test", JsonDocument::class.java),
"The test document should have been saved"
)
}
@ -112,7 +110,7 @@ object Document {
fun updateMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
db.conn.update(TEST_TABLE, "one", JsonDocument("one", "howdy", 8, SubDocument("y", "z")))
val doc = db.conn.findById<String, JsonDocument>(TEST_TABLE, "one")
val doc = db.conn.findById(TEST_TABLE, "one", JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("one", doc.id, "An incorrect document was returned")
assertEquals("howdy", doc.value, "The \"value\" field was not updated")

View File

@ -1,9 +1,6 @@
package solutions.bitbadger.documents.java.integration.common
import solutions.bitbadger.documents.*
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.common.FieldMatch
import solutions.bitbadger.documents.integration.*
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.java.integration.*
import kotlin.test.assertEquals
@ -18,12 +15,16 @@ object Find {
fun allDefault(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertEquals(5, db.conn.findAll<JsonDocument>(TEST_TABLE).size, "There should have been 5 documents returned")
assertEquals(
5,
db.conn.findAll(TEST_TABLE, JsonDocument::class.java).size,
"There should have been 5 documents returned"
)
}
fun allAscending(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findAll<JsonDocument>(TEST_TABLE, listOf(Field.named("id")))
val docs = db.conn.findAll(TEST_TABLE, JsonDocument::class.java, listOf(Field.named("id")))
assertEquals(5, docs.size, "There should have been 5 documents returned")
assertEquals(
"five|four|one|three|two",
@ -34,7 +35,7 @@ object Find {
fun allDescending(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findAll<JsonDocument>(TEST_TABLE, listOf(Field.named("id DESC")))
val docs = db.conn.findAll(TEST_TABLE, JsonDocument::class.java, listOf(Field.named("id DESC")))
assertEquals(5, docs.size, "There should have been 5 documents returned")
assertEquals(
"two|three|one|four|five",
@ -45,8 +46,9 @@ object Find {
fun allNumOrder(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findAll<JsonDocument>(
val docs = db.conn.findAll(
TEST_TABLE,
JsonDocument::class.java,
listOf(Field.named("sub.foo NULLS LAST"), Field.named("n:numValue"))
)
assertEquals(5, docs.size, "There should have been 5 documents returned")
@ -58,11 +60,15 @@ object Find {
}
fun allEmpty(db: ThrowawayDatabase) =
assertEquals(0, db.conn.findAll<JsonDocument>(TEST_TABLE).size, "There should have been no documents returned")
assertEquals(
0,
db.conn.findAll(TEST_TABLE, JsonDocument::class.java).size,
"There should have been no documents returned"
)
fun byIdString(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findById<String, JsonDocument>(TEST_TABLE, "two")
val doc = db.conn.findById(TEST_TABLE, "two", JsonDocument::class.java)
assertNotNull(doc, "The document should have been returned")
assertEquals("two", doc.id, "An incorrect document was returned")
}
@ -71,7 +77,7 @@ object Find {
Configuration.idField = "key"
try {
db.conn.insert(TEST_TABLE, NumIdDocument(18, "howdy"))
val doc = db.conn.findById<Int, NumIdDocument>(TEST_TABLE, 18)
val doc = db.conn.findById(TEST_TABLE, 18, NumIdDocument::class.java)
assertNotNull(doc, "The document should have been returned")
} finally {
Configuration.idField = "id"
@ -81,16 +87,17 @@ object Find {
fun byIdNotFound(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertNull(
db.conn.findById<String, JsonDocument>(TEST_TABLE, "x"),
db.conn.findById(TEST_TABLE, "x", JsonDocument::class.java),
"There should have been no document returned"
)
}
fun byFieldsMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findByFields<JsonDocument>(
val docs = db.conn.findByFields(
TEST_TABLE,
listOf(Field.any("value", listOf("blue", "purple")), Field.exists("sub")),
JsonDocument::class.java,
FieldMatch.ALL
)
assertEquals(1, docs.size, "There should have been a document returned")
@ -99,9 +106,10 @@ object Find {
fun byFieldsMatchOrdered(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findByFields<JsonDocument>(
val docs = db.conn.findByFields(
TEST_TABLE,
listOf(Field.equal("value", "purple")),
JsonDocument::class.java,
orderBy = listOf(Field.named("id"))
)
assertEquals(2, docs.size, "There should have been 2 documents returned")
@ -110,7 +118,11 @@ object Find {
fun byFieldsMatchNumIn(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findByFields<JsonDocument>(TEST_TABLE, listOf(Field.any("numValue", listOf(2, 4, 6, 8))))
val docs = db.conn.findByFields(
TEST_TABLE,
listOf(Field.any("numValue", listOf(2, 4, 6, 8))),
JsonDocument::class.java
)
assertEquals(1, docs.size, "There should have been a document returned")
assertEquals("three", docs[0].id, "The incorrect document was returned")
}
@ -119,7 +131,7 @@ object Find {
JsonDocument.load(db)
assertEquals(
0,
db.conn.findByFields<JsonDocument>(TEST_TABLE, listOf(Field.greater("numValue", 100))).size,
db.conn.findByFields(TEST_TABLE, listOf(Field.greater("numValue", 100)), JsonDocument::class.java).size,
"There should have been no documents returned"
)
}
@ -127,7 +139,11 @@ object Find {
fun byFieldsMatchInArray(db: ThrowawayDatabase) {
ArrayDocument.testDocuments.forEach { db.conn.insert(TEST_TABLE, it) }
val docs =
db.conn.findByFields<ArrayDocument>(TEST_TABLE, listOf(Field.inArray("values", TEST_TABLE, listOf("c"))))
db.conn.findByFields(
TEST_TABLE,
listOf(Field.inArray("values", TEST_TABLE, listOf("c"))),
ArrayDocument::class.java
)
assertEquals(2, docs.size, "There should have been two documents returned")
assertTrue(listOf("first", "second").contains(docs[0].id), "An incorrect document was returned (${docs[0].id}")
assertTrue(listOf("first", "second").contains(docs[1].id), "An incorrect document was returned (${docs[1].id}")
@ -137,9 +153,10 @@ object Find {
ArrayDocument.testDocuments.forEach { db.conn.insert(TEST_TABLE, it) }
assertEquals(
0,
db.conn.findByFields<ArrayDocument>(
db.conn.findByFields(
TEST_TABLE,
listOf(Field.inArray("values", TEST_TABLE, listOf("j")))
listOf(Field.inArray("values", TEST_TABLE, listOf("j"))),
ArrayDocument::class.java
).size,
"There should have been no documents returned"
)
@ -147,7 +164,7 @@ object Find {
fun byContainsMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findByContains<JsonDocument, Map<String, String>>(TEST_TABLE, mapOf("value" to "purple"))
val docs = db.conn.findByContains(TEST_TABLE, mapOf("value" to "purple"), JsonDocument::class.java)
assertEquals(2, docs.size, "There should have been 2 documents returned")
assertTrue(listOf("four", "five").contains(docs[0].id), "An incorrect document was returned (${docs[0].id}")
assertTrue(listOf("four", "five").contains(docs[1].id), "An incorrect document was returned (${docs[1].id}")
@ -155,9 +172,10 @@ object Find {
fun byContainsMatchOrdered(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findByContains<JsonDocument, Map<String, Map<String, String>>>(
val docs = db.conn.findByContains(
TEST_TABLE,
mapOf("sub" to mapOf("foo" to "green")),
JsonDocument::class.java,
listOf(Field.named("value"))
)
assertEquals(2, docs.size, "There should have been 2 documents returned")
@ -168,14 +186,14 @@ object Find {
JsonDocument.load(db)
assertEquals(
0,
db.conn.findByContains<JsonDocument, Map<String, String>>(TEST_TABLE, mapOf("value" to "indigo")).size,
db.conn.findByContains(TEST_TABLE, mapOf("value" to "indigo"), JsonDocument::class.java).size,
"There should have been no documents returned"
)
}
fun byJsonPathMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findByJsonPath<JsonDocument>(TEST_TABLE, "$.numValue ? (@ > 10)")
val docs = db.conn.findByJsonPath(TEST_TABLE, "$.numValue ? (@ > 10)", JsonDocument::class.java)
assertEquals(2, docs.size, "There should have been 2 documents returned")
assertTrue(listOf("four", "five").contains(docs[0].id), "An incorrect document was returned (${docs[0].id}")
assertTrue(listOf("four", "five").contains(docs[1].id), "An incorrect document was returned (${docs[1].id}")
@ -183,7 +201,12 @@ object Find {
fun byJsonPathMatchOrdered(db: ThrowawayDatabase) {
JsonDocument.load(db)
val docs = db.conn.findByJsonPath<JsonDocument>(TEST_TABLE, "$.numValue ? (@ > 10)", listOf(Field.named("id")))
val docs = db.conn.findByJsonPath(
TEST_TABLE,
"$.numValue ? (@ > 10)",
JsonDocument::class.java,
listOf(Field.named("id"))
)
assertEquals(2, docs.size, "There should have been 2 documents returned")
assertEquals("five|four", docs.joinToString("|") { it.id }, "The documents were not ordered correctly")
}
@ -192,30 +215,34 @@ object Find {
JsonDocument.load(db)
assertEquals(
0,
db.conn.findByJsonPath<JsonDocument>(TEST_TABLE, "$.numValue ? (@ > 100)").size,
db.conn.findByJsonPath(TEST_TABLE, "$.numValue ? (@ > 100)", JsonDocument::class.java).size,
"There should have been no documents returned"
)
}
fun firstByFieldsMatchOne(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByFields<JsonDocument>(TEST_TABLE, listOf(Field.equal("value", "another")))
val doc =
db.conn.findFirstByFields(TEST_TABLE, listOf(Field.equal("value", "another")), JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("two", doc.id, "The incorrect document was returned")
}
fun firstByFieldsMatchMany(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByFields<JsonDocument>(TEST_TABLE, listOf(Field.equal("sub.foo", "green")))
val doc =
db.conn.findFirstByFields(TEST_TABLE, listOf(Field.equal("sub.foo", "green")), JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertTrue(listOf("two", "four").contains(doc.id), "An incorrect document was returned (${doc.id}")
}
fun firstByFieldsMatchOrdered(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByFields<JsonDocument>(
TEST_TABLE, listOf(Field.equal("sub.foo", "green")), orderBy = listOf(
Field.named("n:numValue DESC")))
val doc = db.conn.findFirstByFields(
TEST_TABLE, listOf(Field.equal("sub.foo", "green")), JsonDocument::class.java, orderBy = listOf(
Field.named("n:numValue DESC")
)
)
assertNotNull(doc, "There should have been a document returned")
assertEquals("four", doc.id, "An incorrect document was returned")
}
@ -223,30 +250,31 @@ object Find {
fun firstByFieldsNoMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertNull(
db.conn.findFirstByFields(TEST_TABLE, listOf(Field.equal("value", "absent"))),
db.conn.findFirstByFields(TEST_TABLE, listOf(Field.equal("value", "absent")), JsonDocument::class.java),
"There should have been no document returned"
)
}
fun firstByContainsMatchOne(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByContains<JsonDocument, Map<String, String>>(TEST_TABLE, mapOf("value" to "FIRST!"))
val doc = db.conn.findFirstByContains(TEST_TABLE, mapOf("value" to "FIRST!"), JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("one", doc.id, "An incorrect document was returned")
}
fun firstByContainsMatchMany(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByContains<JsonDocument, Map<String, String>>(TEST_TABLE, mapOf("value" to "purple"))
val doc = db.conn.findFirstByContains(TEST_TABLE, mapOf("value" to "purple"), JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertTrue(listOf("four", "five").contains(doc.id), "An incorrect document was returned (${doc.id}")
}
fun firstByContainsMatchOrdered(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByContains<JsonDocument, Map<String, String>>(
val doc = db.conn.findFirstByContains(
TEST_TABLE,
mapOf("value" to "purple"),
JsonDocument::class.java,
listOf(Field.named("sub.bar NULLS FIRST"))
)
assertNotNull(doc, "There should have been a document returned")
@ -256,32 +284,31 @@ object Find {
fun firstByContainsNoMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertNull(
db.conn.findFirstByContains<JsonDocument, Map<String, String>>(
TEST_TABLE,
mapOf("value" to "indigo")
), "There should have been no document returned"
db.conn.findFirstByContains(TEST_TABLE, mapOf("value" to "indigo"), JsonDocument::class.java),
"There should have been no document returned"
)
}
fun firstByJsonPathMatchOne(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByJsonPath<JsonDocument>(TEST_TABLE, "$.numValue ? (@ == 10)")
val doc = db.conn.findFirstByJsonPath(TEST_TABLE, "$.numValue ? (@ == 10)", JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("two", doc.id, "An incorrect document was returned")
}
fun firstByJsonPathMatchMany(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByJsonPath<JsonDocument>(TEST_TABLE, "$.numValue ? (@ > 10)")
val doc = db.conn.findFirstByJsonPath(TEST_TABLE, "$.numValue ? (@ > 10)", JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertTrue(listOf("four", "five").contains(doc.id), "An incorrect document was returned (${doc.id}")
}
fun firstByJsonPathMatchOrdered(db: ThrowawayDatabase) {
JsonDocument.load(db)
val doc = db.conn.findFirstByJsonPath<JsonDocument>(
val doc = db.conn.findFirstByJsonPath(
TEST_TABLE,
"$.numValue ? (@ > 10)",
JsonDocument::class.java,
listOf(Field.named("id DESC"))
)
assertNotNull(doc, "There should have been a document returned")
@ -290,6 +317,9 @@ object Find {
fun firstByJsonPathNoMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertNull(db.conn.findFirstByJsonPath<JsonDocument>(TEST_TABLE, "$.numValue ? (@ > 100)"), "There should have been no document returned")
assertNull(
db.conn.findFirstByJsonPath(TEST_TABLE, "$.numValue ? (@ > 100)", JsonDocument::class.java),
"There should have been no document returned"
)
}
}

View File

@ -1,6 +1,5 @@
package solutions.bitbadger.documents.java.integration.common
import solutions.bitbadger.documents.*
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.java.integration.JsonDocument
@ -19,7 +18,7 @@ object Patch {
fun byIdMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
db.conn.patchById(TEST_TABLE, "one", mapOf("numValue" to 44))
val doc = db.conn.findById<String, JsonDocument>(TEST_TABLE, "one")
val doc = db.conn.findById(TEST_TABLE, "one", JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("one", doc.id, "An incorrect document was returned")
assertEquals(44, doc.numValue, "The document was not patched")
@ -56,7 +55,7 @@ object Patch {
JsonDocument.load(db)
val contains = mapOf("value" to "another")
db.conn.patchByContains(TEST_TABLE, contains, mapOf("numValue" to 12))
val doc = db.conn.findFirstByContains<JsonDocument, Map<String, String>>(TEST_TABLE, contains)
val doc = db.conn.findFirstByContains(TEST_TABLE, contains, JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("two", doc.id, "The incorrect document was returned")
assertEquals(12, doc.numValue, "The document was not updated")
@ -73,7 +72,7 @@ object Patch {
JsonDocument.load(db)
val path = "$.numValue ? (@ > 10)"
db.conn.patchByJsonPath(TEST_TABLE, path, mapOf("value" to "blue"))
val docs = db.conn.findByJsonPath<JsonDocument>(TEST_TABLE, path)
val docs = db.conn.findByJsonPath(TEST_TABLE, path, JsonDocument::class.java)
assertEquals(2, docs.size, "There should have been two documents returned")
docs.forEach {
assertTrue(listOf("four", "five").contains(it.id), "An incorrect document was returned (${it.id})")

View File

@ -1,6 +1,5 @@
package solutions.bitbadger.documents.java.integration.common
import solutions.bitbadger.documents.*
import solutions.bitbadger.documents.common.Field
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.java.integration.JsonDocument
@ -17,7 +16,7 @@ object RemoveFields {
fun byIdMatchFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
db.conn.removeFieldsById(TEST_TABLE, "two", listOf("sub", "value"))
val doc = db.conn.findById<String, JsonDocument>(TEST_TABLE, "two")
val doc = db.conn.findById(TEST_TABLE, "two", JsonDocument::class.java)
assertNotNull(doc, "There should have been a document returned")
assertEquals("", doc.value, "The value should have been empty")
assertNull(doc.sub, "The sub-document should have been removed")
@ -39,7 +38,7 @@ object RemoveFields {
JsonDocument.load(db)
val fields = listOf(Field.equal("numValue", 17))
db.conn.removeFieldsByFields(TEST_TABLE, fields, listOf("sub"))
val doc = db.conn.findFirstByFields<JsonDocument>(TEST_TABLE, fields)
val doc = db.conn.findFirstByFields(TEST_TABLE, fields, JsonDocument::class.java)
assertNotNull(doc, "The document should have been returned")
assertEquals("four", doc.id, "An incorrect document was returned")
assertNull(doc.sub, "The sub-document should have been removed")
@ -62,7 +61,7 @@ object RemoveFields {
JsonDocument.load(db)
val criteria = mapOf("sub" to mapOf("foo" to "green"))
db.conn.removeFieldsByContains(TEST_TABLE, criteria, listOf("value"))
val docs = db.conn.findByContains<JsonDocument, Map<String, Map<String, String>>>(TEST_TABLE, criteria)
val docs = db.conn.findByContains(TEST_TABLE, criteria, JsonDocument::class.java)
assertEquals(2, docs.size, "There should have been 2 documents returned")
docs.forEach {
assertTrue(listOf("two", "four").contains(it.id), "An incorrect document was returned (${it.id})")
@ -88,7 +87,7 @@ object RemoveFields {
JsonDocument.load(db)
val path = "$.value ? (@ == \"purple\")"
db.conn.removeFieldsByJsonPath(TEST_TABLE, path, listOf("sub"))
val docs = db.conn.findByJsonPath<JsonDocument>(TEST_TABLE, path)
val docs = db.conn.findByJsonPath(TEST_TABLE, path, JsonDocument::class.java)
assertEquals(2, docs.size, "There should have been 2 documents returned")
docs.forEach {
assertTrue(listOf("four", "five").contains(it.id), "An incorrect document was returned (${it.id})")

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Count` object / `count*` connection extension functions
*/
@DisplayName("Kotlin | PostgreSQL: Count")
@DisplayName("Java | Kotlin | PostgreSQL: Count")
class CountIT {
@Test

View File

@ -8,7 +8,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Custom` object / `custom*` connection extension functions
*/
@DisplayName("PostgreSQL - Custom")
@DisplayName("Java | Kotlin | PostgreSQL: Custom")
class CustomIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Definition` object / `ensure*` connection extension functions
*/
@DisplayName("PostgreSQL - Definition")
@DisplayName("Java | Kotlin | PostgreSQL: Definition")
class DefinitionIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Delete` object / `deleteBy*` connection extension functions
*/
@DisplayName("PostgreSQL - Delete")
@DisplayName("Java | Kotlin | PostgreSQL: Delete")
class DeleteIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
*/
@DisplayName("PostgreSQL - Document")
@DisplayName("Java | Kotlin | PostgreSQL: Document")
class DocumentIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Exists` object / `existsBy*` connection extension functions
*/
@DisplayName("PostgreSQL - Exists")
@DisplayName("Java | Kotlin | PostgreSQL: Exists")
class ExistsIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Find` object / `find*` connection extension functions
*/
@DisplayName("PostgreSQL - Find")
@DisplayName("Java | Kotlin | PostgreSQL: Find")
class FindIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `Patch` object / `patchBy*` connection extension functions
*/
@DisplayName("PostgreSQL - Patch")
@DisplayName("Java | Kotlin | PostgreSQL: Patch")
class PatchIT {
@Test

View File

@ -1,8 +1,7 @@
package solutions.bitbadger.documents.java.integration.postgresql
import solutions.bitbadger.documents.*
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.common.ParameterType
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.java.integration.TEST_TABLE
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
@ -39,7 +38,7 @@ class PgDB : ThrowawayDatabase {
override fun dbObjectExists(name: String) =
conn.customScalar("SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = :name) AS it",
listOf(Parameter(":name", ParameterType.STRING, name)), Results::toExists)
listOf(Parameter(":name", ParameterType.STRING, name)), Boolean::class.java, Results::toExists)
companion object {

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* PostgreSQL integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
*/
@DisplayName("PostgreSQL - RemoveFields")
@DisplayName("Java | Kotlin | PostgreSQL: RemoveFields")
class RemoveFieldsIT {
@Test

View File

@ -9,7 +9,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Count` object / `count*` connection extension functions
*/
@DisplayName("SQLite - Count")
@DisplayName("Java | Kotlin | SQLite: Count")
class CountIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Custom` object / `custom*` connection extension functions
*/
@DisplayName("SQLite - Custom")
@DisplayName("Java | Kotlin | SQLite: Custom")
class CustomIT {
@Test

View File

@ -9,7 +9,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Definition` object / `ensure*` connection extension functions
*/
@DisplayName("SQLite - Definition")
@DisplayName("Java | Kotlin | SQLite: Definition")
class DefinitionIT {
@Test

View File

@ -9,7 +9,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Delete` object / `deleteBy*` connection extension functions
*/
@DisplayName("SQLite - Delete")
@DisplayName("Java | Kotlin | SQLite: Delete")
class DeleteIT {
@Test

View File

@ -7,7 +7,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
*/
@DisplayName("SQLite - Document")
@DisplayName("Java | Kotlin | SQLite: Document")
class DocumentIT {
@Test

View File

@ -9,7 +9,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Exists` object / `existsBy*` connection extension functions
*/
@DisplayName("SQLite - Exists")
@DisplayName("Java | Kotlin | SQLite: Exists")
class ExistsIT {
@Test

View File

@ -9,7 +9,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Find` object / `find*` connection extension functions
*/
@DisplayName("SQLite - Find")
@DisplayName("Java | Kotlin | SQLite: Find")
class FindIT {
@Test

View File

@ -9,7 +9,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `Patch` object / `patchBy*` connection extension functions
*/
@DisplayName("SQLite - Patch")
@DisplayName("Java | Kotlin | SQLite: Patch")
class PatchIT {
@Test

View File

@ -9,7 +9,7 @@ import kotlin.test.Test
/**
* SQLite integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
*/
@DisplayName("SQLite - RemoveFields")
@DisplayName("Java | Kotlin | SQLite: RemoveFields")
class RemoveFieldsIT {
@Test

View File

@ -1,8 +1,7 @@
package solutions.bitbadger.documents.java.integration.sqlite
import solutions.bitbadger.documents.*
import solutions.bitbadger.documents.common.Parameter
import solutions.bitbadger.documents.common.ParameterType
import solutions.bitbadger.documents.common.*
import solutions.bitbadger.documents.java.*
import solutions.bitbadger.documents.java.integration.TEST_TABLE
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
import java.io.File
@ -32,5 +31,5 @@ class SQLiteDB : ThrowawayDatabase {
override fun dbObjectExists(name: String) =
conn.customScalar("SELECT EXISTS (SELECT 1 FROM sqlite_master WHERE name = :name) AS it",
listOf(Parameter(":name", ParameterType.STRING, name)), Results::toExists)
listOf(Parameter(":name", ParameterType.STRING, name)), Boolean::class.java, Results::toExists)
}

View File

@ -1,79 +0,0 @@
package solutions.bitbadger.documents
import solutions.bitbadger.documents.common.Dialect
import solutions.bitbadger.documents.common.DocumentException
import solutions.bitbadger.documents.java.Results
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.SQLException
/**
* Helper functions for handling results
*/
object Results {
/**
* Create a domain item from a document, specifying the field in which the document is found
*
* @param field The field name containing the JSON document
* @param rs A `ResultSet` set to the row with the document to be constructed
* @return The constructed domain item
*/
inline fun <reified TDoc> fromDocument(field: String): (ResultSet, Class<TDoc>) -> TDoc =
{ rs, _ -> Results.fromDocument(field, rs, TDoc::class.java) }
/**
* Create a domain item from a document
*
* @param rs A `ResultSet` set to the row with the document to be constructed<
* @param clazz The class of the document to be returned
* @return The constructed domain item
*/
inline fun <reified TDoc> fromData(rs: ResultSet, clazz: Class<TDoc> = TDoc::class.java) =
Results.fromDocument("data", rs, TDoc::class.java)
/**
* Create a list of items for the results of the given command, using the specified mapping function
*
* @param stmt The prepared statement to execute
* @param mapFunc The mapping function from data reader to domain class instance
* @return A list of items from the query's result
* @throws DocumentException If there is a problem executing the query
*/
inline fun <reified TDoc : Any> toCustomList(stmt: PreparedStatement, mapFunc: (ResultSet) -> TDoc) =
try {
stmt.executeQuery().use {
val results = mutableListOf<TDoc>()
while (it.next()) {
results.add(mapFunc(it))
}
results.toList()
}
} catch (ex: SQLException) {
throw DocumentException("Error retrieving documents from query: ${ex.message}", ex)
}
/**
* Extract a count from the first column
*
* @param rs A `ResultSet` set to the row with the count to retrieve
* @return The count from the row
*/
fun toCount(rs: ResultSet, clazz: Class<Long> = Long::class.java) =
when (Configuration.dialect()) {
Dialect.POSTGRESQL -> rs.getInt("it").toLong()
Dialect.SQLITE -> rs.getLong("it")
}
/**
* Extract a true/false value from the first column
*
* @param rs A `ResultSet` set to the row with the true/false value to retrieve
* @return The true/false value from the row
*/
fun toExists(rs: ResultSet, clazz: Class<Boolean> = Boolean::class.java) =
when (Configuration.dialect()) {
Dialect.POSTGRESQL -> rs.getBoolean("it")
Dialect.SQLITE -> toCount(rs) > 0L
}
}