diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..724dd10
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documents.iml b/documents.iml
new file mode 100644
index 0000000..ce12650
--- /dev/null
+++ b/documents.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/integration-test/kotlin/CustomSQLiteIT.kt b/src/integration-test/kotlin/CustomSQLiteIT.kt
new file mode 100644
index 0000000..c15ff76
--- /dev/null
+++ b/src/integration-test/kotlin/CustomSQLiteIT.kt
@@ -0,0 +1,43 @@
+package solutions.bitbadger.documents
+
+import kotlinx.serialization.Serializable
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+import solutions.bitbadger.documents.query.Definition
+import solutions.bitbadger.documents.query.Find
+import kotlin.test.assertEquals
+
+
+class CustomSQLiteIT {
+
+ private val tbl = "test_table";
+
+ @BeforeEach
+ fun setUp() {
+ Configuration.connectionString = "jdbc:sqlite:memory"
+ }
+
+ /**
+ * Reset the dialect
+ */
+ @AfterEach
+ fun cleanUp() {
+ Configuration.dialectValue = null
+ }
+
+ @Test
+ @DisplayName("list succeeds with empty list")
+ fun listEmpty() {
+ Configuration.dbConn().use { conn ->
+ conn.customNonQuery(Definition.ensureTable(tbl), listOf())
+ conn.customNonQuery(Definition.ensureKey(tbl, Dialect.SQLITE), listOf())
+ val result = conn.customList(Find.all(tbl), listOf(), Results::fromData)
+ assertEquals(0, result.size, "There should have been no results")
+ }
+ }
+}
+
+@Serializable
+data class TestDocument(val id: String)
diff --git a/src/main/kotlin/ConnectionExtensions.kt b/src/main/kotlin/ConnectionExtensions.kt
index 51f7f93..553107b 100644
--- a/src/main/kotlin/ConnectionExtensions.kt
+++ b/src/main/kotlin/ConnectionExtensions.kt
@@ -11,11 +11,9 @@ import java.sql.ResultSet
* @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>,
- mapFunc: (ResultSet) -> TDoc): List =
- Parameters.apply(this, query, parameters).use { stmt ->
- Results.toCustomList(stmt, mapFunc)
- }
+inline fun Connection.customList(
+ query: String, parameters: Collection>, mapFunc: (ResultSet) -> TDoc
+) = Custom.list(query, parameters, this, mapFunc)
/**
* Execute a query that returns one or no results
@@ -25,9 +23,9 @@ inline fun Connection.customList(query: String, parameters: Colle
* @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>,
- mapFunc: (ResultSet) -> TDoc): TDoc? =
- this.customList("$query LIMIT 1", parameters, mapFunc).singleOrNull()
+inline fun Connection.customSingle(
+ query: String, parameters: Collection>, mapFunc: (ResultSet) -> TDoc
+) = Custom.single(query, parameters, this, mapFunc)
/**
* Execute a query that returns no results
@@ -35,6 +33,19 @@ inline fun Connection.customSingle(query: String, parameters: Col
* @param query The query to retrieve the results
* @param parameters Parameters to use for the query
*/
-fun Connection.customNonQuery(query: String, parameters: Collection>) {
- Parameters.apply(this, query, parameters).use { it.executeUpdate() }
-}
+fun Connection.customNonQuery(query: String, parameters: Collection>) =
+ 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>,
+ mapFunc: (ResultSet) -> T & Any
+) = Custom.scalar(query, parameters, this, mapFunc)
diff --git a/src/main/kotlin/Custom.kt b/src/main/kotlin/Custom.kt
new file mode 100644
index 0000000..87aa352
--- /dev/null
+++ b/src/main/kotlin/Custom.kt
@@ -0,0 +1,110 @@
+package solutions.bitbadger.documents
+
+import java.sql.Connection
+import java.sql.ResultSet
+
+/**
+ * Custom query execution functions
+ */
+object Custom {
+
+ /**
+ * 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 conn The connection over which the query should be executed
+ * @param mapFunc The mapping function between the document and the domain item
+ * @return A list of results for the given query
+ */
+ inline fun list(
+ query: String, parameters: Collection>, conn: Connection, mapFunc: (ResultSet) -> TDoc
+ ) = Parameters.apply(conn, query, parameters).use { Results.toCustomList(it, mapFunc) }
+
+ /**
+ * Execute a query that returns a list of results (creates connection)
+ *
+ * @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 list(
+ query: String, parameters: Collection>, mapFunc: (ResultSet) -> TDoc
+ ) = Configuration.dbConn().use { list(query, parameters, it, 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 conn The connection over which the query should be executed
+ * @param mapFunc The mapping function between the document and the domain item
+ * @return The document if one matches the query, `null` otherwise
+ */
+ inline fun single(
+ query: String, parameters: Collection>, conn: Connection, mapFunc: (ResultSet) -> TDoc
+ ) = list("$query LIMIT 1", parameters, conn, mapFunc).singleOrNull()
+
+ /**
+ * 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 single(
+ query: String, parameters: Collection>, mapFunc: (ResultSet) -> TDoc
+ ) = Configuration.dbConn().use { single(query, parameters, it, mapFunc) }
+
+ /**
+ * Execute a query that returns no results
+ *
+ * @param query The query to retrieve the results
+ * @param conn The connection over which the query should be executed
+ * @param parameters Parameters to use for the query
+ */
+ fun nonQuery(query: String, parameters: Collection>, conn: Connection) {
+ Parameters.apply(conn, query, parameters).use { it.executeUpdate() }
+ }
+
+ /**
+ * Execute a query that returns no results
+ *
+ * @param query The query to retrieve the results
+ * @param parameters Parameters to use for the query
+ */
+ fun nonQuery(query: String, parameters: Collection>) =
+ Configuration.dbConn().use { nonQuery(query, parameters, it) }
+
+ /**
+ * 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 conn The connection over which the query should be executed
+ * @param mapFunc The mapping function between the document and the domain item
+ * @return The scalar value from the query
+ */
+ inline fun scalar(
+ query: String, parameters: Collection>, conn: Connection, mapFunc: (ResultSet) -> T & Any
+ ) = Parameters.apply(conn, query, parameters).use { stmt ->
+ stmt.executeQuery().use { rs ->
+ rs.next()
+ mapFunc(rs)
+ }
+ }
+
+ /**
+ * 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 scalar(
+ query: String, parameters: Collection>, mapFunc: (ResultSet) -> T & Any
+ ) = Configuration.dbConn().use { scalar(query, parameters, it, mapFunc) }
+}