478 lines
19 KiB
Kotlin
478 lines
19 KiB
Kotlin
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 java.sql.Connection
|
|
import java.sql.ResultSet
|
|
|
|
// ~~~ CUSTOM QUERIES ~~~
|
|
|
|
/**
|
|
* Execute a query that returns a list of results
|
|
*
|
|
* @param query The query to retrieve the results
|
|
* @param parameters Parameters to use for the query
|
|
* @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)
|
|
|
|
/**
|
|
* 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 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)
|
|
|
|
/**
|
|
* Execute a query that returns no results
|
|
*
|
|
* @param query The query to retrieve the results
|
|
* @param parameters Parameters to use for the query
|
|
*/
|
|
fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
|
Custom.nonQuery(query, parameters, this)
|
|
|
|
/**
|
|
* Execute a query that returns a scalar result
|
|
*
|
|
* @param query The query to retrieve the result
|
|
* @param parameters Parameters to use for the query
|
|
* @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(
|
|
query: String,
|
|
parameters: Collection<Parameter<*>> = listOf(),
|
|
noinline mapFunc: (ResultSet, Class<T>) -> T
|
|
) = Custom.scalar(query, parameters, this, mapFunc)
|
|
|
|
// ~~~ DEFINITION QUERIES ~~~
|
|
|
|
/**
|
|
* Create a document table if necessary
|
|
*
|
|
* @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)
|
|
|
|
/**
|
|
* Create an index on field(s) within documents in the specified table if necessary
|
|
*
|
|
* @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<
|
|
*/
|
|
fun Connection.ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>) =
|
|
solutions.bitbadger.documents.java.Definition.ensureFieldIndex(tableName, indexName, fields, this)
|
|
|
|
/**
|
|
* Create a document index on a table (PostgreSQL only)
|
|
*
|
|
* @param tableName The table to be indexed (may include schema)
|
|
* @param indexType The type of index to ensure
|
|
* @throws DocumentException If called on a SQLite connection
|
|
*/
|
|
fun Connection.ensureDocumentIndex(tableName: String, indexType: DocumentIndex) =
|
|
solutions.bitbadger.documents.java.Definition.ensureDocumentIndex(tableName, indexType, this)
|
|
|
|
// ~~~ DOCUMENT MANIPULATION QUERIES ~~~
|
|
|
|
/**
|
|
* Insert a new document
|
|
*
|
|
* @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) =
|
|
Document.insert(tableName, document, this)
|
|
|
|
/**
|
|
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
|
*
|
|
* @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) =
|
|
Document.save(tableName, document, this)
|
|
|
|
/**
|
|
* Update (replace) a document by its ID
|
|
*
|
|
* @param tableName The table in which the document should be replaced (may include schema)
|
|
* @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) =
|
|
Document.update(tableName, docId, document, this)
|
|
|
|
// ~~~ DOCUMENT COUNT QUERIES ~~~
|
|
|
|
/**
|
|
* Count all documents in the table
|
|
*
|
|
* @param tableName The name of the table in which documents should be counted
|
|
* @return A count of the documents in the table
|
|
*/
|
|
fun Connection.countAll(tableName: String) =
|
|
Count.all(tableName, this)
|
|
|
|
/**
|
|
* Count documents using a field comparison
|
|
*
|
|
* @param tableName The name of the table in which documents should be counted
|
|
* @param fields The fields which should be compared
|
|
* @param howMatched How the fields should be matched
|
|
* @return A count of the matching documents in the table
|
|
*/
|
|
fun Connection.countByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
|
Count.byFields(tableName, fields, howMatched, this)
|
|
|
|
/**
|
|
* Count documents using a JSON containment query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table in which documents should be counted
|
|
* @param criteria The object for which JSON containment should be checked
|
|
* @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) =
|
|
Count.byContains(tableName, criteria, this)
|
|
|
|
/**
|
|
* Count documents using a JSON Path match query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table in which documents should be counted
|
|
* @param path The JSON path comparison to match
|
|
* @return A count of the matching documents in the table
|
|
* @throws DocumentException If called on a SQLite connection
|
|
*/
|
|
fun Connection.countByJsonPath(tableName: String, path: String) =
|
|
Count.byJsonPath(tableName, path, this)
|
|
|
|
// ~~~ DOCUMENT EXISTENCE QUERIES ~~~
|
|
|
|
/**
|
|
* Determine a document's existence by its ID
|
|
*
|
|
* @param tableName The name of the table in which document existence should be checked
|
|
* @param docId The ID of the document to be checked
|
|
* @return True if the document exists, false if not
|
|
*/
|
|
fun <TKey> Connection.existsById(tableName: String, docId: TKey) =
|
|
Exists.byId(tableName, docId, this)
|
|
|
|
/**
|
|
* Determine document existence using a field comparison
|
|
*
|
|
* @param tableName The name of the table in which document existence should be checked
|
|
* @param fields The fields which should be compared
|
|
* @param howMatched How the fields should be matched
|
|
* @return True if any matching documents exist, false if not
|
|
*/
|
|
fun Connection.existsByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
|
Exists.byFields(tableName, fields, howMatched, this)
|
|
|
|
/**
|
|
* Determine document existence using a JSON containment query (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
|
|
* @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) =
|
|
Exists.byContains(tableName, criteria, this)
|
|
|
|
/**
|
|
* Determine document existence using a JSON Path match query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table in which document existence should be checked
|
|
* @param path The JSON path comparison to match
|
|
* @return True if any matching documents exist, false if not
|
|
* @throws DocumentException If called on a SQLite connection
|
|
*/
|
|
fun Connection.existsByJsonPath(tableName: String, path: String) =
|
|
Exists.byJsonPath(tableName, path, this)
|
|
|
|
// ~~~ DOCUMENT RETRIEVAL QUERIES ~~~
|
|
|
|
/**
|
|
* 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 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)
|
|
|
|
/**
|
|
* 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
|
|
* @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)
|
|
|
|
/**
|
|
* 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 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(
|
|
tableName: String,
|
|
fields: Collection<Field<*>>,
|
|
howMatched: FieldMatch? = null,
|
|
orderBy: Collection<Field<*>>? = null
|
|
) =
|
|
solutions.bitbadger.documents.java.Find.byFields<TDoc>(tableName, fields, 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 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(
|
|
tableName: String,
|
|
criteria: TContains,
|
|
orderBy: Collection<Field<*>>? = null
|
|
) =
|
|
solutions.bitbadger.documents.java.Find.byContains<TDoc, TContains>(tableName, criteria, 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 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(
|
|
tableName: String,
|
|
path: String,
|
|
orderBy: Collection<Field<*>>? = null
|
|
) =
|
|
solutions.bitbadger.documents.java.Find.byJsonPath<TDoc>(tableName, path, 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 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(
|
|
tableName: String,
|
|
fields: Collection<Field<*>>,
|
|
howMatched: FieldMatch? = null,
|
|
orderBy: Collection<Field<*>>? = null
|
|
) =
|
|
solutions.bitbadger.documents.java.Find.firstByFields<TDoc>(tableName, fields, 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 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(
|
|
tableName: String,
|
|
criteria: TContains,
|
|
orderBy: Collection<Field<*>>? = null
|
|
) =
|
|
solutions.bitbadger.documents.java.Find.firstByContains<TDoc, TContains>(tableName, criteria, 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 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(
|
|
tableName: String,
|
|
path: String,
|
|
orderBy: Collection<Field<*>>? = null
|
|
) =
|
|
solutions.bitbadger.documents.java.Find.firstByJsonPath<TDoc>(tableName, path, orderBy, this)
|
|
|
|
// ~~~ DOCUMENT PATCH (PARTIAL UPDATE) QUERIES ~~~
|
|
|
|
/**
|
|
* Patch a document by its ID
|
|
*
|
|
* @param tableName The name of the table in which a document should be patched
|
|
* @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) =
|
|
Patch.byId(tableName, docId, patch, this)
|
|
|
|
/**
|
|
* Patch documents using a field comparison
|
|
*
|
|
* @param tableName The name of the table in which documents should be patched
|
|
* @param fields The fields which should be compared
|
|
* @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(
|
|
tableName: String,
|
|
fields: Collection<Field<*>>,
|
|
patch: TPatch,
|
|
howMatched: FieldMatch? = null
|
|
) =
|
|
Patch.byFields(tableName, fields, patch, howMatched, this)
|
|
|
|
/**
|
|
* Patch documents using a JSON containment query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table in which documents should be patched
|
|
* @param criteria The object against which JSON containment should be checked
|
|
* @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(
|
|
tableName: String,
|
|
criteria: TContains,
|
|
patch: TPatch
|
|
) =
|
|
Patch.byContains(tableName, criteria, patch, this)
|
|
|
|
/**
|
|
* Patch documents using a JSON Path match query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table in which documents should be patched
|
|
* @param path The JSON path comparison to match
|
|
* @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) =
|
|
Patch.byJsonPath(tableName, path, patch, this)
|
|
|
|
// ~~~ DOCUMENT FIELD REMOVAL QUERIES ~~~
|
|
|
|
/**
|
|
* Remove fields from a document by its ID
|
|
*
|
|
* @param tableName The name of the table in which the document's fields should be removed
|
|
* @param docId The ID of the document to have fields removed
|
|
* @param toRemove The names of the fields to be removed
|
|
*/
|
|
fun <TKey> Connection.removeFieldsById(tableName: String, docId: TKey, toRemove: Collection<String>) =
|
|
RemoveFields.byId(tableName, docId, toRemove, this)
|
|
|
|
/**
|
|
* Remove fields from documents using a field comparison
|
|
*
|
|
* @param tableName The name of the table in which document fields should be removed
|
|
* @param fields The fields which should be compared
|
|
* @param toRemove The names of the fields to be removed
|
|
* @param howMatched How the fields should be matched
|
|
*/
|
|
fun Connection.removeFieldsByFields(
|
|
tableName: String,
|
|
fields: Collection<Field<*>>,
|
|
toRemove: Collection<String>,
|
|
howMatched: FieldMatch? = null
|
|
) =
|
|
RemoveFields.byFields(tableName, fields, toRemove, howMatched, this)
|
|
|
|
/**
|
|
* Remove fields from documents using a JSON containment query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table in which document fields should be removed
|
|
* @param criteria The object against which JSON containment should be checked
|
|
* @param toRemove The names of the fields to be removed
|
|
* @throws DocumentException If called on a SQLite connection
|
|
*/
|
|
inline fun <reified TContains> Connection.removeFieldsByContains(
|
|
tableName: String,
|
|
criteria: TContains,
|
|
toRemove: Collection<String>
|
|
) =
|
|
RemoveFields.byContains(tableName, criteria, toRemove, this)
|
|
|
|
/**
|
|
* Remove fields from documents using a JSON Path match query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table in which document fields should be removed
|
|
* @param path The JSON path comparison to match
|
|
* @param toRemove The names of the fields to be removed
|
|
* @throws DocumentException If called on a SQLite connection
|
|
*/
|
|
fun Connection.removeFieldsByJsonPath(tableName: String, path: String, toRemove: Collection<String>) =
|
|
RemoveFields.byJsonPath(tableName, path, toRemove, this)
|
|
|
|
// ~~~ DOCUMENT DELETION QUERIES ~~~
|
|
|
|
/**
|
|
* Delete a document by its ID
|
|
*
|
|
* @param tableName The name of the table from which documents should be deleted
|
|
* @param docId The ID of the document to be deleted
|
|
*/
|
|
fun <TKey> Connection.deleteById(tableName: String, docId: TKey) =
|
|
Delete.byId(tableName, docId, this)
|
|
|
|
/**
|
|
* Delete documents using a field comparison
|
|
*
|
|
* @param tableName The name of the table from which documents should be deleted
|
|
* @param fields The fields which should be compared
|
|
* @param howMatched How the fields should be matched
|
|
*/
|
|
fun Connection.deleteByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
|
Delete.byFields(tableName, fields, howMatched, this)
|
|
|
|
/**
|
|
* Delete documents using a JSON containment query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table from which documents should be deleted
|
|
* @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) =
|
|
Delete.byContains(tableName, criteria, this)
|
|
|
|
/**
|
|
* Delete documents using a JSON Path match query (PostgreSQL only)
|
|
*
|
|
* @param tableName The name of the table from which documents should be deleted
|
|
* @param path The JSON path comparison to match
|
|
* @throws DocumentException If called on a SQLite connection
|
|
*/
|
|
fun Connection.deleteByJsonPath(tableName: String, path: String) =
|
|
Delete.byJsonPath(tableName, path, this)
|