From 53dd31b91324b9abdc0ad57dba1cdd173fc157c0 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Sat, 29 Mar 2025 17:08:12 -0400 Subject: [PATCH] Add Scala Json wrapper --- src/core/src/main/kotlin/java/Json.kt | 20 +- src/scala/src/main/scala/Find.scala | 16 +- src/scala/src/main/scala/Json.scala | 341 ++++++++++++++++++ .../src/main/scala/extensions/package.scala | 118 +++++- 4 files changed, 470 insertions(+), 25 deletions(-) create mode 100644 src/scala/src/main/scala/Json.scala diff --git a/src/core/src/main/kotlin/java/Json.kt b/src/core/src/main/kotlin/java/Json.kt index cebc83e..a5b4c1e 100644 --- a/src/core/src/main/kotlin/java/Json.kt +++ b/src/core/src/main/kotlin/java/Json.kt @@ -26,7 +26,7 @@ object Json { Custom.jsonArray(FindQuery.all(tableName) + (orderBy?.let(::orderBy) ?: ""), listOf(), conn, Results::jsonFromData) /** - * Retrieve all documents in the given table + * Retrieve all documents in the given table (creates connection) * * @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) @@ -72,7 +72,7 @@ object Json { ) /** - * Retrieve a document by its ID + * Retrieve a document by its ID (creates connection) * * @param tableName The table from which the document should be retrieved * @param docId The ID of the document to retrieve @@ -114,7 +114,7 @@ object Json { } /** - * Retrieve documents using a field comparison, ordering results by the given fields + * Retrieve documents using a field comparison, ordering results by the given fields (creates connection) * * @param tableName The table from which documents should be retrieved * @param fields The fields which should be compared @@ -177,7 +177,8 @@ object Json { ) /** - * Retrieve documents using a JSON containment query, ordering results by the given fields (PostgreSQL only) + * Retrieve documents using a JSON containment query, ordering results by the given fields (PostgreSQL only; creates + * connection) * * @param tableName The table from which documents should be retrieved * @param criteria The object for which JSON containment should be checked @@ -226,7 +227,8 @@ object Json { ) /** - * Retrieve documents using a JSON Path match query, ordering results by the given fields (PostgreSQL only) + * Retrieve documents using a JSON Path match query, ordering results by the given fields (PostgreSQL only; creates + * connection) * * @param tableName The table from which documents should be retrieved * @param path The JSON path comparison to match @@ -284,7 +286,7 @@ object Json { } /** - * Retrieve the first document using a field comparison and optional ordering fields + * Retrieve the first document using a field comparison and optional ordering fields (creates connection) * * @param tableName The table from which documents should be retrieved * @param fields The fields which should be compared @@ -361,7 +363,8 @@ object Json { firstByContains(tableName, criteria, null, conn) /** - * Retrieve the first document using a JSON containment query and optional ordering fields (PostgreSQL only) + * Retrieve the first document using a JSON containment query and optional ordering fields (PostgreSQL only; creates + * connection) * * @param tableName The table from which documents should be retrieved * @param criteria The object for which JSON containment should be checked @@ -410,7 +413,8 @@ object Json { firstByJsonPath(tableName, path, null, conn) /** - * Retrieve the first document using a JSON Path match query and optional ordering fields (PostgreSQL only) + * Retrieve the first document using a JSON Path match query and optional ordering fields (PostgreSQL only; creates + * connection) * * @param tableName The table from which documents should be retrieved * @param path The JSON path comparison to match diff --git a/src/scala/src/main/scala/Find.scala b/src/scala/src/main/scala/Find.scala index 4335be7..8f6a2fc 100644 --- a/src/scala/src/main/scala/Find.scala +++ b/src/scala/src/main/scala/Find.scala @@ -44,7 +44,7 @@ object Find: * @return A list of documents from the given table * @throws DocumentException If no connection string has been set, or if query execution fails */ - def all[Doc](tableName: String, orderBy: Seq[Field[?]] = List())(using tag: ClassTag[Doc]): List[Doc] = + def all[Doc](tableName: String, orderBy: Seq[Field[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] = Using(Configuration.dbConn()) { conn => all[Doc](tableName, orderBy, conn) }.get /** @@ -61,7 +61,7 @@ object Find: Parameters.addFields(Field.equal(Configuration.idField, docId, ":id") :: Nil).toSeq, conn, Results.fromData) /** - * Retrieve a document by its ID (creates connection + * Retrieve a document by its ID (creates connection) * * @param tableName The table from which the document should be retrieved * @param docId The ID of the document to retrieve @@ -128,7 +128,7 @@ object Find: * @throws DocumentException If no connection string has been set, or if parameters are invalid */ def byFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, - orderBy: Seq[Field[?]] = List())(using tag: ClassTag[Doc]): List[Doc] = + orderBy: Seq[Field[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] = Using(Configuration.dbConn()) { conn => byFields[Doc](tableName, fields, howMatched, orderBy, conn) }.get /** @@ -168,7 +168,7 @@ object Find: * @return A list of documents matching the JSON containment query * @throws DocumentException If no connection string has been set, or if called on a SQLite connection */ - def byContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = List()) + def byContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): List[Doc] = Using(Configuration.dbConn()) { conn => byContains[Doc, A](tableName, criteria, orderBy, conn) }.get @@ -209,7 +209,7 @@ object Find: * @return A list of documents matching the JSON Path match query * @throws DocumentException If no connection string has been set, or if called on a SQLite connection */ - def byJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = List()) + def byJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): List[Doc] = Using(Configuration.dbConn()) { conn => byJsonPath[Doc](tableName, path, orderBy, conn) }.get @@ -283,7 +283,7 @@ object Find: * @throws DocumentException If no connection string has been set, or if parameters are invalid */ def firstByFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, - orderBy: Seq[Field[?]] = List())(using tag: ClassTag[Doc]): Option[Doc] = + orderBy: Seq[Field[?]] = Nil)(using tag: ClassTag[Doc]): Option[Doc] = Using(Configuration.dbConn()) { conn => firstByFields[Doc](tableName, fields, howMatched, orderBy, conn) }.get /** @@ -323,7 +323,7 @@ object Find: * @return An `Option` with the first document matching the JSON containment query if found * @throws DocumentException If no connection string has been set, or if called on a SQLite connection */ - def firstByContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = List()) + def firstByContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): Option[Doc] = Using(Configuration.dbConn()) { conn => firstByContains[Doc, A](tableName, criteria, orderBy, conn) }.get @@ -364,6 +364,6 @@ object Find: * @return An `Optional` item, with the first document matching the JSON Path match query if found * @throws DocumentException If no connection string has been set, or if called on a SQLite connection */ - def firstByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = List()) + def firstByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): Option[Doc] = Using(Configuration.dbConn()) { conn => firstByJsonPath[Doc](tableName, path, orderBy, conn) }.get diff --git a/src/scala/src/main/scala/Json.scala b/src/scala/src/main/scala/Json.scala new file mode 100644 index 0000000..d38c968 --- /dev/null +++ b/src/scala/src/main/scala/Json.scala @@ -0,0 +1,341 @@ +package solutions.bitbadger.documents.scala + +import solutions.bitbadger.documents.{Field, FieldMatch} +import solutions.bitbadger.documents.java.Json as CoreJson + +import java.sql.Connection +import _root_.scala.jdk.CollectionConverters.* + +object Json: + + /** + * 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) + * @param conn The connection over which documents should be retrieved + * @return A JSON array of documents from the given table + * @throws DocumentException If query execution fails + */ + def all(tableName: String, orderBy: Seq[Field[?]], conn: Connection): String = + CoreJson.all(tableName, orderBy.asJava, conn) + + /** + * 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 conn The connection over which documents should be retrieved + * @return A JSON array of documents from the given table + * @throws DocumentException If query execution fails + */ + def all(tableName: String, conn: Connection): String = + CoreJson.all(tableName, conn) + + /** + * Retrieve all documents in the given table (creates connection) + * + * @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 JSON array of documents from the given table + * @throws DocumentException If no connection string has been set, or if query execution fails + */ + def all(tableName: String, orderBy: Seq[Field[?]] = Nil): String = + CoreJson.all(tableName, orderBy.asJava) + + /** + * 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 conn The connection over which documents should be retrieved + * @return A JSON document if found, an empty JSON object if not found + * @throws DocumentException If no dialect has been configured + */ + def byId[Key](tableName: String, docId: Key, conn: Connection): String = + CoreJson.byId(tableName, docId, conn) + + /** + * Retrieve a document by its ID (creates connection) + * + * @param tableName The table from which the document should be retrieved + * @param docId The ID of the document to retrieve + * @return A JSON document if found, an empty JSON object if not found + * @throws DocumentException If no connection string has been set + */ + def byId[Key](tableName: String, docId: Key): String = + CoreJson.byId(tableName, docId) + + /** + * 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 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 JSON array of documents matching the field comparison + * @throws DocumentException If no dialect has been configured, or if parameters are invalid + */ + def byFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], orderBy: Seq[Field[?]], + conn: Connection): String = + CoreJson.byFields(tableName, fields.asJava, howMatched.orNull, orderBy.asJava, 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 + * @param conn The connection over which documents should be retrieved + * @return A JSON array of documents matching the field comparison + * @throws DocumentException If no dialect has been configured, or if parameters are invalid + */ + def byFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], conn: Connection): String = + CoreJson.byFields(tableName, fields.asJava, howMatched.orNull, conn) + + /** + * 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 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 JSON array of documents matching the field comparison + * @throws DocumentException If no dialect has been configured, or if parameters are invalid + */ + def byFields(tableName: String, fields: Seq[Field[?]], orderBy: Seq[Field[?]], conn: Connection): String = + CoreJson.byFields(tableName, fields.asJava, null, orderBy.asJava, conn) + + /** + * Retrieve documents using a field comparison, ordering results by the given fields (creates connection) + * + * @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 + * @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering) + * @return A JSON array of documents matching the field comparison + * @throws DocumentException If no connection string has been set, or if parameters are invalid + */ + def byFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, + orderBy: Seq[Field[?]] = Nil): String = + CoreJson.byFields(tableName, fields.asJava, howMatched.orNull, orderBy.asJava) + + /** + * 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 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 JSON array of documents matching the JSON containment query + * @throws DocumentException If called on a SQLite connection + */ + def byContains[A](tableName: String, criteria: A, orderBy: Seq[Field[?]], conn: Connection): String = + CoreJson.byContains(tableName, criteria, orderBy.asJava, 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 conn The connection over which documents should be retrieved + * @return A JSON array of documents matching the JSON containment query + * @throws DocumentException If called on a SQLite connection + */ + def byContains[A](tableName: String, criteria: A, conn: Connection): String = + CoreJson.byContains(tableName, criteria, conn) + + /** + * Retrieve documents using a JSON containment query, ordering results by the given fields (PostgreSQL only; creates + * connection) + * + * @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 A JSON array of documents matching the JSON containment query + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def byContains[A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil): String = + CoreJson.byContains(tableName, criteria, orderBy.asJava) + + /** + * 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 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 JSON array of documents matching the JSON Path match query + * @throws DocumentException If called on a SQLite connection + */ + def byJsonPath(tableName: String, path: String, orderBy: Seq[Field[?]], conn: Connection): String = + CoreJson.byJsonPath(tableName, path, orderBy.asJava, conn) + + /** + * 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 conn The connection over which documents should be retrieved + * @return A JSON array of documents matching the JSON Path match query + * @throws DocumentException If called on a SQLite connection + */ + def byJsonPath(tableName: String, path: String, conn: Connection): String = + CoreJson.byJsonPath(tableName, path, conn) + + /** + * Retrieve documents using a JSON Path match query, ordering results by the given fields (PostgreSQL only; creates + * connection) + * + * @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 JSON array of documents matching the JSON Path match query + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def byJsonPath(tableName: String, path: String, orderBy: Seq[Field[?]] = Nil): String = + CoreJson.byJsonPath(tableName, path, orderBy.asJava) + + /** + * Retrieve the first document using a field comparison and 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) + * @param conn The connection over which documents should be retrieved + * @return The first JSON document matching the field comparison if found, an empty JSON object otherwise + * @throws DocumentException If no dialect has been configured, or if parameters are invalid + */ + def firstByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], orderBy: Seq[Field[?]], + conn: Connection): String = + CoreJson.firstByFields(tableName, fields.asJava, howMatched.orNull, orderBy.asJava, conn) + + /** + * 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 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 JSON document matching the field comparison if found, an empty JSON object otherwise + * @throws DocumentException If no dialect has been configured, or if parameters are invalid + */ + def firstByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], + conn: Connection): String = + CoreJson.firstByFields(tableName, fields.asJava, howMatched.orNull, conn) + + /** + * Retrieve the first document using a field comparison and ordering fields + * + * @param tableName The table from which documents should be retrieved + * @param fields The fields which should be compared + * @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 JSON document matching the field comparison if found, an empty JSON object otherwise + * @throws DocumentException If no dialect has been configured, or if parameters are invalid + */ + def firstByFields(tableName: String, fields: Seq[Field[?]], orderBy: Seq[Field[?]], conn: Connection): String = + CoreJson.firstByFields(tableName, fields.asJava, null, orderBy.asJava, conn) + + /** + * 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 conn The connection over which documents should be retrieved + * @return The first JSON document matching the field comparison if found, an empty JSON object otherwise + * @throws DocumentException If no dialect has been configured, or if parameters are invalid + */ + def firstByFields(tableName: String, fields: Seq[Field[?]], conn: Connection): String = + CoreJson.firstByFields(tableName, fields.asJava, null, conn) + + /** + * Retrieve the first document using a field comparison and optional ordering fields (creates connection) + * + * @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 JSON document matching the field comparison if found, an empty JSON object otherwise + * @throws DocumentException If no connection string has been set, or if parameters are invalid + */ + def firstByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, + orderBy: Seq[Field[?]] = Nil): String = + CoreJson.firstByFields(tableName, fields.asJava, howMatched.orNull, orderBy.asJava) + + /** + * Retrieve the first document using a JSON containment query and 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) + * @param conn The connection over which documents should be retrieved + * @return The first JSON document matching the JSON containment query if found, an empty JSON object otherwise + * @throws DocumentException If called on a SQLite connection + */ + def firstByContains[A](tableName: String, criteria: A, orderBy: Seq[Field[?]], conn: Connection): String = + CoreJson.firstByContains(tableName, criteria, orderBy.asJava, conn) + + /** + * Retrieve the first document 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 conn The connection over which documents should be retrieved + * @return The first JSON document matching the JSON containment query if found, an empty JSON object otherwise + * @throws DocumentException If called on a SQLite connection + */ + def firstByContains[A](tableName: String, criteria: A, conn: Connection): String = + CoreJson.firstByContains(tableName, criteria, conn) + + /** + * Retrieve the first document using a JSON containment query and optional ordering fields (PostgreSQL only; creates + * connection) + * + * @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 JSON document matching the JSON containment query if found, an empty JSON object otherwise + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def firstByContains[A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil): String = + CoreJson.firstByContains(tableName, criteria, orderBy.asJava) + + /** + * Retrieve the first document using a JSON Path match query and 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) + * @param conn The connection over which documents should be retrieved + * @return The first JSON document matching the JSON Path match query if found, an empty JSON object otherwise + * @throws DocumentException If called on a SQLite connection + */ + def firstByJsonPath(tableName: String, path: String, orderBy: Seq[Field[?]], conn: Connection): String = + CoreJson.firstByJsonPath(tableName, path, orderBy.asJava, conn) + + /** + * Retrieve the first document 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 conn The connection over which documents should be retrieved + * @return The first JSON document matching the JSON Path match query if found, an empty JSON object otherwise + * @throws DocumentException If called on a SQLite connection + */ + def firstByJsonPath(tableName: String, path: String, conn: Connection): String = + CoreJson.firstByJsonPath(tableName, path, conn) + + /** + * Retrieve the first document using a JSON Path match query and optional ordering fields (PostgreSQL only; creates + * connection) + * + * @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 JSON document matching the JSON Path match query if found, an empty JSON object otherwise + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def firstByJsonPath(tableName: String, path: String, orderBy: Seq[Field[?]] = Nil): String = + CoreJson.firstByJsonPath(tableName, path, orderBy.asJava) diff --git a/src/scala/src/main/scala/extensions/package.scala b/src/scala/src/main/scala/extensions/package.scala index 75275f6..e51dd15 100644 --- a/src/scala/src/main/scala/extensions/package.scala +++ b/src/scala/src/main/scala/extensions/package.scala @@ -113,7 +113,7 @@ extension (conn: Connection) * @param parameters Parameters to use for the query * @throws DocumentException If parameters are invalid */ - def customNonQuery(query: String, parameters: Seq[Parameter[?]] = List()): Unit = + def customNonQuery(query: String, parameters: Seq[Parameter[?]] = Nil): Unit = Custom.nonQuery(query, parameters, conn) /** @@ -298,7 +298,7 @@ extension (conn: Connection) def existsByJsonPath(tableName: String, path: String): Boolean = Exists.byJsonPath(tableName, path, conn) - // ~~~ DOCUMENT RETRIEVAL QUERIES ~~~ + // ~~~ DOCUMENT RETRIEVAL QUERIES (Domain Objects) ~~~ /** * Retrieve all documents in the given table, ordering results by the optional given fields @@ -308,7 +308,7 @@ extension (conn: Connection) * @return A list of documents from the given table * @throws DocumentException If query execution fails */ - def findAll[Doc](tableName: String, orderBy: Seq[Field[?]] = List())(using tag: ClassTag[Doc]): List[Doc] = + def findAll[Doc](tableName: String, orderBy: Seq[Field[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] = Find.all[Doc](tableName, orderBy, conn) /** @@ -333,7 +333,7 @@ extension (conn: Connection) * @throws DocumentException If no dialect has been configured, or if parameters are invalid */ def findByFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, - orderBy: Seq[Field[?]] = List())(using tag: ClassTag[Doc]): List[Doc] = + orderBy: Seq[Field[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] = Find.byFields[Doc](tableName, fields, howMatched, orderBy, conn) /** @@ -346,7 +346,7 @@ extension (conn: Connection) * @return A list of documents matching the JSON containment query * @throws DocumentException If called on a SQLite connection */ - def findByContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = List()) + def findByContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): List[Doc] = Find.byContains[Doc, A](tableName, criteria, orderBy, conn) @@ -359,7 +359,7 @@ extension (conn: Connection) * @return A list of documents matching the JSON Path match query * @throws DocumentException If called on a SQLite connection */ - def findByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = List()) + def findByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): List[Doc] = Find.byJsonPath[Doc](tableName, path, orderBy, conn) @@ -374,7 +374,7 @@ extension (conn: Connection) * @throws DocumentException If no dialect has been configured, or if parameters are invalid */ def findFirstByFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, - orderBy: Seq[Field[?]] = List())(using tag: ClassTag[Doc]): Option[Doc] = + orderBy: Seq[Field[?]] = Nil)(using tag: ClassTag[Doc]): Option[Doc] = Find.firstByFields[Doc](tableName, fields, howMatched, orderBy, conn) /** @@ -386,7 +386,7 @@ extension (conn: Connection) * @return The first document matching the JSON containment query, or `None` if no matches are found * @throws DocumentException If called on a SQLite connection */ - def findFirstByContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = List()) + def findFirstByContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): Option[Doc] = Find.firstByContains[Doc, A](tableName, criteria, orderBy, conn) @@ -399,10 +399,110 @@ extension (conn: Connection) * @return The first document matching the JSON Path match query, or `None` if no matches are found * @throws DocumentException If called on a SQLite connection */ - def findFirstByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = List()) + def findFirstByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = Nil) (using tag: ClassTag[Doc]): Option[Doc] = Find.firstByJsonPath[Doc](tableName, path, orderBy, conn) + // ~~~ DOCUMENT RETRIEVAL QUERIES (Raw JSON) ~~~ + + /** + * Retrieve all documents in the given table + * + * @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 JSON array of documents from the given table + * @throws DocumentException If no connection string has been set, or if query execution fails + */ + def jsonAll(tableName: String, orderBy: Seq[Field[?]] = Nil): String = + Json.all(tableName, orderBy, 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 + * @return A JSON document if found, an empty JSON object if not found + * @throws DocumentException If no connection string has been set + */ + def jsonById[Key](tableName: String, docId: Key): String = + Json.byId(tableName, docId, conn) + + /** + * 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 howMatched How the fields should be matched + * @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering) + * @return A JSON array of documents matching the field comparison + * @throws DocumentException If no connection string has been set, or if parameters are invalid + */ + def jsonByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, + orderBy: Seq[Field[?]] = Nil): String = + Json.byFields(tableName, fields, howMatched, orderBy, 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 orderBy Fields by which the query should be ordered (optional, defaults to no ordering) + * @return A JSON array of documents matching the JSON containment query + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def jsonByContains[A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil): String = + Json.byContains(tableName, criteria, orderBy, 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 orderBy Fields by which the query should be ordered (optional, defaults to no ordering) + * @return A JSON array of documents matching the JSON Path match query + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def jsonByJsonPath(tableName: String, path: String, orderBy: Seq[Field[?]] = Nil): String = + Json.byJsonPath(tableName, path, orderBy, 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 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 JSON document matching the field comparison if found, an empty JSON object otherwise + * @throws DocumentException If no connection string has been set, or if parameters are invalid + */ + def jsonFirstByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None, + orderBy: Seq[Field[?]] = Nil): String = + Json.firstByFields(tableName, fields, howMatched, orderBy, 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 orderBy Fields by which the query should be ordered (optional, defaults to no ordering) + * @return The first JSON document matching the JSON containment query if found, an empty JSON object otherwise + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def jsonFirstByContains[A](tableName: String, criteria: A, orderBy: Seq[Field[?]] = Nil): String = + Json.firstByContains(tableName, criteria, orderBy, 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 orderBy Fields by which the query should be ordered (optional, defaults to no ordering) + * @return The first JSON document matching the JSON Path match query if found, an empty JSON object otherwise + * @throws DocumentException If no connection string has been set, or if called on a SQLite connection + */ + def jsonFirstByJsonPath(tableName: String, path: String, orderBy: Seq[Field[?]] = Nil): String = + Json.firstByJsonPath(tableName, path, orderBy, conn) + // ~~~ DOCUMENT PATCH (PARTIAL UPDATE) QUERIES ~~~ /**