package solutions.bitbadger.documents 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 Connection.customList( query: String, parameters: Collection> = listOf(), mapFunc: (ResultSet) -> 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 Connection.customSingle( query: String, parameters: Collection> = listOf(), mapFunc: (ResultSet) -> 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> = 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 Connection.customScalar( query: String, parameters: Collection> = listOf(), mapFunc: (ResultSet) -> T & Any ) = 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) = 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) = 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) = 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 Connection.insert(tableName: String, document: TDoc) = Document.insert(tableName, 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>, 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 Connection.countByContains(tableName: String, criteria: T) = 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 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>, 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 Connection.existsByContains(tableName: String, criteria: T) = 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 * * @param tableName The table from which documents should be retrieved * @return A list of documents from the given table */ inline fun Connection.findAll(tableName: String) = Find.all(tableName, this) /** * Retrieve all documents in the given table * * @param tableName The table from which documents should be retrieved * @return A list of documents from the given table */ inline fun Connection.findAll(tableName: String, orderBy: Collection>) = Find.all(tableName, orderBy, 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 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>, 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 Connection.deleteByContains(tableName: String, criteria: T) = 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)