Initial Development (#1)
This project now contains: - A generic JVM document library (with Kotlin extensions on the JDBC `Connection` object) - A Groovy library which adds extension methods to the `Connection` object - A Scala library, which uses native Scala collections and adds Scala-style extension methods to the `Connection` object - A Kotlin library which uses `kotlinx.serialization` (no reflection, reified generic types) along with `Connection` extensions Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
167
src/scala/pom.xml
Normal file
167
src/scala/pom.xml
Normal file
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>solutions.bitbadger</groupId>
|
||||
<artifactId>documents</artifactId>
|
||||
<version>1.0.0-RC1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>solutions.bitbadger.documents</groupId>
|
||||
<artifactId>scala</artifactId>
|
||||
|
||||
<name>${project.groupId}:${project.artifactId}</name>
|
||||
<description>Expose a document store interface for PostgreSQL and SQLite (Scala Library)</description>
|
||||
<url>https://relationaldocs.bitbadger.solutions/jvm/</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<url>https://www.opensource.org/licenses/mit-license.php</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Daniel J. Summers</name>
|
||||
<email>daniel@bitbadger.solutions</email>
|
||||
<organization>Bit Badger Solutions</organization>
|
||||
<organizationUrl>https://bitbadger.solutions</organizationUrl>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:https://git.bitbadger.solutions/bit-badger/solutions.bitbadger.documents.git</connection>
|
||||
<developerConnection>scm:git:https://git.bitbadger.solutions/bit-badger/solutions.bitbadger.documents.git</developerConnection>
|
||||
<url>https://git.bitbadger.solutions/bit-badger/solutions.bitbadger.documents</url>
|
||||
</scm>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/src/main/scala</sourceDirectory>
|
||||
<testSourceDirectory>${project.basedir}/src/test/scala</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>${sourcePlugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
<version>4.9.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>doc-jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<args>-nobootcp</args>
|
||||
<scaladocClassName>dotty.tools.scaladoc.Main</scaladocClassName>
|
||||
<sourceDir>${project.build.outputDirectory}</sourceDir>
|
||||
<includes>
|
||||
<include>**/*.tasty</include>
|
||||
</includes>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scaladoc_3</artifactId>
|
||||
<version>${scala.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${failsafe.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- <plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>${sourcePlugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin> -->
|
||||
<plugin>
|
||||
<groupId>org.sonatype.central</groupId>
|
||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||
<version>0.7.0</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<deploymentName>Deployment-scala-${project.version}</deploymentName>
|
||||
<publishingServerId>central</publishingServerId>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>solutions.bitbadger.documents</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala3-library_3</artifactId>
|
||||
<version>${scala.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
9
src/scala/scala.iml
Normal file
9
src/scala/scala.iml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="AdditionalModuleElements">
|
||||
<content url="file://$MODULE_DIR$" dumb="true">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/scala" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/scala" isTestSource="true" />
|
||||
</content>
|
||||
</component>
|
||||
</module>
|
||||
105
src/scala/src/main/scala/Count.scala
Normal file
105
src/scala/src/main/scala/Count.scala
Normal file
@@ -0,0 +1,105 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.java.Count as CoreCount
|
||||
|
||||
import java.sql.Connection
|
||||
|
||||
import _root_.scala.jdk.CollectionConverters.*
|
||||
|
||||
/**
|
||||
* Functions to count documents
|
||||
*/
|
||||
object Count:
|
||||
|
||||
/**
|
||||
* Count all documents in the table
|
||||
*
|
||||
* @param tableName The name of the table in which documents should be counted
|
||||
* @param conn The connection over which documents should be counted
|
||||
* @return A count of the documents in the table
|
||||
* @throws DocumentException If any dependent process does
|
||||
*/
|
||||
def all(tableName: String, conn: Connection): Long =
|
||||
CoreCount.all(tableName, conn)
|
||||
|
||||
/**
|
||||
* Count all documents in the table (creates connection)
|
||||
*
|
||||
* @param tableName The name of the table in which documents should be counted
|
||||
* @return A count of the documents in the table
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def all(tableName: String): Long =
|
||||
CoreCount.all(tableName)
|
||||
|
||||
/**
|
||||
* 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 (optional, default `ALL`)
|
||||
* @param conn The connection on which the deletion should be executed
|
||||
* @return A count of the matching documents in the table
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def byFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], conn: Connection): Long =
|
||||
CoreCount.byFields(tableName, fields.asJava, howMatched.orNull, conn)
|
||||
|
||||
/**
|
||||
* Count documents using a field comparison (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def byFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None): Long =
|
||||
CoreCount.byFields(tableName, fields.asJava, howMatched.orNull)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the count should be executed
|
||||
* @return A count of the matching documents in the table
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A, conn: Connection): Long =
|
||||
CoreCount.byContains(tableName, criteria, conn)
|
||||
|
||||
/**
|
||||
* Count documents using a JSON containment query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A): Long =
|
||||
CoreCount.byContains(tableName, criteria)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the count should be executed
|
||||
* @return A count of the matching documents in the table
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String, conn: Connection): Long =
|
||||
CoreCount.byJsonPath(tableName, path, conn)
|
||||
|
||||
/**
|
||||
* Count documents using a JSON Path match query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String): Long =
|
||||
CoreCount.byJsonPath(tableName, path)
|
||||
360
src/scala/src/main/scala/Custom.scala
Normal file
360
src/scala/src/main/scala/Custom.scala
Normal file
@@ -0,0 +1,360 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Configuration, Parameter}
|
||||
|
||||
import java.io.PrintWriter
|
||||
import java.sql.{Connection, ResultSet}
|
||||
import scala.reflect.ClassTag
|
||||
import scala.util.Using
|
||||
|
||||
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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def list[Doc](query: String, parameters: Seq[Parameter[?]], conn: Connection,
|
||||
mapFunc: (ResultSet, ClassTag[Doc]) => Doc)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Using(Parameters.apply(conn, query, parameters)) { stmt => Results.toCustomList[Doc](stmt, mapFunc) }.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns a list of results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def list[Doc](query: String, conn: Connection, mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
list(query, Nil, conn, 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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def list[Doc](query: String, parameters: Seq[Parameter[?]], mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => list[Doc](query, parameters, conn, mapFunc) }.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns a list of results (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return A list of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def list[Doc](query: String, mapFunc: (ResultSet, ClassTag[Doc]) => Doc)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
list(query, List(), mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array 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 to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonArray(query: String, parameters: Seq[Parameter[?]], conn: Connection, mapFunc: ResultSet => String): String =
|
||||
Using(Parameters.apply(conn, query, parameters)) { stmt => Results.toJsonArray(stmt, mapFunc) }.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array of results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param conn The connection over which the query should be executed
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonArray(query: String, conn: Connection, mapFunc: ResultSet => String): String =
|
||||
jsonArray(query, Nil, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array 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 to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonArray(query: String, parameters: Seq[Parameter[?]], mapFunc: ResultSet => String): String =
|
||||
Using(Configuration.dbConn()) { conn => jsonArray(query, parameters, conn, mapFunc) }.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array of results (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonArray(query: String, mapFunc: ResultSet => String): String =
|
||||
jsonArray(query, Nil, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that writes a JSON array of results to the given `PrintWriter`
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param parameters Parameters to use for the query
|
||||
* @param writer The writer to which the results should be written
|
||||
* @param conn The connection over which the query should be executed
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def writeJsonArray(query: String, parameters: Seq[Parameter[?]], writer: PrintWriter, conn: Connection,
|
||||
mapFunc: ResultSet => String): Unit =
|
||||
Using(Parameters.apply(conn, query, parameters)) { stmt => Results.writeJsonArray(writer, stmt, mapFunc) }
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array of results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param writer The writer to which the results should be written
|
||||
* @param conn The connection over which the query should be executed
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def writeJsonArray(query: String, conn: Connection, writer: PrintWriter, mapFunc: ResultSet => String): Unit =
|
||||
writeJsonArray(query, Nil, writer, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array of results (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param parameters Parameters to use for the query
|
||||
* @param writer The writer to which the results should be written
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def writeJsonArray(query: String, parameters: Seq[Parameter[?]], writer: PrintWriter,
|
||||
mapFunc: ResultSet => String): Unit =
|
||||
Using(Configuration.dbConn()) { conn => writeJsonArray(query, parameters, writer, conn, mapFunc) }
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array of results (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param writer The writer to which the results should be written
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def writeJsonArray(query: String, writer: PrintWriter, mapFunc: ResultSet => String): Unit =
|
||||
writeJsonArray(query, Nil, writer, 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 An `Option` value, with the document if one matches the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def single[Doc](query: String, parameters: Seq[Parameter[?]], conn: Connection,
|
||||
mapFunc: (ResultSet, ClassTag[Doc]) => Doc)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
list[Doc](s"$query LIMIT 1", parameters, conn, mapFunc).headOption
|
||||
|
||||
/**
|
||||
* Execute a query that returns one or no results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param conn The connection over which the query should be executed
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return An `Option` value, with the document if one matches the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def single[Doc](query: String, conn: Connection, mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
list[Doc](s"$query LIMIT 1", List(), conn, mapFunc).headOption
|
||||
|
||||
/**
|
||||
* Execute a query that returns one or no 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 An `Option` value, with the document if one matches the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def single[Doc](query: String, parameters: Seq[Parameter[?]], mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => single[Doc](query, parameters, conn, mapFunc) }.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns one or no results (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return An `Option` value, with the document if one matches the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def single[Doc](query: String, mapFunc: (ResultSet, ClassTag[Doc]) => Doc)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
single[Doc](query, List(), mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns JSON for one or no documents
|
||||
*
|
||||
* @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 JSON for the document if found, an empty object (`{}`) if not
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonSingle(query: String, parameters: Seq[Parameter[?]], conn: Connection, mapFunc: ResultSet => String): String =
|
||||
val result = jsonArray("$query LIMIT 1", parameters, conn, mapFunc)
|
||||
result match
|
||||
case "[]" => "{}"
|
||||
case _ => result.substring(1, result.length - 1)
|
||||
|
||||
/**
|
||||
* Execute a query that returns JSON for one or no documents
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @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 JSON for the document if found, an empty object (`{}`) if not
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonSingle(query: String, conn: Connection, mapFunc: ResultSet => String): String =
|
||||
jsonSingle(query, Nil, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns JSON for one or no documents (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 The JSON for the document if found, an empty object (`{}`) if not
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonSingle(query: String, parameters: Seq[Parameter[?]], mapFunc: ResultSet => String): String =
|
||||
Using(Configuration.dbConn()) { conn => jsonSingle(query, parameters, conn, mapFunc) }.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns JSON for one or no documents (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return The JSON for the document if found, an empty object (`{}`) if not
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def jsonSingle(query: String, mapFunc: ResultSet => String): String =
|
||||
jsonSingle(query, Nil, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns 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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def nonQuery(query: String, parameters: Seq[Parameter[?]], conn: Connection): Unit =
|
||||
Using(Parameters.apply(conn, query, parameters)) { stmt => stmt.executeUpdate() }
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def nonQuery(query: String, conn: Connection): Unit =
|
||||
nonQuery(query, List(), conn)
|
||||
|
||||
/**
|
||||
* Execute a query that returns no results (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param parameters Parameters to use for the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def nonQuery(query: String, parameters: Seq[Parameter[?]]): Unit =
|
||||
Using(Configuration.dbConn()) { conn => nonQuery(query, parameters, conn) }
|
||||
|
||||
/**
|
||||
* Execute a query that returns no results (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def nonQuery(query: String): Unit =
|
||||
nonQuery(query, List())
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def scalar[A](query: String, parameters: Seq[Parameter[?]], conn: Connection, mapFunc: (ResultSet, ClassTag[A]) => A)
|
||||
(using tag: ClassTag[A]): A =
|
||||
Using(Parameters.apply(conn, query, parameters)) { stmt =>
|
||||
Using(stmt.executeQuery()) { rs =>
|
||||
rs.next()
|
||||
mapFunc(rs, tag)
|
||||
}.get
|
||||
}.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns a scalar result
|
||||
*
|
||||
* @param query The query to retrieve the result
|
||||
* @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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def scalar[A](query: String, conn: Connection, mapFunc: (ResultSet, ClassTag[A]) => A)(using tag: ClassTag[A]): A =
|
||||
scalar[A](query, List(), conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a scalar result (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def scalar[A](query: String, parameters: Seq[Parameter[?]], mapFunc: (ResultSet, ClassTag[A]) => A)
|
||||
(using tag: ClassTag[A]): A =
|
||||
Using(Configuration.dbConn()) { conn => scalar[A](query, parameters, conn, mapFunc) }.get
|
||||
|
||||
/**
|
||||
* Execute a query that returns a scalar result (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the result
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return The scalar value from the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def scalar[A](query: String, mapFunc: (ResultSet, ClassTag[A]) => A)(using tag: ClassTag[A]): A =
|
||||
scalar[A](query, List(), mapFunc)
|
||||
72
src/scala/src/main/scala/Definition.scala
Normal file
72
src/scala/src/main/scala/Definition.scala
Normal file
@@ -0,0 +1,72 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.DocumentIndex
|
||||
import solutions.bitbadger.documents.java.Definition as CoreDefinition
|
||||
|
||||
import java.sql.Connection
|
||||
import _root_.scala.jdk.CollectionConverters.*
|
||||
|
||||
object Definition:
|
||||
|
||||
/**
|
||||
* Create a document table if necessary
|
||||
*
|
||||
* @param tableName The table whose existence should be ensured (may include schema)
|
||||
* @param conn The connection on which the query should be executed
|
||||
* @throws DocumentException If the dialect is not configured
|
||||
*/
|
||||
def ensureTable(tableName: String, conn: Connection): Unit =
|
||||
CoreDefinition.ensureTable(tableName, conn)
|
||||
|
||||
/**
|
||||
* Create a document table if necessary
|
||||
*
|
||||
* @param tableName The table whose existence should be ensured (may include schema)
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def ensureTable(tableName: String): Unit =
|
||||
CoreDefinition.ensureTable(tableName)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the query should be executed
|
||||
* @throws DocumentException If any dependent process does
|
||||
*/
|
||||
def ensureFieldIndex(tableName: String, indexName: String, fields: Seq[String], conn: Connection): Unit =
|
||||
CoreDefinition.ensureFieldIndex(tableName, indexName, fields.asJava, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If no connection string has been set, or if any dependent process does
|
||||
*/
|
||||
def ensureFieldIndex(tableName: String, indexName: String, fields: Seq[String]): Unit =
|
||||
CoreDefinition.ensureFieldIndex(tableName, indexName, fields.asJava)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the query should be executed
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def ensureDocumentIndex(tableName: String, indexType: DocumentIndex, conn: Connection): Unit =
|
||||
CoreDefinition.ensureDocumentIndex(tableName, indexType, conn)
|
||||
|
||||
/**
|
||||
* 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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def ensureDocumentIndex(tableName: String, indexType: DocumentIndex): Unit =
|
||||
CoreDefinition.ensureDocumentIndex(tableName, indexType)
|
||||
98
src/scala/src/main/scala/Delete.scala
Normal file
98
src/scala/src/main/scala/Delete.scala
Normal file
@@ -0,0 +1,98 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.java.Delete as CoreDelete
|
||||
|
||||
import java.sql.Connection
|
||||
import _root_.scala.jdk.CollectionConverters.*
|
||||
|
||||
/**
|
||||
* Functions to delete documents
|
||||
*/
|
||||
object Delete:
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the deletion should be executed
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def byId[Key](tableName: String, docId: Key, conn: Connection): Unit =
|
||||
CoreDelete.byId(tableName, docId, conn)
|
||||
|
||||
/**
|
||||
* Delete a document by its ID (creates connection)
|
||||
*
|
||||
* @param tableName The name of the table from which documents should be deleted
|
||||
* @param docId The ID of the document to be deleted
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def byId[Key](tableName: String, docId: Key): Unit =
|
||||
CoreDelete.byId(tableName, docId)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the deletion should be executed
|
||||
* @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): Unit =
|
||||
CoreDelete.byFields(tableName, fields.asJava, howMatched.orNull, conn)
|
||||
|
||||
/**
|
||||
* Delete documents using a field comparison (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @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): Unit =
|
||||
CoreDelete.byFields(tableName, fields.asJava, howMatched.orNull)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the deletion should be executed
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A, conn: Connection): Unit =
|
||||
CoreDelete.byContains(tableName, criteria, conn)
|
||||
|
||||
/**
|
||||
* Delete documents using a JSON containment query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A): Unit =
|
||||
CoreDelete.byContains(tableName, criteria)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the deletion should be executed
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String, conn: Connection): Unit =
|
||||
CoreDelete.byJsonPath(tableName, path, conn)
|
||||
|
||||
/**
|
||||
* Delete documents using a JSON Path match query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @param tableName The name of the table from which documents should be deleted
|
||||
* @param path The JSON path comparison to match
|
||||
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String): Unit =
|
||||
CoreDelete.byJsonPath(tableName, path)
|
||||
72
src/scala/src/main/scala/Document.scala
Normal file
72
src/scala/src/main/scala/Document.scala
Normal file
@@ -0,0 +1,72 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.java.Document as CoreDocument
|
||||
|
||||
import java.sql.Connection
|
||||
|
||||
object Document:
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the query should be executed
|
||||
* @throws DocumentException If IDs are misconfigured, or if the database command fails
|
||||
*/
|
||||
def insert[Doc](tableName: String, document: Doc, conn: Connection): Unit =
|
||||
CoreDocument.insert(tableName, document, conn)
|
||||
|
||||
/**
|
||||
* Insert a new document (creates connection)
|
||||
*
|
||||
* @param tableName The table into which the document should be inserted (may include schema)
|
||||
* @param document The document to be inserted
|
||||
* @throws DocumentException If IDs are misconfigured, or if the database command fails
|
||||
*/
|
||||
def insert[Doc](tableName: String, document: Doc): Unit =
|
||||
CoreDocument.insert(tableName, document)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the query should be executed
|
||||
* @throws DocumentException If the database command fails
|
||||
*/
|
||||
def save[Doc](tableName: String, document: Doc, conn: Connection): Unit =
|
||||
CoreDocument.save(tableName, document, conn)
|
||||
|
||||
/**
|
||||
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert"; creates connection)
|
||||
*
|
||||
* @param tableName The table in which the document should be saved (may include schema)
|
||||
* @param document The document to be saved
|
||||
* @throws DocumentException If the database command fails
|
||||
*/
|
||||
def save[Doc](tableName: String, document: Doc): Unit =
|
||||
CoreDocument.save(tableName, document)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the query should be executed
|
||||
* @throws DocumentException If no dialect has been configured, or if the database command fails
|
||||
*/
|
||||
def update[Key, Doc](tableName: String, docId: Key, document: Doc, conn: Connection): Unit =
|
||||
CoreDocument.update(tableName, docId, document, conn)
|
||||
|
||||
/**
|
||||
* Update (replace) a document by its ID (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If no dialect has been configured, or if the database command fails
|
||||
*/
|
||||
def update[Key, Doc](tableName: String, docId: Key, document: Doc): Unit =
|
||||
CoreDocument.update(tableName, docId, document)
|
||||
106
src/scala/src/main/scala/Exists.scala
Normal file
106
src/scala/src/main/scala/Exists.scala
Normal file
@@ -0,0 +1,106 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.java.Exists as CoreExists
|
||||
|
||||
import java.sql.Connection
|
||||
import _root_.scala.jdk.CollectionConverters.*
|
||||
|
||||
/**
|
||||
* Functions to determine whether documents exist
|
||||
*/
|
||||
object Exists:
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the existence check should be executed
|
||||
* @return True if the document exists, false if not
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def byId[Key](tableName: String, docId: Key, conn: Connection): Boolean =
|
||||
CoreExists.byId(tableName, docId, conn)
|
||||
|
||||
/**
|
||||
* Determine a document's existence by its ID (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def byId[Key](tableName: String, docId: Key): Boolean =
|
||||
CoreExists.byId(tableName, docId)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the existence check should be executed
|
||||
* @return True if any matching documents exist, false if not
|
||||
* @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): Boolean =
|
||||
CoreExists.byFields(tableName, fields.asJava, howMatched.orNull, conn)
|
||||
|
||||
/**
|
||||
* Determine document existence using a field comparison (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @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): Boolean =
|
||||
CoreExists.byFields(tableName, fields.asJava, howMatched.orNull)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the existence check should be executed
|
||||
* @return True if any matching documents exist, false if not
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A, conn: Connection): Boolean =
|
||||
CoreExists.byContains(tableName, criteria, conn)
|
||||
|
||||
/**
|
||||
* Determine document existence using a JSON containment query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A): Boolean =
|
||||
CoreExists.byContains(tableName, criteria)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the existence check should be executed
|
||||
* @return True if any matching documents exist, false if not
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String, conn: Connection): Boolean =
|
||||
CoreExists.byJsonPath(tableName, path, conn)
|
||||
|
||||
/**
|
||||
* Determine document existence using a JSON Path match query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String): Boolean =
|
||||
CoreExists.byJsonPath(tableName, path)
|
||||
369
src/scala/src/main/scala/Find.scala
Normal file
369
src/scala/src/main/scala/Find.scala
Normal file
@@ -0,0 +1,369 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Configuration, Field, FieldMatch, Parameter, ParameterType}
|
||||
import solutions.bitbadger.documents.query.{FindQuery, QueryUtils}
|
||||
|
||||
import java.sql.Connection
|
||||
import scala.reflect.ClassTag
|
||||
import scala.jdk.CollectionConverters.*
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* Functions to find and retrieve documents
|
||||
*/
|
||||
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 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
|
||||
* @throws DocumentException If query execution fails
|
||||
*/
|
||||
def all[Doc](tableName: String, orderBy: Seq[Field[?]], conn: Connection)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Custom.list[Doc](FindQuery.all(tableName) + QueryUtils.orderBy(orderBy.asJava), conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 list of documents from the given table
|
||||
* @throws DocumentException If query execution fails
|
||||
*/
|
||||
def all[Doc](tableName: String, conn: Connection)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
all[Doc](tableName, List(), 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 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[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => all[Doc](tableName, orderBy, conn) }.get
|
||||
|
||||
/**
|
||||
* 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 An `Option` with the document if it is found
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def byId[Key, Doc](tableName: String, docId: Key, conn: Connection)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Custom.single[Doc](FindQuery.byId(tableName, docId),
|
||||
Parameters.addFields(Field.equal(Configuration.idField, docId, ":id") :: Nil).toSeq, conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 An `Option` with the document if it is found
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def byId[Key, Doc](tableName: String, docId: Key)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => byId[Key, Doc](tableName, docId, conn) }.get
|
||||
|
||||
/**
|
||||
* 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 list of documents matching the field comparison
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def byFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], orderBy: Seq[Field[?]],
|
||||
conn: Connection)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
val named = Parameters.nameFields(fields)
|
||||
Custom.list[Doc](
|
||||
FindQuery.byFields(tableName, named.asJava, howMatched.orNull) + QueryUtils.orderBy(orderBy.asJava),
|
||||
Parameters.addFields(named).toSeq, conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 list of documents matching the field comparison
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def byFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
byFields[Doc](tableName, fields, howMatched, List(), 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 list of documents matching the field comparison
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def byFields[Doc](tableName: String, fields: Seq[Field[?]], orderBy: Seq[Field[?]], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
byFields[Doc](tableName, fields, None, orderBy, 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 list of documents matching the field comparison
|
||||
* @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[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => byFields[Doc](tableName, fields, howMatched, orderBy, conn) }.get
|
||||
|
||||
/**
|
||||
* 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 list of documents matching the JSON containment query
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Custom.list[Doc](FindQuery.byContains(tableName) + QueryUtils.orderBy(orderBy.asJava),
|
||||
Parameters.json(":criteria", criteria) :: Nil, conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 list of documents matching the JSON containment query
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byContains[Doc, A](tableName: String, criteria: A, conn: Connection)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
byContains[Doc, A](tableName, criteria, List(), 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 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[?]] = Nil)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => byContains[Doc, A](tableName, criteria, orderBy, conn) }.get
|
||||
|
||||
/**
|
||||
* 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 list of documents matching the JSON Path match query
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Custom.list[Doc](FindQuery.byJsonPath(tableName) + QueryUtils.orderBy(orderBy.asJava),
|
||||
Parameter(":path", ParameterType.STRING, path) :: Nil, conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 list of documents matching the JSON Path match query
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath[Doc](tableName: String, path: String, conn: Connection)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
byJsonPath[Doc](tableName, path, List(), 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 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[?]] = Nil)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => byJsonPath[Doc](tableName, path, orderBy, conn) }.get
|
||||
|
||||
/**
|
||||
* 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 An `Option` with the first document matching the field comparison if found
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def firstByFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch],
|
||||
orderBy: Seq[Field[?]], conn: Connection)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
val named = Parameters.nameFields(fields)
|
||||
Custom.single[Doc](
|
||||
FindQuery.byFields(tableName, named.asJava, howMatched.orNull) + QueryUtils.orderBy(orderBy.asJava),
|
||||
Parameters.addFields(named).toSeq, conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 An `Option` with the first document matching the field comparison if found
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def firstByFields[Doc](tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
firstByFields[Doc](tableName, fields, howMatched, List(), 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 An `Option` with the first document matching the field comparison if found
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def firstByFields[Doc](tableName: String, fields: Seq[Field[?]], orderBy: Seq[Field[?]], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
firstByFields[Doc](tableName, fields, None, orderBy, 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 An `Option` with the first document matching the field comparison if found
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def firstByFields[Doc](tableName: String, fields: Seq[Field[?]], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
firstByFields[Doc](tableName, fields, None, List(), 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 An `Option` with the first document matching the field comparison if found
|
||||
* @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[?]] = Nil)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => firstByFields[Doc](tableName, fields, howMatched, orderBy, conn) }.get
|
||||
|
||||
/**
|
||||
* 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 An `Option` with the first document matching the JSON containment query if found
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def firstByContains[Doc, A](tableName: String, criteria: A, orderBy: Seq[Field[?]], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Custom.single[Doc](FindQuery.byContains(tableName) + QueryUtils.orderBy(orderBy.asJava),
|
||||
Parameters.json(":criteria", criteria) :: Nil, conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 An `Option` with the first document matching the JSON containment query if found
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def firstByContains[Doc, A](tableName: String, criteria: A, conn: Connection)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
firstByContains[Doc, A](tableName, criteria, List(), 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 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[?]] = Nil)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => firstByContains[Doc, A](tableName, criteria, orderBy, conn) }.get
|
||||
|
||||
/**
|
||||
* 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 An `Optional` item, with the first document matching the JSON Path match query if found
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def firstByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]], conn: Connection)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Custom.single[Doc](FindQuery.byJsonPath(tableName) + QueryUtils.orderBy(orderBy.asJava),
|
||||
Parameter(":path", ParameterType.STRING, path) :: Nil, conn, Results.fromData)
|
||||
|
||||
/**
|
||||
* 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 An `Option` with the first document matching the JSON Path match query if found
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def firstByJsonPath[Doc](tableName: String, path: String, conn: Connection)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
firstByJsonPath[Doc](tableName, path, List(), 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 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[?]] = Nil)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Using(Configuration.dbConn()) { conn => firstByJsonPath[Doc](tableName, path, orderBy, conn) }.get
|
||||
688
src/scala/src/main/scala/Json.scala
Normal file
688
src/scala/src/main/scala/Json.scala
Normal file
@@ -0,0 +1,688 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.java.Json as CoreJson
|
||||
|
||||
import java.io.PrintWriter
|
||||
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
|
||||
*
|
||||
* @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, ordering results by the optional given fields (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)
|
||||
|
||||
/**
|
||||
* Write all documents in the given table to the given `PrintWriter`, ordering results by the optional given fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If query execution fails
|
||||
*/
|
||||
def writeAll(tableName: String, writer: PrintWriter, orderBy: Seq[Field[?]], conn: Connection): Unit =
|
||||
CoreJson.writeAll(tableName, writer, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write all documents in the given table to the given `PrintWriter`
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param conn The connection over which documents should be retrieved
|
||||
* @throws DocumentException If query execution fails
|
||||
*/
|
||||
def writeAll(tableName: String, writer: PrintWriter, conn: Connection): Unit =
|
||||
CoreJson.writeAll(tableName, writer, conn)
|
||||
|
||||
/**
|
||||
* Write all documents in the given table to the given `PrintWriter`, ordering results by the optional given fields
|
||||
* (creates connection)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
|
||||
* @throws DocumentException If query execution fails
|
||||
*/
|
||||
def writeAll(tableName: String, writer: PrintWriter, orderBy: Seq[Field[?]]): Unit =
|
||||
CoreJson.writeAll(tableName, writer, 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)
|
||||
|
||||
/**
|
||||
* Write a document to the given `PrintWriter` by its ID
|
||||
*
|
||||
* @param tableName The table from which the document should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param docId The ID of the document to retrieve
|
||||
* @param conn The connection over which documents should be retrieved
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def writeById[Key](tableName: String, writer: PrintWriter, docId: Key, conn: Connection): Unit =
|
||||
CoreJson.writeById(tableName, writer, docId, conn)
|
||||
|
||||
/**
|
||||
* Write a document to the given `PrintWriter` by its ID (creates connection)
|
||||
*
|
||||
* @param tableName The table from which the document should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param docId The ID of the document to retrieve
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def writeById[Key](tableName: String, writer: PrintWriter, docId: Key): Unit =
|
||||
CoreJson.writeById(tableName, writer, 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)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a field comparison, ordering results by the given fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]], howMatched: Option[FieldMatch],
|
||||
orderBy: Seq[Field[?]], conn: Connection): Unit =
|
||||
CoreJson.writeByFields(tableName, writer, fields.asJava, howMatched.orNull, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a field comparison
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]], howMatched: Option[FieldMatch],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeByFields(tableName, writer, fields.asJava, howMatched.orNull, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a field comparison, ordering results by the given fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]], orderBy: Seq[Field[?]],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeByFields(tableName, writer, fields.asJava, null, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a field comparison, ordering results by the given fields (creates
|
||||
* connection)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]],
|
||||
howMatched: Option[FieldMatch] = None, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
CoreJson.writeByFields(tableName, writer, 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)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a JSON containment query, ordering results by the given fields
|
||||
* (PostgreSQL only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeByContains[A](tableName: String, writer: PrintWriter, criteria: A, orderBy: Seq[Field[?]],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeByContains(tableName, writer, criteria, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param criteria The object for which JSON containment should be checked
|
||||
* @param conn The connection over which documents should be retrieved
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeByContains[A](tableName: String, writer: PrintWriter, criteria: A, conn: Connection): Unit =
|
||||
CoreJson.writeByContains(tableName, writer, criteria, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` 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 writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeByContains[A](tableName: String, writer: PrintWriter, criteria: A, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
CoreJson.writeByContains(tableName, writer, 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)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` 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 writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeByJsonPath(tableName: String, writer: PrintWriter, path: String, orderBy: Seq[Field[?]],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeByJsonPath(tableName, writer, path, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a JSON Path match query (PostgreSQL only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param path The JSON path comparison to match
|
||||
* @param conn The connection over which documents should be retrieved
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeByJsonPath(tableName: String, writer: PrintWriter, path: String, conn: Connection): Unit =
|
||||
CoreJson.writeByJsonPath(tableName, writer, path, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` 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 writer The `PrintWriter` to which the results should be written
|
||||
* @param path The JSON path comparison to match
|
||||
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeByJsonPath(tableName: String, writer: PrintWriter, path: String, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
CoreJson.writeByJsonPath(tableName, writer, 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)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a field comparison and ordering fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeFirstByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]], howMatched: Option[FieldMatch],
|
||||
orderBy: Seq[Field[?]], conn: Connection): Unit =
|
||||
CoreJson.writeFirstByFields(tableName, writer, fields.asJava, howMatched.orNull, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a field comparison
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeFirstByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]], howMatched: Option[FieldMatch],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeFirstByFields(tableName, writer, fields.asJava, howMatched.orNull, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a field comparison and ordering fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeFirstByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]], orderBy: Seq[Field[?]],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeFirstByFields(tableName, writer, fields.asJava, null, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a field comparison
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param fields The fields which should be compared
|
||||
* @param conn The connection over which documents should be retrieved
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeFirstByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]], conn: Connection): Unit =
|
||||
CoreJson.writeFirstByFields(tableName, writer, fields.asJava, null, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a field comparison and ordering fields (creates
|
||||
* connection)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def writeFirstByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]],
|
||||
howMatched: Option[FieldMatch] = None, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
CoreJson.writeFirstByFields(tableName, writer, 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)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON containment query and ordering fields (PostgreSQL
|
||||
* only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeFirstByContains[A](tableName: String, writer: PrintWriter, criteria: A, orderBy: Seq[Field[?]],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeFirstByContains(tableName, writer, criteria, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param criteria The object for which JSON containment should be checked
|
||||
* @param conn The connection over which documents should be retrieved
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeFirstByContains[A](tableName: String, writer: PrintWriter, criteria: A, conn: Connection): Unit =
|
||||
CoreJson.writeFirstByContains(tableName, writer, criteria, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON containment query and ordering fields (PostgreSQL
|
||||
* only; creates connection)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeFirstByContains[A](tableName: String, writer: PrintWriter, criteria: A, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
CoreJson.writeFirstByContains(tableName, writer, 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)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON Path match query and ordering fields (PostgreSQL
|
||||
* only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeFirstByJsonPath(tableName: String, writer: PrintWriter, path: String, orderBy: Seq[Field[?]],
|
||||
conn: Connection): Unit =
|
||||
CoreJson.writeFirstByJsonPath(tableName, writer, path, orderBy.asJava, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON Path match query (PostgreSQL only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param path The JSON path comparison to match
|
||||
* @param conn The connection over which documents should be retrieved
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeFirstByJsonPath(tableName: String, writer: PrintWriter, path: String, conn: Connection): Unit =
|
||||
CoreJson.writeFirstByJsonPath(tableName, writer, path, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON Path match query and ordering fields (PostgreSQL
|
||||
* only; creates connection)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param path The JSON path comparison to match
|
||||
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def writeFirstByJsonPath(tableName: String, writer: PrintWriter, path: String, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
CoreJson.writeFirstByJsonPath(tableName, writer, path, orderBy.asJava)
|
||||
86
src/scala/src/main/scala/Parameters.scala
Normal file
86
src/scala/src/main/scala/Parameters.scala
Normal file
@@ -0,0 +1,86 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Field, Op, Parameter, ParameterName}
|
||||
import solutions.bitbadger.documents.java.Parameters as CoreParameters
|
||||
|
||||
import java.sql.{Connection, PreparedStatement}
|
||||
import java.util
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import _root_.scala.jdk.CollectionConverters.*
|
||||
|
||||
/**
|
||||
* Functions to assist with the creation and implementation of parameters for SQL queries
|
||||
*/
|
||||
object Parameters:
|
||||
|
||||
/**
|
||||
* Assign parameter names to any fields that do not have them assigned
|
||||
*
|
||||
* @param fields The collection of fields to be named
|
||||
* @return The collection of fields with parameter names assigned
|
||||
*/
|
||||
def nameFields(fields: Seq[Field[?]]): Seq[Field[?]] =
|
||||
val name = ParameterName()
|
||||
fields.map { it =>
|
||||
if (it.getParameterName == null || it.getParameterName.isEmpty)
|
||||
&& !(Op.EXISTS :: Op.NOT_EXISTS :: Nil).contains(it.getComparison.getOp) then
|
||||
it.withParameterName(name.derive(null))
|
||||
else
|
||||
it
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a parameter by encoding a JSON object
|
||||
*
|
||||
* @param name The parameter name
|
||||
* @param value The object to be encoded as JSON
|
||||
* @return A parameter with the value encoded
|
||||
*/
|
||||
def json[A](name: String, value: A): Parameter[String] =
|
||||
CoreParameters.json(name, value)
|
||||
|
||||
/**
|
||||
* Add field parameters to the given set of parameters
|
||||
*
|
||||
* @param fields The fields being compared in the query
|
||||
* @param existing Any existing parameters for the query (optional, defaults to empty collection)
|
||||
* @return A collection of parameters for the query
|
||||
*/
|
||||
def addFields(fields: Seq[Field[?]],
|
||||
existing: mutable.Buffer[Parameter[?]] = ListBuffer()): mutable.Buffer[Parameter[?]] =
|
||||
fields.foreach { it => it.appendParameter(new util.ArrayList[Parameter[?]]()).forEach(existing.append) }
|
||||
existing
|
||||
|
||||
/**
|
||||
* Replace the parameter names in the query with question marks
|
||||
*
|
||||
* @param query The query with named placeholders
|
||||
* @param parameters The parameters for the query
|
||||
* @return The query, with name parameters changed to `?`s
|
||||
*/
|
||||
def replaceNamesInQuery(query: String, parameters: Seq[Parameter[?]]): String =
|
||||
CoreParameters.replaceNamesInQuery(query, parameters.asJava)
|
||||
|
||||
/**
|
||||
* Apply the given parameters to the given query, returning a prepared statement
|
||||
*
|
||||
* @param conn The active JDBC connection
|
||||
* @param query The query
|
||||
* @param parameters The parameters for the query
|
||||
* @return A `PreparedStatement` with the parameter names replaced with `?` and parameter values bound
|
||||
* @throws DocumentException If parameter names are invalid or number value types are invalid
|
||||
*/
|
||||
def apply(conn: Connection, query: String, parameters: Seq[Parameter[?]]): PreparedStatement =
|
||||
CoreParameters.apply(conn, query, parameters.asJava)
|
||||
|
||||
/**
|
||||
* Create parameters for field names to be removed from a document
|
||||
*
|
||||
* @param names The names of the fields to be removed
|
||||
* @param parameterName The parameter name to use for the query
|
||||
* @return A list of parameters to use for building the query
|
||||
* @throws DocumentException If the dialect has not been set
|
||||
*/
|
||||
def fieldNames(names: Seq[String], parameterName: String = ":name"): mutable.Buffer[Parameter[?]] =
|
||||
CoreParameters.fieldNames(names.asJava, parameterName).asScala.toBuffer
|
||||
120
src/scala/src/main/scala/Patch.scala
Normal file
120
src/scala/src/main/scala/Patch.scala
Normal file
@@ -0,0 +1,120 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.java.Patch as CorePatch
|
||||
|
||||
import java.sql.Connection
|
||||
import _root_.scala.jdk.CollectionConverters.*
|
||||
|
||||
/**
|
||||
* Functions to patch (partially update) documents
|
||||
*/
|
||||
object Patch:
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def byId[Key, Patch](tableName: String, docId: Key, patch: Patch, conn: Connection): Unit =
|
||||
CorePatch.byId(tableName, docId, patch, conn)
|
||||
|
||||
/**
|
||||
* Patch a document by its ID (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def byId[Key, Patch](tableName: String, docId: Key, patch: Patch): Unit =
|
||||
CorePatch.byId(tableName, docId, patch)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def byFields[Patch](tableName: String, fields: Seq[Field[?]], patch: Patch, howMatched: Option[FieldMatch],
|
||||
conn: Connection): Unit =
|
||||
CorePatch.byFields(tableName, fields.asJava, patch, howMatched.orNull, conn)
|
||||
|
||||
/**
|
||||
* 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 conn The connection on which the update should be executed
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def byFields[Patch](tableName: String, fields: Seq[Field[?]], patch: Patch, conn: Connection): Unit =
|
||||
byFields(tableName, fields, patch, None, conn)
|
||||
|
||||
/**
|
||||
* Patch documents using a field comparison (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||
*/
|
||||
def byFields[Patch](tableName: String, fields: Seq[Field[?]], patch: Patch,
|
||||
howMatched: Option[FieldMatch] = None): Unit =
|
||||
CorePatch.byFields(tableName, fields.asJava, patch, howMatched.orNull)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byContains[A, Patch](tableName: String, criteria: A, patch: Patch, conn: Connection): Unit =
|
||||
CorePatch.byContains(tableName, criteria, patch, conn)
|
||||
|
||||
/**
|
||||
* Patch documents using a JSON containment query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byContains[A, Patch](tableName: String, criteria: A, patch: Patch): Unit =
|
||||
CorePatch.byContains(tableName, criteria, patch)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath[Patch](tableName: String, path: String, patch: Patch, conn: Connection): Unit =
|
||||
CorePatch.byJsonPath(tableName, path, patch, conn)
|
||||
|
||||
/**
|
||||
* Patch documents using a JSON Path match query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath[Patch](tableName: String, path: String, patch: Patch): Unit =
|
||||
CorePatch.byJsonPath(tableName, path, patch)
|
||||
120
src/scala/src/main/scala/RemoveFields.scala
Normal file
120
src/scala/src/main/scala/RemoveFields.scala
Normal file
@@ -0,0 +1,120 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.{Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.java.RemoveFields as CoreRemoveFields
|
||||
|
||||
import java.sql.Connection
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
/**
|
||||
* Functions to remove fields from documents
|
||||
*/
|
||||
object RemoveFields:
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def byId[Key](tableName: String, docId: Key, toRemove: Seq[String], conn: Connection): Unit =
|
||||
CoreRemoveFields.byId(tableName, docId, toRemove.asJava, conn)
|
||||
|
||||
/**
|
||||
* Remove fields from a document by its ID (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def byId[Key](tableName: String, docId: Key, toRemove: Seq[String]): Unit =
|
||||
CoreRemoveFields.byId(tableName, docId, toRemove.asJava)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def byFields(tableName: String, fields: Seq[Field[?]], toRemove: Seq[String], howMatched: Option[FieldMatch],
|
||||
conn: Connection): Unit =
|
||||
CoreRemoveFields.byFields(tableName, fields.asJava, toRemove.asJava, howMatched.orNull, conn)
|
||||
|
||||
/**
|
||||
* 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 conn The connection on which the update should be executed
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def byFields(tableName: String, fields: Seq[Field[?]], toRemove: Seq[String], conn: Connection): Unit =
|
||||
byFields(tableName, fields, toRemove, None, conn)
|
||||
|
||||
/**
|
||||
* Remove fields from documents using a field comparison (creates connection)
|
||||
*
|
||||
* @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
|
||||
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||
*/
|
||||
def byFields(tableName: String, fields: Seq[Field[?]], toRemove: Seq[String],
|
||||
howMatched: Option[FieldMatch] = None): Unit =
|
||||
CoreRemoveFields.byFields(tableName, fields.asJava, toRemove.asJava, howMatched.orNull)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A, toRemove: Seq[String], conn: Connection): Unit =
|
||||
CoreRemoveFields.byContains(tableName, criteria, toRemove.asJava, conn)
|
||||
|
||||
/**
|
||||
* Remove fields from documents using a JSON containment query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byContains[A](tableName: String, criteria: A, toRemove: Seq[String]): Unit =
|
||||
CoreRemoveFields.byContains(tableName, criteria, toRemove.asJava)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param conn The connection on which the update should be executed
|
||||
* @throws DocumentException If called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String, toRemove: Seq[String], conn: Connection): Unit =
|
||||
CoreRemoveFields.byJsonPath(tableName, path, toRemove.asJava, conn)
|
||||
|
||||
/**
|
||||
* Remove fields from documents using a JSON Path match query (PostgreSQL only; creates connection)
|
||||
*
|
||||
* @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 no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def byJsonPath(tableName: String, path: String, toRemove: Seq[String]): Unit =
|
||||
CoreRemoveFields.byJsonPath(tableName, path, toRemove.asJava)
|
||||
143
src/scala/src/main/scala/Results.scala
Normal file
143
src/scala/src/main/scala/Results.scala
Normal file
@@ -0,0 +1,143 @@
|
||||
package solutions.bitbadger.documents.scala
|
||||
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.Results as CoreResults
|
||||
|
||||
import java.io.PrintWriter
|
||||
import java.sql.{PreparedStatement, ResultSet, SQLException}
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import scala.reflect.ClassTag
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* Functions to manipulate 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
|
||||
* @param ignored The class tag (placeholder used for signature; implicit tag used for serialization)
|
||||
* @return The constructed domain item
|
||||
*/
|
||||
def fromDocument[Doc](field: String, rs: ResultSet, ignored: ClassTag[Doc])(using tag: ClassTag[Doc]): Doc =
|
||||
CoreResults.fromDocument(field, rs, tag.runtimeClass.asInstanceOf[Class[Doc]])
|
||||
|
||||
/**
|
||||
* Create a domain item from a document
|
||||
*
|
||||
* @param rs A `ResultSet` set to the row with the document to be constructed
|
||||
* @param ignored The class tag (placeholder used for signature; implicit tag used for serialization)
|
||||
* @return The constructed domain item
|
||||
*/
|
||||
def fromData[Doc](rs: ResultSet, ignored: ClassTag[Doc])(using tag: ClassTag[Doc]): Doc =
|
||||
fromDocument[Doc]("data", rs, tag)
|
||||
|
||||
/**
|
||||
* 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 (unchecked)
|
||||
*/
|
||||
def toCustomList[Doc](stmt: PreparedStatement,mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
try
|
||||
val buffer = ListBuffer[Doc]()
|
||||
Using(stmt.executeQuery()) { rs =>
|
||||
while rs.next() do
|
||||
buffer.append(mapFunc(rs, tag))
|
||||
}
|
||||
buffer.toList
|
||||
catch
|
||||
case 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
|
||||
* @throws DocumentException If the dialect has not been set (unchecked)
|
||||
*/
|
||||
def toCount(rs: ResultSet, tag: ClassTag[Long] = ClassTag.Long): Long =
|
||||
CoreResults.toCount(rs, Long.getClass)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If the dialect has not been set (unchecked)
|
||||
*/
|
||||
def toExists(rs: ResultSet, tag: ClassTag[Boolean] = ClassTag.Boolean): Boolean =
|
||||
CoreResults.toExists(rs, Boolean.getClass)
|
||||
|
||||
/**
|
||||
* Retrieve the JSON text of 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 JSON text of the document
|
||||
*/
|
||||
def jsonFromDocument(field: String, rs: ResultSet): String =
|
||||
CoreResults.jsonFromDocument(field, rs)
|
||||
|
||||
/**
|
||||
* Retrieve the JSON text of a document, specifying the field in which the document is found
|
||||
*
|
||||
* @param rs A `ResultSet` set to the row with the document to be constructed
|
||||
* @return The JSON text of the document
|
||||
*/
|
||||
def jsonFromData(rs: ResultSet): String =
|
||||
CoreResults.jsonFromData(rs)
|
||||
|
||||
/**
|
||||
* Create a JSON array 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 JSON text
|
||||
* @return A string with a JSON array of documents from the query's result
|
||||
* @throws DocumentException If there is a problem executing the query (unchecked)
|
||||
*/
|
||||
def toJsonArray(stmt: PreparedStatement, mapFunc: ResultSet => String): String =
|
||||
try
|
||||
val results = StringBuilder("[")
|
||||
Using(stmt.executeQuery()) { rs =>
|
||||
while rs.next() do
|
||||
if (results.length > 2) results.append(",")
|
||||
results.append(mapFunc(rs))
|
||||
}
|
||||
results.append("]").toString()
|
||||
catch
|
||||
case ex: SQLException => throw DocumentException("Error retrieving documents from query: ${ex.message}", ex)
|
||||
|
||||
/**
|
||||
* Write a JSON array of items for the results of the given command to the given `PrintWriter`, using the specified
|
||||
* mapping function
|
||||
*
|
||||
* @param writer The writer for the results of the query
|
||||
* @param stmt The prepared statement to execute
|
||||
* @param mapFunc The mapping function from data reader to JSON text
|
||||
* @return A string with a JSON array of documents from the query's result
|
||||
* @throws DocumentException If there is a problem executing the query (unchecked)
|
||||
*/
|
||||
def writeJsonArray(writer: PrintWriter, stmt: PreparedStatement, mapFunc: ResultSet => String): Unit =
|
||||
try
|
||||
writer.write("[")
|
||||
Using(stmt.executeQuery()) { rs =>
|
||||
var isFirst = true
|
||||
while rs.next() do
|
||||
if isFirst then
|
||||
isFirst = false
|
||||
else
|
||||
writer.write(",")
|
||||
writer.write(mapFunc(rs))
|
||||
}
|
||||
writer.write("]")
|
||||
catch
|
||||
case ex: SQLException => throw DocumentException("Error writing documents from query: ${ex.message}", ex)
|
||||
|
||||
776
src/scala/src/main/scala/extensions/package.scala
Normal file
776
src/scala/src/main/scala/extensions/package.scala
Normal file
@@ -0,0 +1,776 @@
|
||||
package solutions.bitbadger.documents.scala.extensions
|
||||
|
||||
import solutions.bitbadger.documents.{DocumentIndex, Field, FieldMatch, Parameter}
|
||||
import solutions.bitbadger.documents.scala.*
|
||||
|
||||
import java.io.PrintWriter
|
||||
import java.sql.{Connection, ResultSet}
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
extension (conn: Connection)
|
||||
|
||||
// ~~~ 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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customList[Doc](query: String, parameters: Seq[Parameter[?]], mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Custom.list[Doc](query, parameters, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a list of results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return A list of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customList[Doc](query: String, mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Custom.list[Doc](query, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array of results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param parameters Parameters to use for the query
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customJsonArray(query: String, parameters: Seq[Parameter[?]], mapFunc: ResultSet => String): String =
|
||||
Custom.jsonArray(query, parameters, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a JSON array of results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customJsonArray(query: String, mapFunc: ResultSet => String): String =
|
||||
Custom.jsonArray(query, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that writes a JSON array of results to the given `PrintWriter`
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param parameters Parameters to use for the query
|
||||
* @param writer The writer to which the results should be written
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def writeCustomJsonArray(query: String, parameters: Seq[Parameter[?]], writer: PrintWriter,
|
||||
mapFunc: ResultSet => String): Unit =
|
||||
Custom.writeJsonArray(query, parameters, writer, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that writes a JSON array of results to the given `PrintWriter`
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param writer The writer to which the results should be written
|
||||
* @param mapFunc The mapping function to extract the JSON from the query
|
||||
* @return A JSON array of results for the given query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def writeCustomJsonArray(query: String, writer: PrintWriter, mapFunc: ResultSet => String): Unit =
|
||||
Custom.writeJsonArray(query, writer, 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 An optional document, filled if one matches the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customSingle[Doc](query: String, parameters: Seq[Parameter[?]], mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Custom.single[Doc](query, parameters, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns one or no results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return An optional document, filled if one matches the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customSingle[Doc](query: String, mapFunc: (ResultSet, ClassTag[Doc]) => Doc)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Custom.single[Doc](query, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns JSON for one or no documents (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 The JSON for the document if found, an empty object (`{}`) if not
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customJsonSingle(query: String, parameters: Seq[Parameter[?]], mapFunc: ResultSet => String): String =
|
||||
Custom.jsonSingle(query, parameters, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns JSON for one or no documents (creates connection)
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return The JSON for the document if found, an empty object (`{}`) if not
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customJsonSingle(query: String, mapFunc: ResultSet => String): String =
|
||||
Custom.jsonSingle(query, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns no results
|
||||
*
|
||||
* @param query The query to retrieve the results
|
||||
* @param parameters Parameters to use for the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customNonQuery(query: String, parameters: Seq[Parameter[?]] = Nil): Unit =
|
||||
Custom.nonQuery(query, parameters, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customScalar[A](query: String, parameters: Seq[Parameter[?]], mapFunc: (ResultSet, ClassTag[A]) => A)
|
||||
(using tag: ClassTag[A]): A =
|
||||
Custom.scalar[A](query, parameters, conn, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a scalar result
|
||||
*
|
||||
* @param query The query to retrieve the result
|
||||
* @param mapFunc The mapping function between the document and the domain item
|
||||
* @return The scalar value from the query
|
||||
* @throws DocumentException If parameters are invalid
|
||||
*/
|
||||
def customScalar[A](query: String, mapFunc: (ResultSet, ClassTag[A]) => A)(using tag: ClassTag[A]): A =
|
||||
Custom.scalar[A](query, conn, mapFunc)
|
||||
|
||||
// ~~~ DEFINITION QUERIES ~~~
|
||||
|
||||
/**
|
||||
* Create a document table if necessary
|
||||
*
|
||||
* @param tableName The table whose existence should be ensured (may include schema)
|
||||
* @throws DocumentException If the dialect is not configured
|
||||
*/
|
||||
def ensureTable(tableName: String): Unit =
|
||||
Definition.ensureTable(tableName, conn)
|
||||
|
||||
/**
|
||||
* 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<
|
||||
* @throws DocumentException If any dependent process does
|
||||
*/
|
||||
def ensureFieldIndex(tableName: String, indexName: String, fields: Seq[String]): Unit =
|
||||
Definition.ensureFieldIndex(tableName, indexName, fields, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def ensureDocumentIndex(tableName: String, indexType: DocumentIndex): Unit =
|
||||
Definition.ensureDocumentIndex (tableName, indexType, conn)
|
||||
|
||||
// ~~~ 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
|
||||
* @throws DocumentException If IDs are misconfigured, or if the database command fails
|
||||
*/
|
||||
def insert[Doc](tableName: String, document: Doc): Unit =
|
||||
Document.insert(tableName, document, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If the database command fails
|
||||
*/
|
||||
def save[Doc](tableName: String, document: Doc): Unit =
|
||||
Document.save(tableName, document, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If no dialect has been configured, or if the database command fails
|
||||
*/
|
||||
def update[Key, Doc](tableName: String, docId: Key, document: Doc): Unit =
|
||||
Document.update(tableName, docId, document, conn)
|
||||
|
||||
// ~~~ 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
|
||||
* @throws DocumentException If any dependent process does
|
||||
*/
|
||||
def countAll(tableName: String): Long =
|
||||
Count.all(tableName, conn)
|
||||
|
||||
/**
|
||||
* 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 (optional, default `ALL`)
|
||||
* @return A count of the matching documents in the table
|
||||
* @throws DocumentException If the dialect has not been configured
|
||||
*/
|
||||
def countByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None): Long =
|
||||
Count.byFields(tableName, fields, howMatched, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def countByContains[A](tableName: String, criteria: A): Long =
|
||||
Count.byContains(tableName, criteria, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def countByJsonPath(tableName: String, path: String): Long =
|
||||
Count.byJsonPath(tableName, path, conn)
|
||||
|
||||
// ~~~ 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
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def existsById[Key](tableName: String, docId: Key): Boolean =
|
||||
Exists.byId(tableName, docId, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def existsByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None): Boolean =
|
||||
Exists.byFields(tableName, fields, howMatched, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def existsByContains[A](tableName: String, criteria: A): Boolean =
|
||||
Exists.byContains(tableName, criteria, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def existsByJsonPath(tableName: String, path: String): Boolean =
|
||||
Exists.byJsonPath(tableName, path, conn)
|
||||
|
||||
// ~~~ DOCUMENT RETRIEVAL QUERIES (Domain Objects) ~~~
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If query execution fails
|
||||
*/
|
||||
def findAll[Doc](tableName: String, orderBy: Seq[Field[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Find.all[Doc](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 The document if it is found, `None` otherwise
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def findById[Key, Doc](tableName: String, docId: Key)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Find.byId[Key, Doc](tableName, docId, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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[?]] = Nil)(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Find.byFields[Doc](tableName, fields, howMatched, orderBy, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def findByJsonPath[Doc](tableName: String, path: String, orderBy: Seq[Field[?]] = Nil)
|
||||
(using tag: ClassTag[Doc]): List[Doc] =
|
||||
Find.byJsonPath[Doc](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 document matching the field comparison, or `None` if no matches are found
|
||||
* @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[?]] = Nil)(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Find.firstByFields[Doc](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 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[?]] = Nil)
|
||||
(using tag: ClassTag[Doc]): Option[Doc] =
|
||||
Find.firstByContains[Doc, A](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 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[?]] = 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 RETRIEVAL QUERIES (Write raw JSON to PrintWriter) ~~~
|
||||
|
||||
/**
|
||||
* Write all documents in the given table to the given `PrintWriter`, ordering results by the optional given fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
|
||||
* @throws DocumentException If no connection string has been set, or if query execution fails
|
||||
*/
|
||||
def writeJsonAll(tableName: String, writer: PrintWriter, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
Json.writeAll(tableName, writer, orderBy, conn)
|
||||
|
||||
/**
|
||||
* Write a document to the given `PrintWriter` by its ID
|
||||
*
|
||||
* @param tableName The table from which the document should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param docId The ID of the document to retrieve
|
||||
* @throws DocumentException If no connection string has been set
|
||||
*/
|
||||
def writeJsonById[Key](tableName: String, writer: PrintWriter, docId: Key): Unit =
|
||||
Json.writeById(tableName, writer, docId, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a field comparison, ordering results by the given fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||
*/
|
||||
def writeJsonByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]],
|
||||
howMatched: Option[FieldMatch] = None, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
Json.writeByFields(tableName, writer, fields, howMatched, orderBy, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` using a JSON containment query, ordering results by the given fields
|
||||
* (PostgreSQL only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def writeJsonByContains[A](tableName: String, writer: PrintWriter, criteria: A, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
Json.writeByContains(tableName, writer, criteria, orderBy, conn)
|
||||
|
||||
/**
|
||||
* Write documents to the given `PrintWriter` 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 writer The `PrintWriter` to which the results should be written
|
||||
* @param path The JSON path comparison to match
|
||||
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
|
||||
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def writeJsonByJsonPath(tableName: String, writer: PrintWriter, path: String, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
Json.writeByJsonPath(tableName, writer, path, orderBy, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a field comparison and ordering fields
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||
*/
|
||||
def writeJsonFirstByFields(tableName: String, writer: PrintWriter, fields: Seq[Field[?]],
|
||||
howMatched: Option[FieldMatch] = None, orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
Json.writeFirstByFields(tableName, writer, fields, howMatched, orderBy, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON containment query and ordering fields (PostgreSQL
|
||||
* only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @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)
|
||||
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def writeJsonFirstByContains[A](tableName: String, writer: PrintWriter, criteria: A,
|
||||
orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
Json.writeFirstByContains(tableName, writer, criteria, orderBy, conn)
|
||||
|
||||
/**
|
||||
* Write the first document to the given `PrintWriter` using a JSON Path match query and ordering fields (PostgreSQL
|
||||
* only)
|
||||
*
|
||||
* @param tableName The table from which documents should be retrieved
|
||||
* @param writer The `PrintWriter` to which the results should be written
|
||||
* @param path The JSON path comparison to match
|
||||
* @param orderBy Fields by which the query should be ordered (optional, defaults to no ordering)
|
||||
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||
*/
|
||||
def writeJsonFirstByJsonPath(tableName: String, writer: PrintWriter, path: String,
|
||||
orderBy: Seq[Field[?]] = Nil): Unit =
|
||||
Json.writeFirstByJsonPath(tableName, writer, path, orderBy, conn)
|
||||
|
||||
// ~~~ 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
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def patchById[Key, Patch](tableName: String, docId: Key, patch: Patch): Unit =
|
||||
Patch.byId(tableName, docId, patch, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def patchByFields[Patch](tableName: String, fields: Seq[Field[?]], patch: Patch,
|
||||
howMatched: Option[FieldMatch] = None): Unit =
|
||||
Patch.byFields(tableName, fields, patch, howMatched, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def patchByContains[A, Patch](tableName: String, criteria: A, patch: Patch): Unit =
|
||||
Patch.byContains(tableName, criteria, patch, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def patchByJsonPath[Patch](tableName: String, path: String, patch: Patch): Unit =
|
||||
Patch.byJsonPath(tableName, path, patch, conn)
|
||||
|
||||
// ~~~ 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
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def removeFieldsById[Key](tableName: String, docId: Key, toRemove: Seq[String]): Unit =
|
||||
RemoveFields.byId(tableName, docId, toRemove, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def removeFieldsByFields(tableName: String, fields: Seq[Field[?]], toRemove: Seq[String],
|
||||
howMatched: Option[FieldMatch] = None): Unit =
|
||||
RemoveFields.byFields(tableName, fields, toRemove, howMatched, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def removeFieldsByContains[A](tableName: String, criteria: A, toRemove: Seq[String]): Unit =
|
||||
RemoveFields.byContains(tableName, criteria, toRemove, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def removeFieldsByJsonPath(tableName: String, path: String, toRemove: Seq[String]): Unit =
|
||||
RemoveFields.byJsonPath(tableName, path, toRemove, conn)
|
||||
|
||||
// ~~~ 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
|
||||
* @throws DocumentException If no dialect has been configured
|
||||
*/
|
||||
def deleteById[Key](tableName: String, docId: Key): Unit =
|
||||
Delete.byId(tableName, docId, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws DocumentException If no dialect has been configured, or if parameters are invalid
|
||||
*/
|
||||
def deleteByFields(tableName: String, fields: Seq[Field[?]], howMatched: Option[FieldMatch] = None): Unit =
|
||||
Delete.byFields(tableName, fields, howMatched, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def deleteByContains[A](tableName: String, criteria: A): Unit =
|
||||
Delete.byContains(tableName, criteria, conn)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
def deleteByJsonPath(tableName: String, path: String): Unit =
|
||||
Delete.byJsonPath(tableName, path, conn)
|
||||
126
src/scala/src/test/scala/AutoIdTest.scala
Normal file
126
src/scala/src/test/scala/AutoIdTest.scala
Normal file
@@ -0,0 +1,126 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{AutoId, DocumentException}
|
||||
|
||||
@DisplayName("Scala | AutoId")
|
||||
class AutoIdTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates a UUID string")
|
||||
def generateUUID(): Unit =
|
||||
assertEquals(32, AutoId.generateUUID().length(), "The UUID should have been a 32-character string")
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates a random hex character string of an even length")
|
||||
def generateRandomStringEven(): Unit =
|
||||
val result = AutoId.generateRandomString(8)
|
||||
assertEquals(8, result.length(), s"There should have been 8 characters in $result")
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates a random hex character string of an odd length")
|
||||
def generateRandomStringOdd(): Unit =
|
||||
val result = AutoId.generateRandomString(11)
|
||||
assertEquals(11, result.length(), s"There should have been 11 characters in $result")
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates different random hex character strings")
|
||||
def generateRandomStringIsRandom(): Unit =
|
||||
val result1 = AutoId.generateRandomString(16)
|
||||
val result2 = AutoId.generateRandomString(16)
|
||||
assertNotEquals(result1, result2, "There should have been 2 different strings generated")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for null document")
|
||||
def needsAutoIdFailsForNullDocument(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => AutoId.needsAutoId(AutoId.DISABLED, null, "id"))
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for missing ID property")
|
||||
def needsAutoIdFailsForMissingId(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => AutoId.needsAutoId(AutoId.UUID, IntIdClass(0), "Id"))
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false if disabled")
|
||||
def needsAutoIdFalseIfDisabled(): Unit =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.DISABLED, "", ""), "Disabled Auto ID should always return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and byte ID of 0")
|
||||
def needsAutoIdTrueForByteWithZero(): Unit =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, ByteIdClass(0), "id"), "Number Auto ID with 0 should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and byte ID of non-0")
|
||||
def needsAutoIdFalseForByteWithNonZero(): Unit =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, ByteIdClass(77), "id"), "Number Auto ID with 77 should return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and short ID of 0")
|
||||
def needsAutoIdTrueForShortWithZero(): Unit =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, ShortIdClass(0), "id"), "Number Auto ID with 0 should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and short ID of non-0")
|
||||
def needsAutoIdFalseForShortWithNonZero(): Unit =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, ShortIdClass(31), "id"), "Number Auto ID with 31 should return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and int ID of 0")
|
||||
def needsAutoIdTrueForIntWithZero(): Unit =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, IntIdClass(0), "id"), "Number Auto ID with 0 should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and int ID of non-0")
|
||||
def needsAutoIdFalseForIntWithNonZero(): Unit =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, IntIdClass(6), "id"), "Number Auto ID with 6 should return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and long ID of 0")
|
||||
def needsAutoIdTrueForLongWithZero(): Unit =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, LongIdClass(0), "id"), "Number Auto ID with 0 should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and long ID of non-0")
|
||||
def needsAutoIdFalseForLongWithNonZero(): Unit =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, LongIdClass(2), "id"), "Number Auto ID with 2 should return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for Number strategy and non-number ID")
|
||||
def needsAutoIdFailsForNumberWithStringId(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => AutoId.needsAutoId(AutoId.NUMBER, StringIdClass(""), "id"))
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for UUID strategy and blank ID")
|
||||
def needsAutoIdTrueForUUIDWithBlank(): Unit =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.UUID, StringIdClass(""), "id"), "UUID Auto ID with blank should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for UUID strategy and non-blank ID")
|
||||
def needsAutoIdFalseForUUIDNotBlank(): Unit =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.UUID, StringIdClass("howdy"), "id"),
|
||||
"UUID Auto ID with non-blank should return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for UUID strategy and non-string ID")
|
||||
def needsAutoIdFailsForUUIDNonString(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => AutoId.needsAutoId(AutoId.UUID, IntIdClass(5), "id"))
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Random String strategy and blank ID")
|
||||
def needsAutoIdTrueForRandomWithBlank(): Unit =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.RANDOM_STRING, StringIdClass(""), "id"),
|
||||
"Random String Auto ID with blank should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Random String strategy and non-blank ID")
|
||||
def needsAutoIdFalseForRandomNotBlank(): Unit =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.RANDOM_STRING, StringIdClass("full"), "id"),
|
||||
"Random String Auto ID with non-blank should return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for Random String strategy and non-string ID")
|
||||
def needsAutoIdFailsForRandomNonString(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => AutoId.needsAutoId(AutoId.RANDOM_STRING, ShortIdClass(55), "id"))
|
||||
3
src/scala/src/test/scala/ByteIdClass.scala
Normal file
3
src/scala/src/test/scala/ByteIdClass.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
class ByteIdClass(var id: Byte)
|
||||
33
src/scala/src/test/scala/ConfigurationTest.scala
Normal file
33
src/scala/src/test/scala/ConfigurationTest.scala
Normal file
@@ -0,0 +1,33 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{AutoId, Configuration, Dialect, DocumentException}
|
||||
|
||||
@DisplayName("Scala | Configuration")
|
||||
class ConfigurationTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("Default ID field is `id`")
|
||||
def defaultIdField(): Unit =
|
||||
assertEquals("id", Configuration.idField, "Default ID field incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("Default Auto ID strategy is `DISABLED`")
|
||||
def defaultAutoId(): Unit =
|
||||
assertEquals(AutoId.DISABLED, Configuration.autoIdStrategy, "Default Auto ID strategy should be `disabled`")
|
||||
|
||||
@Test
|
||||
@DisplayName("Default ID string length should be 16")
|
||||
def defaultIdStringLength(): Unit =
|
||||
assertEquals(16, Configuration.idStringLength, "Default ID string length should be 16")
|
||||
|
||||
@Test
|
||||
@DisplayName("Dialect is derived from connection string")
|
||||
def dialectIsDerived(): Unit =
|
||||
try
|
||||
assertThrows(classOf[DocumentException], () => Configuration.dialect())
|
||||
Configuration.setConnectionString("jdbc:postgresql:db")
|
||||
assertEquals(Dialect.POSTGRESQL, Configuration.dialect())
|
||||
finally
|
||||
Configuration.setConnectionString(null)
|
||||
66
src/scala/src/test/scala/CountQueryTest.scala
Normal file
66
src/scala/src/test/scala/CountQueryTest.scala
Normal file
@@ -0,0 +1,66 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field}
|
||||
import solutions.bitbadger.documents.query.CountQuery
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | CountQuery")
|
||||
class CountQueryTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("all generates correctly")
|
||||
def all(): Unit =
|
||||
assertEquals(s"SELECT COUNT(*) AS it FROM $TEST_TABLE", CountQuery.all(TEST_TABLE),
|
||||
"Count query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||
def byFieldsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT COUNT(*) AS it FROM $TEST_TABLE WHERE data->>'test' = :field0",
|
||||
CountQuery.byFields(TEST_TABLE, List(Field.equal("test", "", ":field0")).asJava),
|
||||
"Count query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | SQLite")
|
||||
def byFieldsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"SELECT COUNT(*) AS it FROM $TEST_TABLE WHERE data->>'test' = :field0",
|
||||
CountQuery.byFields(TEST_TABLE, List(Field.equal("test", "", ":field0")).asJava),
|
||||
"Count query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||
def byContainsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT COUNT(*) AS it FROM $TEST_TABLE WHERE data @> :criteria", CountQuery.byContains(TEST_TABLE),
|
||||
"Count query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails | SQLite")
|
||||
def byContainsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => CountQuery.byContains(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||
def byJsonPathPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT COUNT(*) AS it FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
CountQuery.byJsonPath(TEST_TABLE), "Count query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails | SQLite")
|
||||
def byJsonPathSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => CountQuery.byJsonPath(TEST_TABLE))
|
||||
104
src/scala/src/test/scala/DefinitionQueryTest.scala
Normal file
104
src/scala/src/test/scala/DefinitionQueryTest.scala
Normal file
@@ -0,0 +1,104 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{Dialect, DocumentException, DocumentIndex}
|
||||
import solutions.bitbadger.documents.query.DefinitionQuery
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | DefinitionQuery")
|
||||
class DefinitionQueryTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTableFor generates correctly")
|
||||
def ensureTableFor(): Unit =
|
||||
assertEquals("CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
||||
DefinitionQuery.ensureTableFor("my.table", "JSONB"), "CREATE TABLE statement not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable generates correctly | PostgreSQL")
|
||||
def ensureTablePostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"CREATE TABLE IF NOT EXISTS $TEST_TABLE (data JSONB NOT NULL)",
|
||||
DefinitionQuery.ensureTable(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable generates correctly | SQLite")
|
||||
def ensureTableSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"CREATE TABLE IF NOT EXISTS $TEST_TABLE (data TEXT NOT NULL)",
|
||||
DefinitionQuery.ensureTable(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable fails when no dialect is set")
|
||||
def ensureTableFailsUnknown(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => DefinitionQuery.ensureTable(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureKey generates correctly with schema")
|
||||
def ensureKeyWithSchema(): Unit =
|
||||
assertEquals("CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data->>'id'))",
|
||||
DefinitionQuery.ensureKey("test.table", Dialect.POSTGRESQL),
|
||||
"CREATE INDEX for key statement with schema not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureKey generates correctly without schema")
|
||||
def ensureKeyWithoutSchema(): Unit =
|
||||
assertEquals(s"CREATE UNIQUE INDEX IF NOT EXISTS idx_${TEST_TABLE}_key ON $TEST_TABLE ((data->>'id'))",
|
||||
DefinitionQuery.ensureKey(TEST_TABLE, Dialect.SQLITE),
|
||||
"CREATE INDEX for key statement without schema not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureIndexOn generates multiple fields and directions")
|
||||
def ensureIndexOnMultipleFields(): Unit =
|
||||
assertEquals("CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table " +
|
||||
"((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
||||
DefinitionQuery.ensureIndexOn("test.table", "gibberish", List("taco", "guac DESC", "salsa ASC").asJava,
|
||||
Dialect.POSTGRESQL),
|
||||
"CREATE INDEX for multiple field statement not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureIndexOn generates nested field | PostgreSQL")
|
||||
def ensureIndexOnNestedPostgres(): Unit =
|
||||
assertEquals(s"CREATE INDEX IF NOT EXISTS idx_${TEST_TABLE}_nest ON $TEST_TABLE ((data#>>'{a,b,c}'))",
|
||||
DefinitionQuery.ensureIndexOn(TEST_TABLE, "nest", List("a.b.c").asJava, Dialect.POSTGRESQL),
|
||||
"CREATE INDEX for nested PostgreSQL field incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureIndexOn generates nested field | SQLite")
|
||||
def ensureIndexOnNestedSQLite(): Unit =
|
||||
assertEquals(s"CREATE INDEX IF NOT EXISTS idx_${TEST_TABLE}_nest ON $TEST_TABLE ((data->'a'->'b'->>'c'))",
|
||||
DefinitionQuery.ensureIndexOn(TEST_TABLE, "nest", List("a.b.c").asJava, Dialect.SQLITE),
|
||||
"CREATE INDEX for nested SQLite field incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndexOn generates Full | PostgreSQL")
|
||||
def ensureDocumentIndexOnFullPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"CREATE INDEX IF NOT EXISTS idx_${TEST_TABLE}_document ON $TEST_TABLE USING GIN (data)",
|
||||
DefinitionQuery.ensureDocumentIndexOn(TEST_TABLE, DocumentIndex.FULL),
|
||||
"CREATE INDEX for full document index incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndexOn generates Optimized | PostgreSQL")
|
||||
def ensureDocumentIndexOnOptimizedPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(
|
||||
s"CREATE INDEX IF NOT EXISTS idx_${TEST_TABLE}_document ON $TEST_TABLE USING GIN (data jsonb_path_ops)",
|
||||
DefinitionQuery.ensureDocumentIndexOn(TEST_TABLE, DocumentIndex.OPTIMIZED),
|
||||
"CREATE INDEX for optimized document index incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndexOn fails | SQLite")
|
||||
def ensureDocumentIndexOnFailsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException],
|
||||
() => DefinitionQuery.ensureDocumentIndexOn(TEST_TABLE, DocumentIndex.FULL))
|
||||
74
src/scala/src/test/scala/DeleteQueryTest.scala
Normal file
74
src/scala/src/test/scala/DeleteQueryTest.scala
Normal file
@@ -0,0 +1,74 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field}
|
||||
import solutions.bitbadger.documents.query.DeleteQuery
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | DeleteQuery")
|
||||
class DeleteQueryTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | PostgreSQL")
|
||||
def byIdPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"DELETE FROM $TEST_TABLE WHERE data->>'id' = :id", DeleteQuery.byId(TEST_TABLE),
|
||||
"Delete query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | SQLite")
|
||||
def byIdSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"DELETE FROM $TEST_TABLE WHERE data->>'id' = :id", DeleteQuery.byId(TEST_TABLE),
|
||||
"Delete query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||
def byFieldsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"DELETE FROM $TEST_TABLE WHERE data->>'a' = :b",
|
||||
DeleteQuery.byFields(TEST_TABLE, List(Field.equal("a", "", ":b")).asJava),
|
||||
"Delete query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | SQLite")
|
||||
def byFieldsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"DELETE FROM $TEST_TABLE WHERE data->>'a' = :b",
|
||||
DeleteQuery.byFields(TEST_TABLE, List(Field.equal("a", "", ":b")).asJava),
|
||||
"Delete query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||
def byContainsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"DELETE FROM $TEST_TABLE WHERE data @> :criteria", DeleteQuery.byContains(TEST_TABLE),
|
||||
"Delete query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails | SQLite")
|
||||
def byContainsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => DeleteQuery.byContains(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||
def byJsonPathPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"DELETE FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
DeleteQuery.byJsonPath(TEST_TABLE), "Delete query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails | SQLite")
|
||||
def byJsonPathSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => DeleteQuery.byJsonPath(TEST_TABLE))
|
||||
32
src/scala/src/test/scala/DialectTest.scala
Normal file
32
src/scala/src/test/scala/DialectTest.scala
Normal file
@@ -0,0 +1,32 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{Dialect, DocumentException}
|
||||
|
||||
@DisplayName("Scala | Dialect")
|
||||
class DialectTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("deriveFromConnectionString derives PostgreSQL correctly")
|
||||
def derivesPostgres(): Unit =
|
||||
assertEquals(Dialect.POSTGRESQL, Dialect.deriveFromConnectionString("jdbc:postgresql:db"),
|
||||
"Dialect should have been PostgreSQL")
|
||||
|
||||
@Test
|
||||
@DisplayName("deriveFromConnectionString derives SQLite correctly")
|
||||
def derivesSQLite(): Unit =
|
||||
assertEquals(Dialect.SQLITE, Dialect.deriveFromConnectionString("jdbc:sqlite:memory"),
|
||||
"Dialect should have been SQLite")
|
||||
|
||||
@Test
|
||||
@DisplayName("deriveFromConnectionString fails when the connection string is unknown")
|
||||
def deriveFailsWhenUnknown(): Unit =
|
||||
try
|
||||
Dialect.deriveFromConnectionString("SQL Server")
|
||||
fail("Dialect derivation should have failed")
|
||||
catch
|
||||
case ex: DocumentException =>
|
||||
assertNotNull(ex.getMessage, "The exception message should not have been null")
|
||||
assertTrue(ex.getMessage.contains("[SQL Server]"),
|
||||
"The connection string should have been in the exception message")
|
||||
18
src/scala/src/test/scala/DocumentIndexTest.scala
Normal file
18
src/scala/src/test/scala/DocumentIndexTest.scala
Normal file
@@ -0,0 +1,18 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.DocumentIndex
|
||||
|
||||
@DisplayName("Scala | DocumentIndex")
|
||||
class DocumentIndexTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("FULL uses proper SQL")
|
||||
def fullSQL(): Unit =
|
||||
assertEquals("", DocumentIndex.FULL.getSql, "The SQL for Full is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("OPTIMIZED uses proper SQL")
|
||||
def optimizedSQL(): Unit =
|
||||
assertEquals(" jsonb_path_ops", DocumentIndex.OPTIMIZED.getSql, "The SQL for Optimized is incorrect")
|
||||
109
src/scala/src/test/scala/DocumentQueryTest.scala
Normal file
109
src/scala/src/test/scala/DocumentQueryTest.scala
Normal file
@@ -0,0 +1,109 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{AutoId, Configuration, DocumentException}
|
||||
import solutions.bitbadger.documents.query.DocumentQuery
|
||||
|
||||
@DisplayName("Scala | Query | DocumentQuery")
|
||||
class DocumentQueryTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates no auto ID | PostgreSQL")
|
||||
def insertNoAutoPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"INSERT INTO $TEST_TABLE VALUES (:data)", DocumentQuery.insert(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates no auto ID | SQLite")
|
||||
def insertNoAutoSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"INSERT INTO $TEST_TABLE VALUES (:data)", DocumentQuery.insert(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto number | PostgreSQL")
|
||||
def insertAutoNumberPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"INSERT INTO $TEST_TABLE VALUES (:data::jsonb || ('{\"id\":' " +
|
||||
s"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $TEST_TABLE) || '}')::jsonb)",
|
||||
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER))
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto number | SQLite")
|
||||
def insertAutoNumberSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$$.id', " +
|
||||
s"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $TEST_TABLE)))",
|
||||
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER))
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto UUID | PostgreSQL")
|
||||
def insertAutoUUIDPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
val query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID)
|
||||
assertTrue(query.startsWith(s"INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\""),
|
||||
s"Query start not correct (actual: $query)")
|
||||
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto UUID | SQLite")
|
||||
def insertAutoUUIDSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
val query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID)
|
||||
assertTrue(query.startsWith(s"INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$$.id', '"),
|
||||
s"Query start not correct (actual: $query)")
|
||||
assertTrue(query.endsWith("'))"), "Query end not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto random string | PostgreSQL")
|
||||
def insertAutoRandomPostgres(): Unit =
|
||||
try
|
||||
ForceDialect.postgres()
|
||||
Configuration.idStringLength = 8
|
||||
val query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING)
|
||||
assertTrue(query.startsWith(s"INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\""),
|
||||
s"Query start not correct (actual: $query)")
|
||||
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
||||
assertEquals(8, query.replace(s"INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\"", "")
|
||||
.replace("\"}')", "").length,
|
||||
"Random string length incorrect")
|
||||
finally
|
||||
Configuration.idStringLength = 16
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto random string | SQLite")
|
||||
def insertAutoRandomSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
val query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING)
|
||||
assertTrue(query.startsWith(s"INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$$.id', '"),
|
||||
s"Query start not correct (actual: $query)")
|
||||
assertTrue(query.endsWith("'))"), "Query end not correct")
|
||||
assertEquals(Configuration.idStringLength,
|
||||
query.replace(s"INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$$.id', '", "").replace("'))", "").length,
|
||||
"Random string length incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("insert fails when no dialect is set")
|
||||
def insertFailsUnknown(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => DocumentQuery.insert(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("save generates correctly")
|
||||
def save(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(
|
||||
s"INSERT INTO $TEST_TABLE VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
||||
DocumentQuery.save(TEST_TABLE), "INSERT ON CONFLICT UPDATE statement not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("update generates successfully")
|
||||
def update(): Unit =
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = :data", DocumentQuery.update(TEST_TABLE),
|
||||
"Update query not constructed correctly")
|
||||
74
src/scala/src/test/scala/ExistsQueryTest.scala
Normal file
74
src/scala/src/test/scala/ExistsQueryTest.scala
Normal file
@@ -0,0 +1,74 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field}
|
||||
import solutions.bitbadger.documents.query.ExistsQuery
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | ExistsQuery")
|
||||
class ExistsQueryTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | PostgreSQL")
|
||||
def byIdPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data->>'id' = :id) AS it",
|
||||
ExistsQuery.byId(TEST_TABLE), "Exists query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | SQLite")
|
||||
def byIdSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data->>'id' = :id) AS it",
|
||||
ExistsQuery.byId(TEST_TABLE), "Exists query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||
def byFieldsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE (data->>'it')::numeric = :test) AS it",
|
||||
ExistsQuery.byFields(TEST_TABLE, List(Field.equal("it", 7, ":test")).asJava),
|
||||
"Exists query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | SQLite")
|
||||
def byFieldsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data->>'it' = :test) AS it",
|
||||
ExistsQuery.byFields(TEST_TABLE, List(Field.equal("it", 7, ":test")).asJava),
|
||||
"Exists query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||
def byContainsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data @> :criteria) AS it",
|
||||
ExistsQuery.byContains(TEST_TABLE), "Exists query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails | SQLite")
|
||||
def byContainsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => ExistsQuery.byContains(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||
def byJsonPathPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
||||
ExistsQuery.byJsonPath(TEST_TABLE), "Exists query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails | SQLite")
|
||||
def byJsonPathSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => ExistsQuery.byJsonPath(TEST_TABLE))
|
||||
21
src/scala/src/test/scala/FieldMatchTest.scala
Normal file
21
src/scala/src/test/scala/FieldMatchTest.scala
Normal file
@@ -0,0 +1,21 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.FieldMatch
|
||||
|
||||
/**
|
||||
* Unit tests for the `FieldMatch` enum
|
||||
*/
|
||||
@DisplayName("Scala | FieldMatch")
|
||||
class FieldMatchTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("ANY uses proper SQL")
|
||||
def any(): Unit =
|
||||
assertEquals("OR", FieldMatch.ANY.getSql, "ANY should use OR")
|
||||
|
||||
@Test
|
||||
@DisplayName("ALL uses proper SQL")
|
||||
def all(): Unit =
|
||||
assertEquals("AND", FieldMatch.ALL.getSql, "ALL should use AND")
|
||||
537
src/scala/src/test/scala/FieldTest.scala
Normal file
537
src/scala/src/test/scala/FieldTest.scala
Normal file
@@ -0,0 +1,537 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.*
|
||||
|
||||
import _root_.scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Field")
|
||||
class FieldTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
// ~~~ INSTANCE METHODS ~~~
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName fails for invalid name")
|
||||
def withParamNameFails(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => Field.equal("it", "").withParameterName("2424"))
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName works with colon prefix")
|
||||
def withParamNameColon(): Unit =
|
||||
val field = Field.equal("abc", "22").withQualifier("me")
|
||||
val withParam = field.withParameterName(":test")
|
||||
assertNotSame(field, withParam, "A new Field instance should have been created")
|
||||
assertEquals(field.getName, withParam.getName, "Name should have been preserved")
|
||||
assertEquals(field.getComparison, withParam.getComparison, "Comparison should have been preserved")
|
||||
assertEquals(":test", withParam.getParameterName, "Parameter name not set correctly")
|
||||
assertEquals(field.getQualifier, withParam.getQualifier, "Qualifier should have been preserved")
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName works with at-sign prefix")
|
||||
def withParamNameAtSign(): Unit =
|
||||
val field = Field.equal("def", "44")
|
||||
val withParam = field.withParameterName("@unit")
|
||||
assertNotSame(field, withParam, "A new Field instance should have been created")
|
||||
assertEquals(field.getName, withParam.getName, "Name should have been preserved")
|
||||
assertEquals(field.getComparison, withParam.getComparison, "Comparison should have been preserved")
|
||||
assertEquals("@unit", withParam.getParameterName, "Parameter name not set correctly")
|
||||
assertEquals(field.getQualifier, withParam.getQualifier, "Qualifier should have been preserved")
|
||||
|
||||
@Test
|
||||
@DisplayName("withQualifier sets qualifier correctly")
|
||||
def withQualifier(): Unit =
|
||||
val field = Field.equal("j", "k")
|
||||
val withQual = field.withQualifier("test")
|
||||
assertNotSame(field, withQual, "A new Field instance should have been created")
|
||||
assertEquals(field.getName, withQual.getName, "Name should have been preserved")
|
||||
assertEquals(field.getComparison, withQual.getComparison, "Comparison should have been preserved")
|
||||
assertEquals(field.getParameterName, withQual.getParameterName, "Parameter Name should have been preserved")
|
||||
assertEquals("test", withQual.getQualifier, "Qualifier not set correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple unqualified PostgreSQL field")
|
||||
def pathPostgresSimpleUnqualified(): Unit =
|
||||
assertEquals("data->>'SomethingCool'",
|
||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple qualified PostgreSQL field")
|
||||
def pathPostgresSimpleQualified(): Unit =
|
||||
assertEquals("this.data->>'SomethingElse'",
|
||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested unqualified PostgreSQL field")
|
||||
def pathPostgresNestedUnqualified(): Unit =
|
||||
assertEquals("data#>>'{My,Nested,Field}'",
|
||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested qualified PostgreSQL field")
|
||||
def pathPostgresNestedQualified(): Unit =
|
||||
assertEquals("bird.data#>>'{Nest,Away}'",
|
||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple unqualified SQLite field")
|
||||
def pathSQLiteSimpleUnqualified(): Unit =
|
||||
assertEquals("data->>'SomethingCool'",
|
||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple qualified SQLite field")
|
||||
def pathSQLiteSimpleQualified(): Unit =
|
||||
assertEquals("this.data->>'SomethingElse'",
|
||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested unqualified SQLite field")
|
||||
def pathSQLiteNestedUnqualified(): Unit =
|
||||
assertEquals("data->'My'->'Nested'->>'Field'",
|
||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested qualified SQLite field")
|
||||
def pathSQLiteNestedQualified(): Unit =
|
||||
assertEquals("bird.data->'Nest'->>'Away'",
|
||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for exists w/o qualifier | PostgreSQL")
|
||||
def toWhereExistsNoQualPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for exists w/o qualifier | SQLite")
|
||||
def toWhereExistsNoQualSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for not-exists w/o qualifier | PostgreSQL")
|
||||
def toWhereNotExistsNoQualPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for not-exists w/o qualifier | SQLite")
|
||||
def toWhereNotExistsNoQualSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, numeric range | PostgreSQL")
|
||||
def toWhereBetweenNoQualNumericPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("(data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").toWhere, "Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, alphanumeric range | PostgreSQL")
|
||||
def toWhereBetweenNoQualAlphaPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'city' BETWEEN :citymin AND :citymax",
|
||||
Field.between("city", "Atlanta", "Chicago", ":city").toWhere, "Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier | SQLite")
|
||||
def toWhereBetweenNoQualSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'age' BETWEEN @agemin AND @agemax", Field.between("age", 13, 17, "@age").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, numeric range | PostgreSQL")
|
||||
def toWhereBetweenQualNumericPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("(test.data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").withQualifier("test").toWhere, "Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, alphanumeric range | PostgreSQL")
|
||||
def toWhereBetweenQualAlphaPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("unit.data->>'city' BETWEEN :citymin AND :citymax",
|
||||
Field.between("city", "Atlanta", "Chicago", ":city").withQualifier("unit").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier | SQLite")
|
||||
def toWhereBetweenQualSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("my.data->>'age' BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").withQualifier("my").toWhere, "Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any, numeric values | PostgreSQL")
|
||||
def toWhereAnyNumericPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)",
|
||||
Field.any("even", List(2, 4, 6).asJava, ":nbr").toWhere, "Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any, alphanumeric values | PostgreSQL")
|
||||
def toWhereAnyAlphaPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||
Field.any("test", List("Atlanta", "Chicago").asJava, ":city").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any | SQLite")
|
||||
def toWhereAnySQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||
Field.any("test", List("Atlanta", "Chicago").asJava, ":city").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for inArray | PostgreSQL")
|
||||
def toWhereInArrayPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]",
|
||||
Field.inArray("even", "tbl", List(2, 4, 6, 8).asJava, ":it").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for inArray | SQLite")
|
||||
def toWhereInArraySQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("EXISTS (SELECT 1 FROM json_each(tbl.data, '$.test') WHERE value IN (:city_0, :city_1))",
|
||||
Field.inArray("test", "tbl", List("Atlanta", "Chicago").asJava, ":city").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for others w/o qualifier | PostgreSQL")
|
||||
def toWhereOtherNoQualPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for others w/o qualifier | SQLite")
|
||||
def toWhereOtherNoQualSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates no-parameter w/ qualifier | PostgreSQL")
|
||||
def toWhereNoParamWithQualPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates no-parameter w/ qualifier | SQLite")
|
||||
def toWhereNoParamWithQualSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates parameter w/ qualifier | PostgreSQL")
|
||||
def toWhereParamWithQualPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("(q.data->>'le_field')::numeric <= :it",
|
||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere, "Field WHERE clause not generated correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates parameter w/ qualifier | SQLite")
|
||||
def toWhereParamWithQualSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("q.data->>'le_field' <= :it",
|
||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere,
|
||||
"Field WHERE clause not generated correctly")
|
||||
|
||||
// ~~~ STATIC CONSTRUCTOR TESTS ~~~
|
||||
|
||||
@Test
|
||||
@DisplayName("equal constructs a field w/o parameter name")
|
||||
def equalCtor(): Unit =
|
||||
val field = Field.equal("Test", 14)
|
||||
assertEquals("Test", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(14, field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("equal constructs a field w/ parameter name")
|
||||
def equalParameterCtor(): Unit =
|
||||
val field = Field.equal("Test", 14, ":w")
|
||||
assertEquals("Test", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(14, field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertEquals(":w", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("greater constructs a field w/o parameter name")
|
||||
def greaterCtor(): Unit =
|
||||
val field = Field.greater("Great", "night")
|
||||
assertEquals("Great", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("night", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("greater constructs a field w/ parameter name")
|
||||
def greaterParameterCtor(): Unit =
|
||||
val field = Field.greater("Great", "night", ":yeah")
|
||||
assertEquals("Great", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("night", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertEquals(":yeah", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("greaterOrEqual constructs a field w/o parameter name")
|
||||
def greaterOrEqualCtor(): Unit =
|
||||
val field = Field.greaterOrEqual("Nice", 88L)
|
||||
assertEquals("Nice", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(88L, field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("greaterOrEqual constructs a field w/ parameter name")
|
||||
def greaterOrEqualParameterCtor(): Unit =
|
||||
val field = Field.greaterOrEqual("Nice", 88L, ":nice")
|
||||
assertEquals("Nice", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(88L, field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertEquals(":nice", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("less constructs a field w/o parameter name")
|
||||
def lessCtor(): Unit =
|
||||
val field = Field.less("Lesser", "seven")
|
||||
assertEquals("Lesser", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("seven", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("less constructs a field w/ parameter name")
|
||||
def lessParameterCtor(): Unit =
|
||||
val field = Field.less("Lesser", "seven", ":max")
|
||||
assertEquals("Lesser", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("seven", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertEquals(":max", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("lessOrEqual constructs a field w/o parameter name")
|
||||
def lessOrEqualCtor(): Unit =
|
||||
val field = Field.lessOrEqual("Nobody", "KNOWS")
|
||||
assertEquals("Nobody", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS_OR_EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("KNOWS", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("lessOrEqual constructs a field w/ parameter name")
|
||||
def lessOrEqualParameterCtor(): Unit =
|
||||
val field = Field.lessOrEqual("Nobody", "KNOWS", ":nope")
|
||||
assertEquals("Nobody", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS_OR_EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("KNOWS", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertEquals(":nope", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("notEqual constructs a field w/o parameter name")
|
||||
def notEqualCtor(): Unit =
|
||||
val field = Field.notEqual("Park", "here")
|
||||
assertEquals("Park", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.NOT_EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("here", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("notEqual constructs a field w/ parameter name")
|
||||
def notEqualParameterCtor(): Unit =
|
||||
val field = Field.notEqual("Park", "here", ":now")
|
||||
assertEquals("Park", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.NOT_EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("here", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertEquals(":now", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("between constructs a field w/o parameter name")
|
||||
def betweenCtor(): Unit =
|
||||
val field = Field.between("Age", 18, 49)
|
||||
assertEquals("Age", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.BETWEEN, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(18, field.getComparison.getValue.getFirst, "Field comparison min value not filled correctly")
|
||||
assertEquals(49, field.getComparison.getValue.getSecond, "Field comparison max value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("between constructs a field w/ parameter name")
|
||||
def betweenParameterCtor(): Unit =
|
||||
val field = Field.between("Age", 18, 49, ":limit")
|
||||
assertEquals("Age", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.BETWEEN, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(18, field.getComparison.getValue.getFirst, "Field comparison min value not filled correctly")
|
||||
assertEquals(49, field.getComparison.getValue.getSecond, "Field comparison max value not filled correctly")
|
||||
assertEquals(":limit", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("any constructs a field w/o parameter name")
|
||||
def anyCtor(): Unit =
|
||||
val field = Field.any("Here", List(8, 16, 32).asJava)
|
||||
assertEquals("Here", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.IN, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(List(8, 16, 32).asJava, field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("any constructs a field w/ parameter name")
|
||||
def anyParameterCtor(): Unit =
|
||||
val field = Field.any("Here", List(8, 16, 32).asJava, ":list")
|
||||
assertEquals("Here", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.IN, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals(List(8, 16, 32).asJava, field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertEquals(":list", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("inArray constructs a field w/o parameter name")
|
||||
def inArrayCtor(): Unit =
|
||||
val field = Field.inArray("ArrayField", "table", List("z").asJava)
|
||||
assertEquals("ArrayField", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.IN_ARRAY, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("table", field.getComparison.getValue.getFirst, "Field comparison table not filled correctly")
|
||||
assertEquals(List("z").asJava, field.getComparison.getValue.getSecond,
|
||||
"Field comparison values not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("inArray constructs a field w/ parameter name")
|
||||
def inArrayParameterCtor(): Unit =
|
||||
val field = Field.inArray("ArrayField", "table", List("z").asJava, ":a")
|
||||
assertEquals("ArrayField", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.IN_ARRAY, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("table", field.getComparison.getValue.getFirst, "Field comparison table not filled correctly")
|
||||
assertEquals(List("z").asJava, field.getComparison.getValue.getSecond,
|
||||
"Field comparison values not filled correctly")
|
||||
assertEquals(":a", field.getParameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("exists constructs a field")
|
||||
def existsCtor(): Unit =
|
||||
val field = Field.exists("Groovy")
|
||||
assertEquals("Groovy", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.EXISTS, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("notExists constructs a field")
|
||||
def notExistsCtor(): Unit =
|
||||
val field = Field.notExists("Groovy")
|
||||
assertEquals("Groovy", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.NOT_EXISTS, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("named constructs a field")
|
||||
def namedCtor(): Unit =
|
||||
val field = Field.named("Tacos")
|
||||
assertEquals("Tacos", field.getName, "Field name not filled correctly")
|
||||
assertEquals(Op.EQUAL, field.getComparison.getOp, "Field comparison operation not filled correctly")
|
||||
assertEquals("", field.getComparison.getValue, "Field comparison value not filled correctly")
|
||||
assertNull(field.getParameterName, "The parameter name should have been null")
|
||||
assertNull(field.getQualifier, "The qualifier should have been null")
|
||||
|
||||
@Test
|
||||
@DisplayName("static constructors fail for invalid parameter name")
|
||||
def staticCtorsFailOnParamName(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => Field.equal("a", "b", "that ain't it, Jack..."))
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple PostgreSQL SQL name")
|
||||
def nameToPathPostgresSimpleSQL(): Unit =
|
||||
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple SQLite SQL name")
|
||||
def nameToPathSQLiteSimpleSQL(): Unit =
|
||||
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested PostgreSQL SQL name")
|
||||
def nameToPathPostgresNestedSQL(): Unit =
|
||||
assertEquals("data#>>'{A,Long,Path,to,the,Property}'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested SQLite SQL name")
|
||||
def nameToPathSQLiteNestedSQL(): Unit =
|
||||
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->>'Property'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple PostgreSQL JSON name")
|
||||
def nameToPathPostgresSimpleJSON(): Unit =
|
||||
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple SQLite JSON name")
|
||||
def nameToPathSQLiteSimpleJSON(): Unit =
|
||||
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested PostgreSQL JSON name")
|
||||
def nameToPathPostgresNestedJSON(): Unit =
|
||||
assertEquals("data#>'{A,Long,Path,to,the,Property}'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested SQLite JSON name")
|
||||
def nameToPathSQLiteNestedJSON(): Unit =
|
||||
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->'Property'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
79
src/scala/src/test/scala/FindQueryTest.scala
Normal file
79
src/scala/src/test/scala/FindQueryTest.scala
Normal file
@@ -0,0 +1,79 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field}
|
||||
import solutions.bitbadger.documents.query.FindQuery
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | FindQuery")
|
||||
class FindQueryTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("all generates correctly")
|
||||
def all(): Unit =
|
||||
assertEquals(s"SELECT data FROM $TEST_TABLE", FindQuery.all(TEST_TABLE), "Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | PostgreSQL")
|
||||
def byIdPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id", FindQuery.byId(TEST_TABLE),
|
||||
"Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | SQLite")
|
||||
def byIdSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id", FindQuery.byId(TEST_TABLE),
|
||||
"Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||
def byFieldsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND (data->>'c')::numeric < :d",
|
||||
FindQuery.byFields(TEST_TABLE, List(Field.equal("a", "", ":b"), Field.less("c", 14, ":d")).asJava),
|
||||
"Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | SQLite")
|
||||
def byFieldsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND data->>'c' < :d",
|
||||
FindQuery.byFields(TEST_TABLE, List(Field.equal("a", "", ":b"), Field.less("c", 14, ":d")).asJava),
|
||||
"Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||
def byContainsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT data FROM $TEST_TABLE WHERE data @> :criteria", FindQuery.byContains(TEST_TABLE),
|
||||
"Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails | SQLite")
|
||||
def byContainsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => FindQuery.byContains(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||
def byJsonPathPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"SELECT data FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
FindQuery.byJsonPath(TEST_TABLE), "Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails | SQLite")
|
||||
def byJsonPathSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => FindQuery.byJsonPath(TEST_TABLE))
|
||||
17
src/scala/src/test/scala/ForceDialect.scala
Normal file
17
src/scala/src/test/scala/ForceDialect.scala
Normal file
@@ -0,0 +1,17 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
|
||||
/**
|
||||
* These functions use a dummy connection string to force the given dialect for a given test
|
||||
*/
|
||||
object ForceDialect:
|
||||
|
||||
def postgres(): Unit =
|
||||
Configuration.setConnectionString(":postgresql:")
|
||||
|
||||
def sqlite(): Unit =
|
||||
Configuration.setConnectionString(":sqlite:")
|
||||
|
||||
def none(): Unit =
|
||||
Configuration.setConnectionString(null)
|
||||
3
src/scala/src/test/scala/IntIdClass.scala
Normal file
3
src/scala/src/test/scala/IntIdClass.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
class IntIdClass(var id: Int)
|
||||
3
src/scala/src/test/scala/LongIdClass.scala
Normal file
3
src/scala/src/test/scala/LongIdClass.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
class LongIdClass(var id: Long)
|
||||
63
src/scala/src/test/scala/OpTest.scala
Normal file
63
src/scala/src/test/scala/OpTest.scala
Normal file
@@ -0,0 +1,63 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.Op
|
||||
|
||||
@DisplayName("Scala | Op")
|
||||
class OpTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("EQUAL uses proper SQL")
|
||||
def equalSQL(): Unit =
|
||||
assertEquals("=", Op.EQUAL.getSql, "The SQL for equal is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("GREATER uses proper SQL")
|
||||
def greaterSQL(): Unit =
|
||||
assertEquals(">", Op.GREATER.getSql, "The SQL for greater is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("GREATER_OR_EQUAL uses proper SQL")
|
||||
def greaterOrEqualSQL(): Unit =
|
||||
assertEquals(">=", Op.GREATER_OR_EQUAL.getSql, "The SQL for greater-or-equal is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("LESS uses proper SQL")
|
||||
def lessSQL(): Unit =
|
||||
assertEquals("<", Op.LESS.getSql, "The SQL for less is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("LESS_OR_EQUAL uses proper SQL")
|
||||
def lessOrEqualSQL(): Unit =
|
||||
assertEquals("<=", Op.LESS_OR_EQUAL.getSql, "The SQL for less-or-equal is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("NOT_EQUAL uses proper SQL")
|
||||
def notEqualSQL(): Unit =
|
||||
assertEquals("<>", Op.NOT_EQUAL.getSql, "The SQL for not-equal is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("BETWEEN uses proper SQL")
|
||||
def betweenSQL(): Unit =
|
||||
assertEquals("BETWEEN", Op.BETWEEN.getSql, "The SQL for between is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("IN uses proper SQL")
|
||||
def inSQL(): Unit =
|
||||
assertEquals("IN", Op.IN.getSql, "The SQL for in is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("IN_ARRAY uses proper SQL")
|
||||
def inArraySQL(): Unit =
|
||||
assertEquals("??|", Op.IN_ARRAY.getSql, "The SQL for in-array is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("EXISTS uses proper SQL")
|
||||
def existsSQL(): Unit =
|
||||
assertEquals("IS NOT NULL", Op.EXISTS.getSql, "The SQL for exists is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("NOT_EXISTS uses proper SQL")
|
||||
def notExistsSQL(): Unit =
|
||||
assertEquals("IS NULL", Op.NOT_EXISTS.getSql, "The SQL for not-exists is incorrect")
|
||||
24
src/scala/src/test/scala/ParameterNameTest.scala
Normal file
24
src/scala/src/test/scala/ParameterNameTest.scala
Normal file
@@ -0,0 +1,24 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.ParameterName
|
||||
|
||||
@DisplayName("Scala | ParameterName")
|
||||
class ParameterNameTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("derive works when given existing names")
|
||||
def withExisting(): Unit =
|
||||
val names = ParameterName()
|
||||
assertEquals(":taco", names.derive(":taco"), "Name should have been :taco")
|
||||
assertEquals(":field0", names.derive(null), "Counter should not have advanced for named field")
|
||||
|
||||
@Test
|
||||
@DisplayName("derive works when given all anonymous fields")
|
||||
def allAnonymous(): Unit =
|
||||
val names = ParameterName()
|
||||
assertEquals(":field0", names.derive(null), "Anonymous field name should have been returned")
|
||||
assertEquals(":field1", names.derive(null), "Counter should have advanced from previous call")
|
||||
assertEquals(":field2", names.derive(null), "Counter should have advanced from previous call")
|
||||
assertEquals(":field3", names.derive(null), "Counter should have advanced from previous call")
|
||||
29
src/scala/src/test/scala/ParameterTest.scala
Normal file
29
src/scala/src/test/scala/ParameterTest.scala
Normal file
@@ -0,0 +1,29 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Parameter, ParameterType}
|
||||
|
||||
@DisplayName("Scala | Parameter")
|
||||
class ParameterTest:
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction with colon-prefixed name")
|
||||
def ctorWithColon(): Unit =
|
||||
val p = Parameter(":test", ParameterType.STRING, "ABC")
|
||||
assertEquals(":test", p.getName, "Parameter name was incorrect")
|
||||
assertEquals(ParameterType.STRING, p.getType, "Parameter type was incorrect")
|
||||
assertEquals("ABC", p.getValue, "Parameter value was incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction with at-sign-prefixed name")
|
||||
def ctorWithAtSign(): Unit =
|
||||
val p = Parameter("@yo", ParameterType.NUMBER, null)
|
||||
assertEquals("@yo", p.getName, "Parameter name was incorrect")
|
||||
assertEquals(ParameterType.NUMBER, p.getType, "Parameter type was incorrect")
|
||||
assertNull(p.getValue, "Parameter value was incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction fails with incorrect prefix")
|
||||
def ctorFailsForPrefix(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => Parameter("it", ParameterType.JSON, ""))
|
||||
100
src/scala/src/test/scala/ParametersTest.scala
Normal file
100
src/scala/src/test/scala/ParametersTest.scala
Normal file
@@ -0,0 +1,100 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field, Parameter, ParameterType}
|
||||
import solutions.bitbadger.documents.scala.Parameters
|
||||
|
||||
@DisplayName("Scala | Parameters")
|
||||
class ParametersTest:
|
||||
|
||||
/**
|
||||
* Reset the dialect
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("nameFields works with no changes")
|
||||
def nameFieldsNoChange(): Unit =
|
||||
val fields = Field.equal("a", "", ":test") :: Field.exists("q") :: Field.equal("b", "", ":me") :: Nil
|
||||
val named = Parameters.nameFields(fields).toList
|
||||
assertEquals(fields.size, named.size, "There should have been 3 fields in the list")
|
||||
assertSame(fields.head, named.head, "The first field should be the same")
|
||||
assertSame(fields(1), named(1), "The second field should be the same")
|
||||
assertSame(fields(2), named(2), "The third field should be the same")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameFields works when changing fields")
|
||||
def nameFieldsChange(): Unit =
|
||||
val fields = Field.equal("a", "") :: Field.equal("e", "", ":hi") :: Field.equal("b", "") ::
|
||||
Field.notExists("z") :: Nil
|
||||
val named = Parameters.nameFields(fields).toList
|
||||
assertEquals(fields.size, named.size, "There should have been 4 fields in the list")
|
||||
assertNotSame(fields.head, named.head, "The first field should not be the same")
|
||||
assertEquals(":field0", named.head.getParameterName, "First parameter name incorrect")
|
||||
assertSame(fields(1), named(1), "The second field should be the same")
|
||||
assertNotSame(fields(2), named(2), "The third field should not be the same")
|
||||
assertEquals(":field1", named(2).getParameterName, "Third parameter name incorrect")
|
||||
assertSame(fields(3), named(3), "The fourth field should be the same")
|
||||
|
||||
@Test
|
||||
@DisplayName("replaceNamesInQuery replaces successfully")
|
||||
def replaceNamesInQuery(): Unit =
|
||||
val parameters = Parameter(":data", ParameterType.JSON, "{}") ::
|
||||
Parameter(":data_ext", ParameterType.STRING, "") :: Nil
|
||||
val query = "SELECT data, data_ext FROM tbl WHERE data = :data AND data_ext = :data_ext AND more_data = :data"
|
||||
assertEquals("SELECT data, data_ext FROM tbl WHERE data = ? AND data_ext = ? AND more_data = ?",
|
||||
Parameters.replaceNamesInQuery(query, parameters), "Parameters not replaced correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("fieldNames generates a single parameter (PostgreSQL)")
|
||||
def fieldNamesSinglePostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
val nameParams = Parameters.fieldNames("test" :: Nil).toList
|
||||
assertEquals(1, nameParams.size, "There should be one name parameter")
|
||||
assertEquals(":name", nameParams.head.getName, "The parameter name is incorrect")
|
||||
assertEquals(ParameterType.STRING, nameParams.head.getType, "The parameter type is incorrect")
|
||||
assertEquals("{test}", nameParams.head.getValue, "The parameter value is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("fieldNames generates multiple parameters (PostgreSQL)")
|
||||
def fieldNamesMultiplePostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
val nameParams = Parameters.fieldNames("test" :: "this" :: "today" :: Nil).toList
|
||||
assertEquals(1, nameParams.size, "There should be one name parameter")
|
||||
assertEquals(":name", nameParams.head.getName, "The parameter name is incorrect")
|
||||
assertEquals(ParameterType.STRING, nameParams.head.getType, "The parameter type is incorrect")
|
||||
assertEquals("{test,this,today}", nameParams.head.getValue, "The parameter value is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("fieldNames generates a single parameter (SQLite)")
|
||||
def fieldNamesSingleSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
val nameParams = Parameters.fieldNames("test" :: Nil).toList
|
||||
assertEquals(1, nameParams.size, "There should be one name parameter")
|
||||
assertEquals(":name0", nameParams.head.getName, "The parameter name is incorrect")
|
||||
assertEquals(ParameterType.STRING, nameParams.head.getType, "The parameter type is incorrect")
|
||||
assertEquals("test", nameParams.head.getValue, "The parameter value is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("fieldNames generates multiple parameters (SQLite)")
|
||||
def fieldNamesMultipleSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
val nameParams = Parameters.fieldNames("test" :: "this" :: "today" :: Nil).toList
|
||||
assertEquals(3, nameParams.size, "There should be one name parameter")
|
||||
assertEquals(":name0", nameParams.head.getName, "The first parameter name is incorrect")
|
||||
assertEquals(ParameterType.STRING, nameParams.head.getType, "The first parameter type is incorrect")
|
||||
assertEquals("test", nameParams.head.getValue, "The first parameter value is incorrect")
|
||||
assertEquals(":name1", nameParams(1).getName, "The second parameter name is incorrect")
|
||||
assertEquals(ParameterType.STRING, nameParams(1).getType, "The second parameter type is incorrect")
|
||||
assertEquals("this", nameParams(1).getValue, "The second parameter value is incorrect")
|
||||
assertEquals(":name2", nameParams(2).getName, "The third parameter name is incorrect")
|
||||
assertEquals(ParameterType.STRING, nameParams(2).getType, "The third parameter type is incorrect")
|
||||
assertEquals("today", nameParams(2).getValue, "The third parameter value is incorrect")
|
||||
|
||||
@Test
|
||||
@DisplayName("fieldNames fails if dialect not set")
|
||||
def fieldNamesFails(): Unit =
|
||||
assertThrows(classOf[DocumentException], () => Parameters.fieldNames(List()))
|
||||
72
src/scala/src/test/scala/PatchQueryTest.scala
Normal file
72
src/scala/src/test/scala/PatchQueryTest.scala
Normal file
@@ -0,0 +1,72 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field}
|
||||
import solutions.bitbadger.documents.query.PatchQuery
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | PatchQuery")
|
||||
class PatchQueryTest:
|
||||
|
||||
/**
|
||||
* Reset the dialect
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | PostgreSQL")
|
||||
def byIdPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data || :data WHERE data->>'id' = :id", PatchQuery.byId(TEST_TABLE),
|
||||
"Patch query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | SQLite")
|
||||
def byIdSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id",
|
||||
PatchQuery.byId(TEST_TABLE), "Patch query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||
def byFieldsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data || :data WHERE data->>'z' = :y",
|
||||
PatchQuery.byFields(TEST_TABLE, List(Field.equal("z", "", ":y")).asJava), "Patch query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | SQLite")
|
||||
def byFieldsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = json_patch(data, json(:data)) WHERE data->>'z' = :y",
|
||||
PatchQuery.byFields(TEST_TABLE, List(Field.equal("z", "", ":y")).asJava), "Patch query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||
def byContainsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data || :data WHERE data @> :criteria",
|
||||
PatchQuery.byContains(TEST_TABLE), "Patch query not constructed correctly" )
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails | SQLite")
|
||||
def byContainsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => PatchQuery.byContains(TEST_TABLE))
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||
def byJsonPathPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
PatchQuery.byJsonPath(TEST_TABLE), "Patch query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails | SQLite")
|
||||
def byJsonPathSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => PatchQuery.byJsonPath(TEST_TABLE))
|
||||
136
src/scala/src/test/scala/QueryUtilsTest.scala
Normal file
136
src/scala/src/test/scala/QueryUtilsTest.scala
Normal file
@@ -0,0 +1,136 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{Dialect, Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.query.QueryUtils
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | Package Functions")
|
||||
class QueryUtilsTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("statementWhere generates correctly")
|
||||
def statementWhere(): Unit =
|
||||
assertEquals("x WHERE y", QueryUtils.statementWhere("x", "y"), "Statements not combined correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates a numeric ID query | PostgreSQL")
|
||||
def byIdNumericPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("test WHERE (data->>'id')::numeric = :id", QueryUtils.byId("test", 9))
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates an alphanumeric ID query | PostgreSQL")
|
||||
def byIdAlphaPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("unit WHERE data->>'id' = :id", QueryUtils.byId("unit", "18"))
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates ID query | SQLite")
|
||||
def byIdSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("yo WHERE data->>'id' = :id", QueryUtils.byId("yo", 27))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates default field query | PostgreSQL")
|
||||
def byFieldsMultipleDefaultPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
|
||||
QueryUtils.byFields("this", List(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")).asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates default field query | SQLite")
|
||||
def byFieldsMultipleDefaultSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
|
||||
QueryUtils.byFields("this", List(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")).asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates ANY field query | PostgreSQL")
|
||||
def byFieldsMultipleAnyPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
|
||||
QueryUtils.byFields("that", List(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")).asJava,
|
||||
FieldMatch.ANY))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates ANY field query | SQLite")
|
||||
def byFieldsMultipleAnySQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
|
||||
QueryUtils.byFields("that", List(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")).asJava,
|
||||
FieldMatch.ANY))
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates for no fields")
|
||||
def orderByNone(): Unit =
|
||||
assertEquals("", QueryUtils.orderBy(List().asJava, Dialect.POSTGRESQL),
|
||||
"ORDER BY should have been blank (PostgreSQL)")
|
||||
assertEquals("", QueryUtils.orderBy(List().asJava, Dialect.SQLITE), "ORDER BY should have been blank (SQLite)")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates single, no direction | PostgreSQL")
|
||||
def orderBySinglePostgres(): Unit =
|
||||
assertEquals(" ORDER BY data->>'TestField'",
|
||||
QueryUtils.orderBy(List(Field.named("TestField")).asJava, Dialect.POSTGRESQL),
|
||||
"ORDER BY not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates single, no direction | SQLite")
|
||||
def orderBySingleSQLite(): Unit =
|
||||
assertEquals(" ORDER BY data->>'TestField'",
|
||||
QueryUtils.orderBy(List(Field.named("TestField")).asJava, Dialect.SQLITE),
|
||||
"ORDER BY not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates multiple with direction | PostgreSQL")
|
||||
def orderByMultiplePostgres(): Unit =
|
||||
assertEquals(" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||
QueryUtils.orderBy(
|
||||
List(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")).asJava,
|
||||
Dialect.POSTGRESQL),
|
||||
"ORDER BY not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates multiple with direction | SQLite")
|
||||
def orderByMultipleSQLite(): Unit =
|
||||
assertEquals(" ORDER BY data->'Nested'->'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||
QueryUtils.orderBy(
|
||||
List(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")).asJava,
|
||||
Dialect.SQLITE),
|
||||
"ORDER BY not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates numeric ordering | PostgreSQL")
|
||||
def orderByNumericPostgres(): Unit =
|
||||
assertEquals(" ORDER BY (data->>'Test')::numeric",
|
||||
QueryUtils.orderBy(List(Field.named("n:Test")).asJava, Dialect.POSTGRESQL), "ORDER BY not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates numeric ordering | SQLite")
|
||||
def orderByNumericSQLite(): Unit =
|
||||
assertEquals(" ORDER BY data->>'Test'", QueryUtils.orderBy(List(Field.named("n:Test")).asJava, Dialect.SQLITE),
|
||||
"ORDER BY not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates case-insensitive ordering | PostgreSQL")
|
||||
def orderByCIPostgres(): Unit =
|
||||
assertEquals(" ORDER BY LOWER(data#>>'{Test,Field}') DESC NULLS FIRST",
|
||||
QueryUtils.orderBy(List(Field.named("i:Test.Field DESC NULLS FIRST")).asJava, Dialect.POSTGRESQL),
|
||||
"ORDER BY not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates case-insensitive ordering | SQLite")
|
||||
def orderByCISQLite(): Unit =
|
||||
assertEquals(" ORDER BY data->'Test'->>'Field' COLLATE NOCASE ASC NULLS LAST",
|
||||
QueryUtils.orderBy(List(Field.named("i:Test.Field ASC NULLS LAST")).asJava, Dialect.SQLITE),
|
||||
"ORDER BY not constructed correctly")
|
||||
82
src/scala/src/test/scala/RemoveFieldsQueryTest.scala
Normal file
82
src/scala/src/test/scala/RemoveFieldsQueryTest.scala
Normal file
@@ -0,0 +1,82 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field, Parameter, ParameterType}
|
||||
import solutions.bitbadger.documents.query.RemoveFieldsQuery
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | RemoveFieldsQuery")
|
||||
class RemoveFieldsQueryTest:
|
||||
|
||||
/**
|
||||
* Reset the dialect
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp(): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | PostgreSQL")
|
||||
def byIdPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE data->>'id' = :id",
|
||||
RemoveFieldsQuery.byId(TEST_TABLE, List(Parameter(":name", ParameterType.STRING, "{a,z}")).asJava),
|
||||
"Remove Fields query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly | SQLite")
|
||||
def byIdSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = json_remove(data, :name0, :name1) WHERE data->>'id' = :id",
|
||||
RemoveFieldsQuery.byId(TEST_TABLE,
|
||||
List(Parameter(":name0", ParameterType.STRING, "a"),Parameter(":name1", ParameterType.STRING, "z")).asJava),
|
||||
"Remove Field query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||
def byFieldsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE data->>'f' > :g",
|
||||
RemoveFieldsQuery.byFields(TEST_TABLE, List(Parameter(":name", ParameterType.STRING, "{b,c}")).asJava,
|
||||
List(Field.greater("f", "", ":g")).asJava),
|
||||
"Remove Field query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly | SQLite")
|
||||
def byFieldsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = json_remove(data, :name0, :name1) WHERE data->>'f' > :g",
|
||||
RemoveFieldsQuery.byFields(TEST_TABLE,
|
||||
List(Parameter(":name0", ParameterType.STRING, "b"), Parameter(":name1", ParameterType.STRING, "c")).asJava,
|
||||
List(Field.greater("f", "", ":g")).asJava),
|
||||
"Remove Field query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||
def byContainsPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE data @> :criteria",
|
||||
RemoveFieldsQuery.byContains(TEST_TABLE, List(Parameter(":name", ParameterType.STRING, "{m,n}")).asJava),
|
||||
"Remove Field query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails | SQLite")
|
||||
def byContainsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => RemoveFieldsQuery.byContains(TEST_TABLE, List().asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||
def byJsonPathPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals(s"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
RemoveFieldsQuery.byJsonPath(TEST_TABLE, List(Parameter(":name", ParameterType.STRING, "{o,p}")).asJava),
|
||||
"Remove Field query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails | SQLite")
|
||||
def byJsonPathSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => RemoveFieldsQuery.byJsonPath(TEST_TABLE, List().asJava))
|
||||
3
src/scala/src/test/scala/ShortIdClass.scala
Normal file
3
src/scala/src/test/scala/ShortIdClass.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
class ShortIdClass(var id: Short)
|
||||
3
src/scala/src/test/scala/StringIdClass.scala
Normal file
3
src/scala/src/test/scala/StringIdClass.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
class StringIdClass(var id: String)
|
||||
141
src/scala/src/test/scala/WhereTest.scala
Normal file
141
src/scala/src/test/scala/WhereTest.scala
Normal file
@@ -0,0 +1,141 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.{AfterEach, DisplayName, Test}
|
||||
import solutions.bitbadger.documents.{DocumentException, Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.query.Where
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
@DisplayName("Scala | Query | Where")
|
||||
class WhereTest:
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
def cleanUp (): Unit =
|
||||
ForceDialect.none()
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields is blank when given no fields")
|
||||
def byFieldsBlankIfEmpty(): Unit =
|
||||
assertEquals("", Where.byFields(List().asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates one numeric field | PostgreSQL")
|
||||
def byFieldsOneFieldPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("(data->>'it')::numeric = :that", Where.byFields(List(Field.equal("it", 9, ":that")).asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates one alphanumeric field | PostgreSQL")
|
||||
def byFieldsOneAlphaFieldPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'it' = :that", Where.byFields(List(Field.equal("it", "", ":that")).asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates one field | SQLite")
|
||||
def byFieldsOneFieldSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'it' = :that", Where.byFields(List(Field.equal("it", "", ":that")).asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ default match | PostgreSQL")
|
||||
def byFieldsMultipleDefaultPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three",
|
||||
Where.byFields(
|
||||
List(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")).asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ default match | SQLite")
|
||||
def byFieldsMultipleDefaultSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three",
|
||||
Where.byFields(
|
||||
List(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")).asJava))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ ANY match | PostgreSQL")
|
||||
def byFieldsMultipleAnyPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three",
|
||||
Where.byFields(
|
||||
List(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")).asJava,
|
||||
FieldMatch.ANY))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ ANY match | SQLite")
|
||||
def byFieldsMultipleAnySQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three",
|
||||
Where.byFields(
|
||||
List(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")).asJava,
|
||||
FieldMatch.ANY))
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates defaults for alphanumeric key | PostgreSQL")
|
||||
def byIdDefaultAlphaPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'id' = :id", Where.byId())
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates defaults for numeric key | PostgreSQL")
|
||||
def byIdDefaultNumericPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("(data->>'id')::numeric = :id", Where.byId(":id", 5))
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates defaults | SQLite")
|
||||
def byIdDefaultSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'id' = :id", Where.byId())
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates named ID | PostgreSQL")
|
||||
def byIdDefaultNamedPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data->>'id' = :key", Where.byId(":key"))
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates named ID | SQLite")
|
||||
def byIdDefaultNamedSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertEquals("data->>'id' = :key", Where.byId(":key"))
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonContains generates defaults | PostgreSQL")
|
||||
def jsonContainsDefaultPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data @> :criteria", Where.jsonContains())
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonContains generates named parameter | PostgreSQL")
|
||||
def jsonContainsNamedPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("data @> :it", Where.jsonContains(":it"))
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonContains fails | SQLite")
|
||||
def jsonContainsFailsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => Where.jsonContains())
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonPathMatches generates defaults | PostgreSQL")
|
||||
def jsonPathMatchDefaultPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("jsonb_path_exists(data, :path::jsonpath)", Where.jsonPathMatches())
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonPathMatches generates named parameter | PostgreSQL")
|
||||
def jsonPathMatchNamedPostgres(): Unit =
|
||||
ForceDialect.postgres()
|
||||
assertEquals("jsonb_path_exists(data, :jp::jsonpath)", Where.jsonPathMatches(":jp"))
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonPathMatches fails | SQLite")
|
||||
def jsonPathFailsSQLite(): Unit =
|
||||
ForceDialect.sqlite()
|
||||
assertThrows(classOf[DocumentException], () => Where.jsonPathMatches())
|
||||
11
src/scala/src/test/scala/integration/ArrayDocument.scala
Normal file
11
src/scala/src/test/scala/integration/ArrayDocument.scala
Normal file
@@ -0,0 +1,11 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
class ArrayDocument(val id: String = "", val values: List[String] = List())
|
||||
|
||||
object ArrayDocument:
|
||||
|
||||
/** A set of documents used for integration tests */
|
||||
val testDocuments: List[ArrayDocument] =
|
||||
ArrayDocument("first", "a" :: "b" :: "c" :: Nil) ::
|
||||
ArrayDocument("second", "c" :: "d" :: "e" :: Nil) ::
|
||||
ArrayDocument("third", "x" :: "y" :: "z" :: Nil) :: Nil
|
||||
42
src/scala/src/test/scala/integration/CountFunctions.scala
Normal file
42
src/scala/src/test/scala/integration/CountFunctions.scala
Normal file
@@ -0,0 +1,42 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
object CountFunctions:
|
||||
|
||||
def all(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should have been 5 documents in the table")
|
||||
|
||||
def byFieldsNumeric(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(3L, db.conn.countByFields(TEST_TABLE, Field.between("numValue", 10, 20) :: Nil),
|
||||
"There should have been 3 matching documents")
|
||||
|
||||
def byFieldsAlpha(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(1L, db.conn.countByFields(TEST_TABLE, Field.between("value", "aardvark", "apple") :: Nil),
|
||||
"There should have been 1 matching document")
|
||||
|
||||
def byContainsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(2L, db.conn.countByContains(TEST_TABLE, Map.Map1("value", "purple")),
|
||||
"There should have been 2 matching documents")
|
||||
|
||||
def byContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(0L, db.conn.countByContains(TEST_TABLE, Map.Map1("value", "magenta")),
|
||||
"There should have been no matching documents")
|
||||
|
||||
def byJsonPathMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(2L, db.conn.countByJsonPath(TEST_TABLE, "$.numValue ? (@ < 5)"),
|
||||
"There should have been 2 matching documents")
|
||||
|
||||
def byJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(0L, db.conn.countByJsonPath(TEST_TABLE, "$.numValue ? (@ > 100)"),
|
||||
"There should have been no matching documents")
|
||||
109
src/scala/src/test/scala/integration/CustomFunctions.scala
Normal file
109
src/scala/src/test/scala/integration/CustomFunctions.scala
Normal file
@@ -0,0 +1,109 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.query.{CountQuery, DeleteQuery, FindQuery, QueryUtils}
|
||||
import solutions.bitbadger.documents.scala.Results
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
import solutions.bitbadger.documents.{Configuration, Field, Parameter, ParameterType}
|
||||
|
||||
import java.io.{PrintWriter, StringWriter}
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
object CustomFunctions:
|
||||
|
||||
def listEmpty(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
db.conn.deleteByFields(TEST_TABLE, Field.exists(Configuration.idField) :: Nil)
|
||||
val result = db.conn.customList[JsonDocument](FindQuery.all(TEST_TABLE), Results.fromData)
|
||||
assertEquals(0, result.size, "There should have been no results")
|
||||
|
||||
def listAll(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val result = db.conn.customList[JsonDocument](FindQuery.all(TEST_TABLE), Results.fromData)
|
||||
assertEquals(5, result.size, "There should have been 5 results")
|
||||
|
||||
def jsonArrayEmpty(db: ThrowawayDatabase): Unit =
|
||||
assertEquals(0L, db.conn.countAll(TEST_TABLE), "The test table should be empty")
|
||||
assertEquals("[]", db.conn.customJsonArray(FindQuery.all(TEST_TABLE), Nil, Results.jsonFromData),
|
||||
"An empty list was not represented correctly")
|
||||
|
||||
def jsonArraySingle(db: ThrowawayDatabase): Unit =
|
||||
db.conn.insert(TEST_TABLE, ArrayDocument("one", "2" :: "3" :: Nil))
|
||||
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"one","values":["2","3"]}]"""),
|
||||
db.conn.customJsonArray(FindQuery.all(TEST_TABLE), Nil, Results.jsonFromData),
|
||||
"A single document list was not represented correctly")
|
||||
|
||||
def jsonArrayMany(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"first","values":["a","b","c"]},"""
|
||||
+ """{"id":"second","values":["c","d","e"]},{"id":"third","values":["x","y","z"]}]"""),
|
||||
db.conn.customJsonArray(FindQuery.all(TEST_TABLE) + QueryUtils.orderBy((Field.named("id") :: Nil).asJava), Nil,
|
||||
Results.jsonFromData),
|
||||
"A multiple document list was not represented correctly")
|
||||
|
||||
def writeJsonArrayEmpty(db: ThrowawayDatabase): Unit =
|
||||
assertEquals(0L, db.conn.countAll(TEST_TABLE), "The test table should be empty")
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeCustomJsonArray(FindQuery.all(TEST_TABLE), Nil, writer, Results.jsonFromData)
|
||||
assertEquals("[]", output.toString, "An empty list was not represented correctly")
|
||||
|
||||
def writeJsonArraySingle(db: ThrowawayDatabase): Unit =
|
||||
db.conn.insert(TEST_TABLE, ArrayDocument("one", "2" :: "3" :: Nil))
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeCustomJsonArray(FindQuery.all(TEST_TABLE), Nil, writer, Results.jsonFromData)
|
||||
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"one","values":["2","3"]}]"""), output.toString,
|
||||
"A single document list was not represented correctly")
|
||||
|
||||
def writeJsonArrayMany(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeCustomJsonArray(FindQuery.all(TEST_TABLE) + QueryUtils.orderBy((Field.named("id") :: Nil).asJava), Nil,
|
||||
writer, Results.jsonFromData)
|
||||
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"first","values":["a","b","c"]},"""
|
||||
+ """{"id":"second","values":["c","d","e"]},{"id":"third","values":["x","y","z"]}]"""),
|
||||
output.toString, "A multiple document list was not represented correctly")
|
||||
|
||||
def singleNone(db: ThrowawayDatabase): Unit =
|
||||
assertTrue(db.conn.customSingle[JsonDocument](FindQuery.all(TEST_TABLE), Results.fromData).isEmpty,
|
||||
"There should not have been a document returned")
|
||||
|
||||
def singleOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertTrue(db.conn.customSingle[JsonDocument](FindQuery.all(TEST_TABLE), Results.fromData).isDefined,
|
||||
"There should have been a document returned")
|
||||
|
||||
def jsonSingleNone(db: ThrowawayDatabase): Unit =
|
||||
assertEquals("{}", db.conn.customJsonSingle(FindQuery.all(TEST_TABLE), Nil, Results.jsonFromData),
|
||||
"An empty document was not represented correctly")
|
||||
|
||||
def jsonSingleOne(db: ThrowawayDatabase): Unit =
|
||||
db.conn.insert(TEST_TABLE, ArrayDocument("me", "myself" :: "i" :: Nil))
|
||||
assertEquals(JsonFunctions.maybeJsonB("{\"id\":\"me\",\"values\":[\"myself\",\"i\"]}"),
|
||||
db.conn.customJsonSingle(FindQuery.all(TEST_TABLE), Nil, Results.jsonFromData),
|
||||
"A single document was not represented correctly")
|
||||
|
||||
def nonQueryChanges(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.customScalar[Long](CountQuery.all(TEST_TABLE), Results.toCount),
|
||||
"There should have been 5 documents in the table")
|
||||
db.conn.customNonQuery(s"DELETE FROM $TEST_TABLE")
|
||||
assertEquals(0L, db.conn.customScalar[Long](CountQuery.all(TEST_TABLE), Results.toCount),
|
||||
"There should have been no documents in the table")
|
||||
|
||||
def nonQueryNoChanges(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.customScalar[Long](CountQuery.all(TEST_TABLE), Results.toCount),
|
||||
"There should have been 5 documents in the table")
|
||||
db.conn.customNonQuery(DeleteQuery.byId(TEST_TABLE, "eighty-two"),
|
||||
Parameter(":id", ParameterType.STRING, "eighty-two") :: Nil)
|
||||
assertEquals(5L, db.conn.customScalar[Long](CountQuery.all(TEST_TABLE), Results.toCount),
|
||||
"There should still have been 5 documents in the table")
|
||||
|
||||
def scalar(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(3L, db.conn.customScalar[Long](s"SELECT 3 AS it FROM $TEST_TABLE LIMIT 1", Results.toCount),
|
||||
"The number 3 should have been returned")
|
||||
@@ -0,0 +1,36 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.DocumentIndex
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
object DefinitionFunctions:
|
||||
|
||||
def ensureTable(db: ThrowawayDatabase): Unit =
|
||||
assertFalse(db.dbObjectExists("ensured"), "The 'ensured' table should not exist")
|
||||
assertFalse(db.dbObjectExists("idx_ensured_key"), "The PK index for the 'ensured' table should not exist")
|
||||
db.conn.ensureTable("ensured")
|
||||
assertTrue(db.dbObjectExists("ensured"), "The 'ensured' table should exist")
|
||||
assertTrue(db.dbObjectExists("idx_ensured_key"), "The PK index for the 'ensured' table should now exist")
|
||||
|
||||
def ensureFieldIndex(db: ThrowawayDatabase): Unit =
|
||||
assertFalse(db.dbObjectExists("idx_${TEST_TABLE}_test"), "The test index should not exist")
|
||||
db.conn.ensureFieldIndex(TEST_TABLE, "test", "id" :: "category" :: Nil)
|
||||
assertTrue(db.dbObjectExists(s"idx_${TEST_TABLE}_test"), "The test index should now exist")
|
||||
|
||||
def ensureDocumentIndexFull(db: ThrowawayDatabase): Unit =
|
||||
assertFalse(db.dbObjectExists("doc_table"), "The 'doc_table' table should not exist")
|
||||
db.conn.ensureTable("doc_table")
|
||||
assertTrue(db.dbObjectExists("doc_table"), "The 'doc_table' table should exist")
|
||||
assertFalse(db.dbObjectExists("idx_doc_table_document"), "The document index should not exist")
|
||||
db.conn.ensureDocumentIndex("doc_table", DocumentIndex.FULL)
|
||||
assertTrue(db.dbObjectExists("idx_doc_table_document"), "The document index should exist")
|
||||
|
||||
def ensureDocumentIndexOptimized(db: ThrowawayDatabase): Unit =
|
||||
assertFalse(db.dbObjectExists("doc_table"), "The 'doc_table' table should not exist")
|
||||
db.conn.ensureTable("doc_table")
|
||||
assertTrue(db.dbObjectExists("doc_table"), "The 'doc_table' table should exist")
|
||||
assertFalse(db.dbObjectExists("idx_doc_table_document"), "The document index should not exist")
|
||||
db.conn.ensureDocumentIndex("doc_table", DocumentIndex.OPTIMIZED)
|
||||
assertTrue(db.dbObjectExists("idx_doc_table_document"), "The document index should exist")
|
||||
56
src/scala/src/test/scala/integration/DeleteFunctions.scala
Normal file
56
src/scala/src/test/scala/integration/DeleteFunctions.scala
Normal file
@@ -0,0 +1,56 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
object DeleteFunctions:
|
||||
|
||||
def byIdMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteById(TEST_TABLE, "four")
|
||||
assertEquals(4L, db.conn.countAll(TEST_TABLE), "There should now be 4 documents in the table")
|
||||
|
||||
def byIdNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteById(TEST_TABLE, "negative four")
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should still be 5 documents in the table")
|
||||
|
||||
def byFieldsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteByFields(TEST_TABLE, Field.notEqual("value", "purple") :: Nil)
|
||||
assertEquals(2L, db.conn.countAll(TEST_TABLE), "There should now be 2 documents in the table")
|
||||
|
||||
def byFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteByFields(TEST_TABLE, Field.equal("value", "crimson") :: Nil)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should still be 5 documents in the table")
|
||||
|
||||
def byContainsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteByContains(TEST_TABLE, Map.Map1("value", "purple"))
|
||||
assertEquals(3L, db.conn.countAll(TEST_TABLE), "There should now be 3 documents in the table")
|
||||
|
||||
def byContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteByContains(TEST_TABLE, Map.Map1("target", "acquired"))
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should still be 5 documents in the table")
|
||||
|
||||
def byJsonPathMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteByJsonPath(TEST_TABLE, "$.value ? (@ == \"purple\")")
|
||||
assertEquals(3L, db.conn.countAll(TEST_TABLE), "There should now be 3 documents in the table")
|
||||
|
||||
def byJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should be 5 documents in the table")
|
||||
db.conn.deleteByJsonPath(TEST_TABLE, "$.numValue ? (@ > 100)")
|
||||
assertEquals(5L, db.conn.countAll(TEST_TABLE), "There should still be 5 documents in the table")
|
||||
108
src/scala/src/test/scala/integration/DocumentFunctions.scala
Normal file
108
src/scala/src/test/scala/integration/DocumentFunctions.scala
Normal file
@@ -0,0 +1,108 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.{AutoId, Configuration, DocumentException, Field}
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
object DocumentFunctions:
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
|
||||
def insertDefault(db: ThrowawayDatabase): Unit =
|
||||
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)
|
||||
assertEquals(1, after.size, "There should be one document in the table")
|
||||
assertEquals(doc, after.head, "The document should be what was inserted")
|
||||
|
||||
def insertDupe(db: ThrowawayDatabase): Unit =
|
||||
db.conn.insert(TEST_TABLE, JsonDocument("a", "", 0, null))
|
||||
assertThrows(classOf[DocumentException], () => db.conn.insert(TEST_TABLE, JsonDocument("a", "b", 22, null)),
|
||||
"Inserting a document with a duplicate key should have thrown an exception")
|
||||
|
||||
def insertNumAutoId(db: ThrowawayDatabase): Unit =
|
||||
try
|
||||
Configuration.autoIdStrategy = AutoId.NUMBER
|
||||
Configuration.idField = "key"
|
||||
assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table")
|
||||
|
||||
db.conn.insert(TEST_TABLE, NumIdDocument(0, "one"))
|
||||
db.conn.insert(TEST_TABLE, NumIdDocument(0, "two"))
|
||||
db.conn.insert(TEST_TABLE, NumIdDocument(77, "three"))
|
||||
db.conn.insert(TEST_TABLE, NumIdDocument(0, "four"))
|
||||
|
||||
val after = db.conn.findAll[NumIdDocument](TEST_TABLE, Field.named("key") :: Nil)
|
||||
assertEquals(4, after.size, "There should have been 4 documents returned")
|
||||
assertEquals("1|2|77|78", after.fold("") { (acc, item) => s"$acc|$item" }, "The IDs were not generated correctly")
|
||||
finally
|
||||
Configuration.autoIdStrategy = AutoId.DISABLED
|
||||
Configuration.idField = "id"
|
||||
|
||||
def insertUUIDAutoId(db: ThrowawayDatabase): Unit =
|
||||
try
|
||||
Configuration.autoIdStrategy = AutoId.UUID
|
||||
assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table")
|
||||
|
||||
db.conn.insert(TEST_TABLE, JsonDocument(""))
|
||||
|
||||
val after = db.conn.findAll[JsonDocument](TEST_TABLE)
|
||||
assertEquals(1, after.size, "There should have been 1 document returned")
|
||||
assertEquals(32, after.head.id.length, "The ID was not generated correctly")
|
||||
finally
|
||||
Configuration.autoIdStrategy = AutoId.DISABLED
|
||||
|
||||
def insertStringAutoId(db: ThrowawayDatabase): Unit =
|
||||
try
|
||||
Configuration.autoIdStrategy = AutoId.RANDOM_STRING
|
||||
assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table")
|
||||
|
||||
db.conn.insert(TEST_TABLE, JsonDocument(""))
|
||||
|
||||
Configuration.idStringLength = 21
|
||||
db.conn.insert(TEST_TABLE, JsonDocument(""))
|
||||
|
||||
val after = db.conn.findAll[JsonDocument](TEST_TABLE)
|
||||
assertEquals(2, after.size, "There should have been 2 documents returned")
|
||||
assertEquals(16, after.head.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")
|
||||
finally
|
||||
Configuration.autoIdStrategy = AutoId.DISABLED
|
||||
Configuration.idStringLength = 16
|
||||
|
||||
def saveMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
db.conn.save(TEST_TABLE, JsonDocument("two", numValue = 44))
|
||||
val tryDoc = db.conn.findById[String, JsonDocument](TEST_TABLE, "two")
|
||||
assertTrue(tryDoc.isDefined, "There should have been a document returned")
|
||||
val doc = tryDoc.get
|
||||
assertEquals("two", doc.id, "An incorrect document was returned")
|
||||
assertEquals("", doc.value, "The \"value\" field was not updated")
|
||||
assertEquals(44, doc.numValue, "The \"numValue\" field was not updated")
|
||||
assertNull(doc.sub, "The \"sub\" field was not updated")
|
||||
|
||||
def saveNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
db.conn.save(TEST_TABLE, JsonDocument("test", sub = SubDocument("a", "b")))
|
||||
assertTrue(db.conn.findById[String, JsonDocument](TEST_TABLE, "test").isDefined,
|
||||
"The test document should have been saved")
|
||||
|
||||
def updateMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
db.conn.update(TEST_TABLE, "one", JsonDocument("one", "howdy", 8, SubDocument("y", "z")))
|
||||
val tryDoc = db.conn.findById[String, JsonDocument](TEST_TABLE, "one")
|
||||
assertTrue(tryDoc.isDefined, "There should have been a document returned")
|
||||
val doc = tryDoc.get
|
||||
assertEquals("one", doc.id, "An incorrect document was returned")
|
||||
assertEquals("howdy", doc.value, "The \"value\" field was not updated")
|
||||
assertEquals(8, doc.numValue, "The \"numValue\" field was not updated")
|
||||
assertNotNull(doc.sub, "The sub-document should not be null")
|
||||
assertEquals("y", doc.sub.foo, "The sub-document \"foo\" field was not updated")
|
||||
assertEquals("z", doc.sub.bar, "The sub-document \"bar\" field was not updated")
|
||||
|
||||
def updateNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsById(TEST_TABLE, "two-hundred"))
|
||||
db.conn.update(TEST_TABLE, "two-hundred", JsonDocument("two-hundred", numValue = 200))
|
||||
assertFalse(db.conn.existsById(TEST_TABLE, "two-hundred"))
|
||||
46
src/scala/src/test/scala/integration/ExistsFunctions.scala
Normal file
46
src/scala/src/test/scala/integration/ExistsFunctions.scala
Normal file
@@ -0,0 +1,46 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
object ExistsFunctions:
|
||||
|
||||
def byIdMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertTrue(db.conn.existsById(TEST_TABLE, "three"), "The document with ID \"three\" should exist")
|
||||
|
||||
def byIdNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsById(TEST_TABLE, "seven"), "The document with ID \"seven\" should not exist")
|
||||
|
||||
def byFieldsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertTrue(db.conn.existsByFields(TEST_TABLE, Field.equal("numValue", 10) :: Nil),
|
||||
"Matching documents should have been found")
|
||||
|
||||
def byFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsByFields(TEST_TABLE, Field.equal("nothing", "none") :: Nil),
|
||||
"No matching documents should have been found")
|
||||
|
||||
def byContainsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertTrue(db.conn.existsByContains(TEST_TABLE, Map.Map1("value", "purple")),
|
||||
"Matching documents should have been found")
|
||||
|
||||
def byContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsByContains(TEST_TABLE, Map.Map1("value", "violet")),
|
||||
"Matching documents should not have been found")
|
||||
|
||||
def byJsonPathMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertTrue(db.conn.existsByJsonPath(TEST_TABLE, "$.numValue ? (@ == 10)"),
|
||||
"Matching documents should have been found")
|
||||
|
||||
def byJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsByJsonPath(TEST_TABLE, "$.numValue ? (@ == 10.1)"),
|
||||
"Matching documents should not have been found")
|
||||
216
src/scala/src/test/scala/integration/FindFunctions.scala
Normal file
216
src/scala/src/test/scala/integration/FindFunctions.scala
Normal file
@@ -0,0 +1,216 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.{Configuration, Field}
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
object FindFunctions:
|
||||
|
||||
/** Generate IDs as a pipe-delimited string */
|
||||
private def docIds(docs: List[JsonDocument]) =
|
||||
docs.map(_.id).reduce((ids, docId) => s"$ids|$docId")
|
||||
|
||||
def allDefault(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(5, db.conn.findAll[JsonDocument](TEST_TABLE).size, "There should have been 5 documents returned")
|
||||
|
||||
def allAscending(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findAll[JsonDocument](TEST_TABLE, Field.named("id") :: Nil)
|
||||
assertEquals(5, docs.size, "There should have been 5 documents returned")
|
||||
assertEquals("five|four|one|three|two", docIds(docs), "The documents were not ordered correctly")
|
||||
|
||||
def allDescending(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findAll[JsonDocument](TEST_TABLE, Field.named("id DESC") :: Nil)
|
||||
assertEquals(5, docs.size, "There should have been 5 documents returned")
|
||||
assertEquals("two|three|one|four|five", docIds(docs), "The documents were not ordered correctly")
|
||||
|
||||
def allNumOrder(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findAll[JsonDocument](TEST_TABLE,
|
||||
Field.named("sub.foo NULLS LAST") :: Field.named("n:numValue") :: Nil)
|
||||
assertEquals(5, docs.size, "There should have been 5 documents returned")
|
||||
assertEquals("two|four|one|three|five", docIds(docs), "The documents were not ordered correctly")
|
||||
|
||||
def allEmpty(db: ThrowawayDatabase): Unit =
|
||||
assertEquals(0, db.conn.findAll[JsonDocument](TEST_TABLE).size, "There should have been no documents returned")
|
||||
|
||||
def byIdString(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findById[String, JsonDocument](TEST_TABLE, "two")
|
||||
assertTrue(doc.isDefined, "The document should have been returned")
|
||||
assertEquals("two", doc.get.id, "An incorrect document was returned")
|
||||
|
||||
def byIdNumber(db: ThrowawayDatabase): Unit =
|
||||
Configuration.idField = "key"
|
||||
try
|
||||
db.conn.insert(TEST_TABLE, NumIdDocument(18, "howdy"))
|
||||
val doc = db.conn.findById[Int, NumIdDocument](TEST_TABLE, 18)
|
||||
assertTrue(doc.isDefined, "The document should have been returned")
|
||||
finally
|
||||
Configuration.idField = "id"
|
||||
|
||||
def byIdNotFound(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.findById[String, JsonDocument](TEST_TABLE, "x").isDefined,
|
||||
"There should have been no document returned")
|
||||
|
||||
def byFieldsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findByFields[JsonDocument](TEST_TABLE,
|
||||
Field.any("value", ("blue" :: "purple" :: Nil).asJava) :: Nil, orderBy = Field.exists("sub") :: Nil)
|
||||
assertEquals(1, docs.size, "There should have been a document returned")
|
||||
assertEquals("four", docs.head.id, "The incorrect document was returned")
|
||||
|
||||
def byFieldsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findByFields[JsonDocument](TEST_TABLE, Field.equal("value", "purple") :: Nil,
|
||||
orderBy = Field.named("id") :: Nil)
|
||||
assertEquals(2, docs.size, "There should have been 2 documents returned")
|
||||
assertEquals("five|four", docIds(docs), "The documents were not ordered correctly")
|
||||
|
||||
def byFieldsMatchNumIn(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findByFields[JsonDocument](TEST_TABLE,
|
||||
Field.any("numValue", (2 :: 4 :: 6 :: 8 :: Nil).asJava) :: Nil)
|
||||
assertEquals(1, docs.size, "There should have been a document returned")
|
||||
assertEquals("three", docs.head.id, "The incorrect document was returned")
|
||||
|
||||
def byFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(0, db.conn.findByFields[JsonDocument](TEST_TABLE, Field.greater("numValue", 100) :: Nil).size,
|
||||
"There should have been no documents returned")
|
||||
|
||||
def byFieldsMatchInArray(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
val docs = db.conn.findByFields[ArrayDocument](TEST_TABLE,
|
||||
Field.inArray("values", TEST_TABLE, ("c" :: Nil).asJava) :: Nil)
|
||||
assertEquals(2, docs.size, "There should have been two documents returned")
|
||||
assertTrue(("first" :: "second" :: Nil).contains(docs.head.id),
|
||||
s"An incorrect document was returned (${docs.head.id}")
|
||||
assertTrue(("first" :: "second" :: Nil).contains(docs(1).id), s"An incorrect document was returned (${docs(1).id})")
|
||||
|
||||
def byFieldsNoMatchInArray(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
assertEquals(0,
|
||||
db.conn.findByFields[ArrayDocument](TEST_TABLE,
|
||||
Field.inArray("values", TEST_TABLE, ("j" :: Nil).asJava) :: Nil).size,
|
||||
"There should have been no documents returned")
|
||||
|
||||
def byContainsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findByContains[JsonDocument, Map.Map1[String, String]](TEST_TABLE, Map.Map1("value", "purple"))
|
||||
assertEquals(2, docs.size, "There should have been 2 documents returned")
|
||||
assertTrue(("four" :: "five" :: Nil).contains(docs.head.id),
|
||||
s"An incorrect document was returned (${docs.head.id})")
|
||||
assertTrue(("four" :: "five" :: Nil).contains(docs(1).id), s"An incorrect document was returned (${docs(1).id})")
|
||||
|
||||
def byContainsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findByContains[JsonDocument, Map.Map1[String, Map.Map1[String, String]]](TEST_TABLE,
|
||||
Map.Map1("sub", Map.Map1("foo", "green")), Field.named("value") :: Nil)
|
||||
assertEquals(2, docs.size, "There should have been 2 documents returned")
|
||||
assertEquals("two|four", docIds(docs), "The documents were not ordered correctly")
|
||||
|
||||
def byContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(0,
|
||||
db.conn.findByContains[JsonDocument, Map.Map1[String, String]](TEST_TABLE, Map.Map1("value", "indigo")).size,
|
||||
"There should have been no documents returned")
|
||||
|
||||
def byJsonPathMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findByJsonPath[JsonDocument](TEST_TABLE, "$.numValue ? (@ > 10)")
|
||||
assertEquals(2, docs.size, "There should have been 2 documents returned")
|
||||
assertTrue(("four" :: "five" :: Nil).contains(docs.head.id),
|
||||
s"An incorrect document was returned (${docs.head.id})")
|
||||
assertTrue(("four" :: "five" :: Nil).contains(docs(1).id), s"An incorrect document was returned (${docs(1).id})")
|
||||
|
||||
def byJsonPathMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val docs = db.conn.findByJsonPath[JsonDocument](TEST_TABLE, "$.numValue ? (@ > 10)", Field.named("id") :: Nil)
|
||||
assertEquals(2, docs.size, "There should have been 2 documents returned")
|
||||
assertEquals("five|four", docIds(docs), "The documents were not ordered correctly")
|
||||
|
||||
def byJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertEquals(0, db.conn.findByJsonPath[JsonDocument](TEST_TABLE, "$.numValue ? (@ > 100)").size,
|
||||
"There should have been no documents returned")
|
||||
|
||||
def firstByFieldsMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByFields[JsonDocument](TEST_TABLE, Field.equal("value", "another") :: Nil)
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("two", doc.get.id, "The incorrect document was returned")
|
||||
|
||||
def firstByFieldsMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByFields[JsonDocument](TEST_TABLE, Field.equal("sub.foo", "green") :: Nil)
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertTrue(("two" :: "four" :: Nil).contains(doc.get.id), s"An incorrect document was returned (${doc.get.id})")
|
||||
|
||||
def firstByFieldsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByFields[JsonDocument](TEST_TABLE, Field.equal("sub.foo", "green") :: Nil,
|
||||
orderBy = Field.named("n:numValue DESC") :: Nil)
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("four", doc.get.id, "An incorrect document was returned")
|
||||
|
||||
def firstByFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.findFirstByFields[JsonDocument](TEST_TABLE, Field.equal("value", "absent") :: Nil).isDefined,
|
||||
"There should have been no document returned")
|
||||
|
||||
def firstByContainsMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByContains[JsonDocument, Map.Map1[String, String]](TEST_TABLE,
|
||||
Map.Map1("value", "FIRST!"))
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("one", doc.get.id, "An incorrect document was returned")
|
||||
|
||||
def firstByContainsMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByContains[JsonDocument, Map.Map1[String, String]](TEST_TABLE,
|
||||
Map.Map1("value", "purple"))
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertTrue(("four" :: "five" :: Nil).contains(doc.get.id), s"An incorrect document was returned (${doc.get.id})")
|
||||
|
||||
def firstByContainsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByContains[JsonDocument, Map.Map1[String, String]](TEST_TABLE,
|
||||
Map.Map1("value", "purple"), Field.named("sub.bar NULLS FIRST") :: Nil)
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("five", doc.get.id, "An incorrect document was returned")
|
||||
|
||||
def firstByContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.findFirstByContains[JsonDocument, Map.Map1[String, String]](TEST_TABLE,
|
||||
Map.Map1("value", "indigo")).isDefined, "There should have been no document returned")
|
||||
|
||||
def firstByJsonPathMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByJsonPath[JsonDocument](TEST_TABLE, "$.numValue ? (@ == 10)")
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("two", doc.get.id, "An incorrect document was returned")
|
||||
|
||||
def firstByJsonPathMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByJsonPath[JsonDocument](TEST_TABLE, "$.numValue ? (@ > 10)")
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertTrue(("four" :: "five" :: Nil).contains(doc.get.id), s"An incorrect document was returned (${doc.get.id})")
|
||||
|
||||
def firstByJsonPathMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val doc = db.conn.findFirstByJsonPath[JsonDocument](TEST_TABLE, "$.numValue ? (@ > 10)",
|
||||
Field.named("id DESC") :: Nil)
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("four", doc.get.id, "An incorrect document was returned")
|
||||
|
||||
def firstByJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.findFirstByJsonPath[JsonDocument](TEST_TABLE, "$.numValue ? (@ > 100)").isDefined,
|
||||
"There should have been no document returned")
|
||||
@@ -0,0 +1,17 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import solutions.bitbadger.documents.DocumentSerializer
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
|
||||
/**
|
||||
* A JSON serializer using Jackson's default options
|
||||
*/
|
||||
class JacksonDocumentSerializer extends DocumentSerializer:
|
||||
|
||||
private val mapper = ObjectMapper()
|
||||
|
||||
override def serialize[TDoc](document: TDoc): String =
|
||||
mapper.writeValueAsString(document)
|
||||
|
||||
override def deserialize[TDoc](json: String, clazz: Class[TDoc]): TDoc =
|
||||
mapper.readValue(json, clazz)
|
||||
34
src/scala/src/test/scala/integration/JsonDocument.scala
Normal file
34
src/scala/src/test/scala/integration/JsonDocument.scala
Normal file
@@ -0,0 +1,34 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import solutions.bitbadger.documents.scala.extensions.insert
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
class JsonDocument(val id: String = "", val value: String = "", val numValue: Int = 0, val sub: SubDocument = null)
|
||||
|
||||
object JsonDocument:
|
||||
|
||||
/** Documents to use for testing */
|
||||
private val testDocuments = List(
|
||||
JsonDocument("one", "FIRST!", 0, null),
|
||||
JsonDocument("two", "another", 10, SubDocument("green", "blue")),
|
||||
JsonDocument("three", "", 4, null),
|
||||
JsonDocument("four", "purple", 17, SubDocument("green", "red")),
|
||||
JsonDocument("five", "purple", 18, null))
|
||||
|
||||
def load(db: ThrowawayDatabase, tableName: String = TEST_TABLE): Unit =
|
||||
testDocuments.foreach { it => db.conn.insert(tableName, it) }
|
||||
|
||||
/** Document ID `one` as a JSON string */
|
||||
val one = """{"id":"one","value":"FIRST!","numValue":0,"sub":null}"""
|
||||
|
||||
/** Document ID `two` as a JSON string */
|
||||
val two = """{"id":"two","value":"another","numValue":10,"sub":{"foo":"green","bar":"blue"}}"""
|
||||
|
||||
/** Document ID `three` as a JSON string */
|
||||
val three = """{"id":"three","value":"","numValue":4,"sub":null}"""
|
||||
|
||||
/** Document ID `four` as a JSON string */
|
||||
val four = """{"id":"four","value":"purple","numValue":17,"sub":{"foo":"green","bar":"red"}}"""
|
||||
|
||||
/** Document ID `five` as a JSON string */
|
||||
val five = """{"id":"five","value":"purple","numValue":18,"sub":null}"""
|
||||
572
src/scala/src/test/scala/integration/JsonFunctions.scala
Normal file
572
src/scala/src/test/scala/integration/JsonFunctions.scala
Normal file
@@ -0,0 +1,572 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.{Configuration, Dialect, Field, FieldMatch}
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
import java.io.{PrintWriter, StringWriter}
|
||||
import scala.jdk.CollectionConverters.*
|
||||
|
||||
/**
|
||||
* Tests for the JSON-returning functions
|
||||
*
|
||||
* NOTE: PostgreSQL JSONB columns do not preserve the original JSON with which a document was stored. These tests are
|
||||
* the most complex within the library, as they have split testing based on the backing data store. The PostgreSQL tests
|
||||
* check IDs (and, in the case of ordered queries, which ones occur before which others) vs. the entire JSON string.
|
||||
* Meanwhile, SQLite stores JSON as text, and will return exactly the JSON it was given when it was originally written.
|
||||
* These tests can ensure the expected round-trip of the entire JSON string.
|
||||
*/
|
||||
object JsonFunctions:
|
||||
|
||||
/**
|
||||
* PostgreSQL, when returning JSONB as a string, has spaces after commas and colons delineating fields and values.
|
||||
* This function will do a crude string replacement to match the target string based on the dialect being tested.
|
||||
*
|
||||
* @param json The JSON which should be returned
|
||||
* @return The actual expected JSON based on the database being tested
|
||||
*/
|
||||
def maybeJsonB(json: String): String =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => json
|
||||
case Dialect.POSTGRESQL => json.replace("\":", "\": ").replace(",\"", ", \"")
|
||||
|
||||
/**
|
||||
* Create a snippet of JSON to find a document ID
|
||||
*
|
||||
* @param id The ID of the document
|
||||
* @return A connection-aware ID to check for presence and positioning
|
||||
*/
|
||||
private def docId(id: String): String =
|
||||
maybeJsonB(s"""{"id":"$id"""")
|
||||
|
||||
private def checkAllDefault(json: String): Unit =
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertTrue(json.contains(JsonDocument.one), s"Document 'one' not found in JSON ($json)")
|
||||
assertTrue(json.contains(JsonDocument.two), s"Document 'two' not found in JSON ($json)")
|
||||
assertTrue(json.contains(JsonDocument.three), s"Document 'three' not found in JSON ($json)")
|
||||
assertTrue(json.contains(JsonDocument.four), s"Document 'four' not found in JSON ($json)")
|
||||
assertTrue(json.contains(JsonDocument.five), s"Document 'five' not found in JSON ($json)")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.contains(docId("one")), s"Document 'one' not found in JSON ($json)")
|
||||
assertTrue(json.contains(docId("two")), s"Document 'two' not found in JSON ($json)")
|
||||
assertTrue(json.contains(docId("three")), s"Document 'three' not found in JSON ($json)")
|
||||
assertTrue(json.contains(docId("four")), s"Document 'four' not found in JSON ($json)")
|
||||
assertTrue(json.contains(docId("five")), s"Document 'five' not found in JSON ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def allDefault(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkAllDefault(db.conn.jsonAll(TEST_TABLE))
|
||||
|
||||
def writeAllDefault(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonAll(TEST_TABLE, writer)
|
||||
checkAllDefault(output.toString)
|
||||
|
||||
private def checkAllEmpty(json: String): Unit =
|
||||
assertEquals("[]", json, "There should have been no documents returned")
|
||||
|
||||
def allEmpty(db: ThrowawayDatabase): Unit =
|
||||
checkAllEmpty(db.conn.jsonAll(TEST_TABLE))
|
||||
|
||||
def writeAllEmpty(db: ThrowawayDatabase): Unit =
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonAll(TEST_TABLE, writer)
|
||||
checkAllEmpty(output.toString)
|
||||
|
||||
private def checkByIdString(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => assertEquals(JsonDocument.two, json, "An incorrect document was returned")
|
||||
case Dialect.POSTGRESQL => assertTrue(json.contains(docId("two")), s"An incorrect document was returned ($json)")
|
||||
|
||||
def byIdString(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByIdString(db.conn.jsonById(TEST_TABLE, "two"))
|
||||
|
||||
def writeByIdString(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonById(TEST_TABLE, writer, "two")
|
||||
checkByIdString(output.toString)
|
||||
|
||||
private def checkByIdNumber(json: String): Unit =
|
||||
assertEquals(maybeJsonB("""{"key":18,"text":"howdy"}"""), json, "The document should have been found by numeric ID")
|
||||
|
||||
def byIdNumber(db: ThrowawayDatabase): Unit =
|
||||
Configuration.idField = "key"
|
||||
try
|
||||
db.conn.insert(TEST_TABLE, NumIdDocument(18, "howdy"))
|
||||
checkByIdNumber(db.conn.jsonById(TEST_TABLE, 18))
|
||||
finally
|
||||
Configuration.idField = "id"
|
||||
|
||||
def writeByIdNumber(db: ThrowawayDatabase): Unit =
|
||||
Configuration.idField = "key"
|
||||
try
|
||||
db.conn.insert(TEST_TABLE, NumIdDocument(18, "howdy"))
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonById(TEST_TABLE, writer, 18)
|
||||
checkByIdNumber(output.toString)
|
||||
finally
|
||||
Configuration.idField = "id"
|
||||
|
||||
private def checkByIdNotFound(json: String): Unit =
|
||||
assertEquals("{}", json, "There should have been no document returned")
|
||||
|
||||
def byIdNotFound(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByIdNotFound(db.conn.jsonById(TEST_TABLE, "x"))
|
||||
|
||||
def writeByIdNotFound(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonById(TEST_TABLE, writer, "x")
|
||||
checkByIdNotFound(output.toString)
|
||||
|
||||
private def checkByFieldsMatch(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertEquals(s"[${JsonDocument.four}]", json, "The incorrect document was returned")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
assertTrue(json.contains(docId("four")), s"The incorrect document was returned ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byFieldsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByFieldsMatch(db.conn.jsonByFields(TEST_TABLE,
|
||||
Field.any("value", ("blue" :: "purple" :: Nil).asJava) :: Field.exists("sub") :: Nil, Some(FieldMatch.ALL)))
|
||||
|
||||
def writeByFieldsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByFields(TEST_TABLE, writer,
|
||||
Field.any("value", ("blue" :: "purple" :: Nil).asJava) :: Field.exists("sub") :: Nil, Some(FieldMatch.ALL))
|
||||
checkByFieldsMatch(output.toString)
|
||||
|
||||
private def checkByFieldsMatchOrdered(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertEquals(s"[${JsonDocument.five},${JsonDocument.four}]", json, "The documents were not ordered correctly")
|
||||
case Dialect.POSTGRESQL =>
|
||||
val fiveIdx = json.indexOf(docId("five"))
|
||||
val fourIdx = json.indexOf(docId("four"))
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
assertTrue(fiveIdx >= 0, s"Document 'five' not found ($json)")
|
||||
assertTrue(fourIdx >= 0, s"Document 'four' not found ($json)")
|
||||
assertTrue(fiveIdx < fourIdx, s"Document 'five' should have been before 'four' ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byFieldsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByFieldsMatchOrdered(db.conn.jsonByFields(TEST_TABLE, Field.equal("value", "purple") :: Nil, None,
|
||||
Field.named("id") :: Nil))
|
||||
|
||||
def writeByFieldsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByFields(TEST_TABLE, writer, Field.equal("value", "purple") :: Nil, None, Field.named("id") :: Nil)
|
||||
checkByFieldsMatchOrdered(output.toString)
|
||||
|
||||
private def checkByFieldsMatchNumIn(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertEquals(s"[${JsonDocument.three}]", json, "The incorrect document was returned")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
assertTrue(json.contains(docId("three")), s"The incorrect document was returned ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byFieldsMatchNumIn(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByFieldsMatchNumIn(db.conn.jsonByFields(TEST_TABLE,
|
||||
Field.any("numValue", (2 :: 4 :: 6 :: 8 :: Nil).asJava) :: Nil))
|
||||
|
||||
def writeByFieldsMatchNumIn(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByFields(TEST_TABLE, writer, Field.any("numValue", (2 :: 4 :: 6 :: 8 :: Nil).asJava) :: Nil)
|
||||
checkByFieldsMatchNumIn(output.toString)
|
||||
|
||||
private def checkByFieldsNoMatch(json: String): Unit =
|
||||
assertEquals("[]", json, "There should have been no documents returned")
|
||||
|
||||
def byFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByFieldsNoMatch(db.conn.jsonByFields(TEST_TABLE, Field.greater("numValue", 100) :: Nil))
|
||||
|
||||
def writeByFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByFields(TEST_TABLE, writer, Field.greater("numValue", 100) :: Nil)
|
||||
checkByFieldsNoMatch(output.toString)
|
||||
|
||||
private def checkByFieldsMatchInArray(json: String): Unit =
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
assertTrue(json.contains(docId("first")), s"The 'first' document was not found ($json)")
|
||||
assertTrue(json.contains(docId("second")), s"The 'second' document was not found ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byFieldsMatchInArray(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
checkByFieldsMatchInArray(db.conn.jsonByFields(TEST_TABLE,
|
||||
Field.inArray("values", TEST_TABLE, ("c" :: Nil).asJava) :: Nil))
|
||||
|
||||
def writeByFieldsMatchInArray(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByFields(TEST_TABLE, writer, Field.inArray("values", TEST_TABLE, ("c" :: Nil).asJava) :: Nil)
|
||||
checkByFieldsMatchInArray(output.toString)
|
||||
|
||||
private def checkByFieldsNoMatchInArray(json: String): Unit =
|
||||
assertEquals("[]", json, "There should have been no documents returned")
|
||||
|
||||
def byFieldsNoMatchInArray(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
checkByFieldsNoMatchInArray(db.conn.jsonByFields(TEST_TABLE,
|
||||
Field.inArray("values", TEST_TABLE, ("j" :: Nil).asJava) :: Nil))
|
||||
|
||||
def writeByFieldsNoMatchInArray(db: ThrowawayDatabase): Unit =
|
||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByFields(TEST_TABLE, writer, Field.inArray("values", TEST_TABLE, ("j" :: Nil).asJava) :: Nil)
|
||||
checkByFieldsNoMatchInArray(output.toString)
|
||||
|
||||
private def checkByContainsMatch(json: String): Unit =
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertTrue(json.contains(JsonDocument.four), s"Document 'four' not found ($json)")
|
||||
assertTrue(json.contains(JsonDocument.five), s"Document 'five' not found ($json)")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.contains(docId("four")), s"Document 'four' not found ($json)")
|
||||
assertTrue(json.contains(docId("five")), s"Document 'five' not found ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byContainsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByContainsMatch(db.conn.jsonByContains(TEST_TABLE, Map.Map1("value", "purple")))
|
||||
|
||||
def writeByContainsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByContains(TEST_TABLE, writer, Map.Map1("value", "purple"))
|
||||
checkByContainsMatch(output.toString)
|
||||
|
||||
private def checkByContainsMatchOrdered(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertEquals(s"[${JsonDocument.two},${JsonDocument.four}]", json, "The documents were not ordered correctly")
|
||||
case Dialect.POSTGRESQL =>
|
||||
val twoIdx = json.indexOf(docId("two"))
|
||||
val fourIdx = json.indexOf(docId("four"))
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
assertTrue(twoIdx >= 0, s"Document 'two' not found ($json)")
|
||||
assertTrue(fourIdx >= 0, s"Document 'four' not found ($json)")
|
||||
assertTrue(twoIdx < fourIdx, s"Document 'two' should have been before 'four' ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byContainsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByContainsMatchOrdered(db.conn.jsonByContains(TEST_TABLE, Map.Map1("sub", Map.Map1("foo", "green")),
|
||||
Field.named("value") :: Nil))
|
||||
|
||||
def writeByContainsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByContains(TEST_TABLE, writer, Map.Map1("sub", Map.Map1("foo", "green")),
|
||||
Field.named("value") :: Nil)
|
||||
checkByContainsMatchOrdered(output.toString)
|
||||
|
||||
private def checkByContainsNoMatch(json: String): Unit =
|
||||
assertEquals("[]", json, "There should have been no documents returned")
|
||||
|
||||
def byContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByContainsNoMatch(db.conn.jsonByContains(TEST_TABLE, Map.Map1("value", "indigo")))
|
||||
|
||||
def writeByContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByContains(TEST_TABLE, writer, Map.Map1("value", "indigo"))
|
||||
checkByContainsNoMatch(output.toString)
|
||||
|
||||
private def checkByJsonPathMatch(json: String): Unit =
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertTrue(json.contains(JsonDocument.four), s"Document 'four' not found ($json)")
|
||||
assertTrue(json.contains(JsonDocument.five), s"Document 'five' not found ($json)")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.contains(docId("four")), s"Document 'four' not found ($json)")
|
||||
assertTrue(json.contains(docId("five")), s"Document 'five' not found ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byJsonPathMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByJsonPathMatch(db.conn.jsonByJsonPath(TEST_TABLE, "$.numValue ? (@ > 10)"))
|
||||
|
||||
def writeByJsonPathMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByJsonPath(TEST_TABLE, writer, "$.numValue ? (@ > 10)")
|
||||
checkByJsonPathMatch(output.toString)
|
||||
|
||||
private def checkByJsonPathMatchOrdered(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertEquals(s"[${JsonDocument.five},${JsonDocument.four}]", json, "The documents were not ordered correctly")
|
||||
case Dialect.POSTGRESQL =>
|
||||
val fiveIdx = json.indexOf(docId("five"))
|
||||
val fourIdx = json.indexOf(docId("four"))
|
||||
assertTrue(json.startsWith("["), s"JSON should start with '[' ($json)")
|
||||
assertTrue(fiveIdx >= 0, s"Document 'five' not found ($json)")
|
||||
assertTrue(fourIdx >= 0, s"Document 'four' not found ($json)")
|
||||
assertTrue(fiveIdx < fourIdx, s"Document 'five' should have been before 'four' ($json)")
|
||||
assertTrue(json.endsWith("]"), s"JSON should end with ']' ($json)")
|
||||
|
||||
def byJsonPathMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByJsonPathMatchOrdered(db.conn.jsonByJsonPath(TEST_TABLE, "$.numValue ? (@ > 10)", Field.named("id") :: Nil))
|
||||
|
||||
def writeByJsonPathMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByJsonPath(TEST_TABLE, writer, "$.numValue ? (@ > 10)", Field.named("id") :: Nil)
|
||||
checkByJsonPathMatchOrdered(output.toString)
|
||||
|
||||
private def checkByJsonPathNoMatch(json: String): Unit =
|
||||
assertEquals("[]", json, "There should have been no documents returned")
|
||||
|
||||
def byJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkByJsonPathNoMatch(db.conn.jsonByJsonPath(TEST_TABLE, "$.numValue ? (@ > 100)"))
|
||||
|
||||
def writeByJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonByJsonPath(TEST_TABLE, writer, "$.numValue ? (@ > 100)")
|
||||
checkByJsonPathNoMatch(output.toString)
|
||||
|
||||
private def checkFirstByFieldsMatchOne(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => assertEquals(JsonDocument.two, json, "The incorrect document was returned")
|
||||
case Dialect.POSTGRESQL => assertTrue(json.contains(docId("two")), s"The incorrect document was returned ($json)")
|
||||
|
||||
def firstByFieldsMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByFieldsMatchOne(db.conn.jsonFirstByFields(TEST_TABLE, Field.equal("value", "another") :: Nil))
|
||||
|
||||
def writeFirstByFieldsMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByFields(TEST_TABLE, writer, Field.equal("value", "another") :: Nil)
|
||||
checkFirstByFieldsMatchOne(output.toString)
|
||||
|
||||
private def checkFirstByFieldsMatchMany(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertTrue(json.contains(JsonDocument.two) || json.contains(JsonDocument.four),
|
||||
s"Expected document 'two' or 'four' ($json)")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.contains(docId("two")) || json.contains(docId("four")),
|
||||
s"Expected document 'two' or 'four' ($json)")
|
||||
|
||||
def firstByFieldsMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByFieldsMatchMany(db.conn.jsonFirstByFields(TEST_TABLE, Field.equal("sub.foo", "green") :: Nil))
|
||||
|
||||
def writeFirstByFieldsMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByFields(TEST_TABLE, writer, Field.equal("sub.foo", "green") :: Nil)
|
||||
checkFirstByFieldsMatchMany(output.toString)
|
||||
|
||||
private def checkFirstByFieldsMatchOrdered(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => assertEquals(JsonDocument.four, json, "An incorrect document was returned")
|
||||
case Dialect.POSTGRESQL => assertTrue(json.contains(docId("four")), s"An incorrect document was returned ($json)")
|
||||
|
||||
def firstByFieldsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByFieldsMatchOrdered(db.conn.jsonFirstByFields(TEST_TABLE, Field.equal("sub.foo", "green") :: Nil, None,
|
||||
Field.named("n:numValue DESC") :: Nil))
|
||||
|
||||
def writeFirstByFieldsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByFields(TEST_TABLE, writer, Field.equal("sub.foo", "green") :: Nil, None,
|
||||
Field.named("n:numValue DESC") :: Nil)
|
||||
|
||||
private def checkFirstByFieldsNoMatch(json: String): Unit =
|
||||
assertEquals("{}", json, "There should have been no document returned")
|
||||
|
||||
def firstByFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByFieldsNoMatch(db.conn.jsonFirstByFields(TEST_TABLE, Field.equal("value", "absent") :: Nil))
|
||||
|
||||
def writeFirstByFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByFields(TEST_TABLE, writer, Field.equal("value", "absent") :: Nil)
|
||||
checkFirstByFieldsNoMatch(output.toString)
|
||||
|
||||
private def checkFirstByContainsMatchOne(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => assertEquals(JsonDocument.one, json, "An incorrect document was returned")
|
||||
case Dialect.POSTGRESQL => assertTrue(json.contains(docId("one")), s"An incorrect document was returned ($json)")
|
||||
|
||||
def firstByContainsMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByContainsMatchOne(db.conn.jsonFirstByContains(TEST_TABLE, Map.Map1("value", "FIRST!")))
|
||||
|
||||
def writeFirstByContainsMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByContains(TEST_TABLE, writer, Map.Map1("value", "FIRST!"))
|
||||
checkFirstByContainsMatchOne(output.toString)
|
||||
|
||||
private def checkFirstByContainsMatchMany(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertTrue(json.contains(JsonDocument.four) || json.contains(JsonDocument.five),
|
||||
s"Expected document 'four' or 'five' ($json)")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.contains(docId("four")) || json.contains(docId("five")),
|
||||
s"Expected document 'four' or 'five' ($json)")
|
||||
|
||||
def firstByContainsMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByContainsMatchMany(db.conn.jsonFirstByContains(TEST_TABLE, Map.Map1("value", "purple")))
|
||||
|
||||
def writeFirstByContainsMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByContains(TEST_TABLE, writer, Map.Map1("value", "purple"))
|
||||
checkFirstByContainsMatchMany(output.toString)
|
||||
|
||||
private def checkFirstByContainsMatchOrdered(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => assertEquals(JsonDocument.five, json, "An incorrect document was returned")
|
||||
case Dialect.POSTGRESQL => assertTrue(json.contains(docId("five")), s"An incorrect document was returned ($json)")
|
||||
|
||||
def firstByContainsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByContainsMatchOrdered(db.conn.jsonFirstByContains(TEST_TABLE, Map.Map1("value", "purple"),
|
||||
Field.named("sub.bar NULLS FIRST") :: Nil))
|
||||
|
||||
def writeFirstByContainsMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByContains(TEST_TABLE, writer, Map.Map1("value", "purple"),
|
||||
Field.named("sub.bar NULLS FIRST") :: Nil)
|
||||
checkFirstByContainsMatchOrdered(output.toString)
|
||||
|
||||
private def checkFirstByContainsNoMatch(json: String): Unit =
|
||||
assertEquals("{}", json, "There should have been no document returned")
|
||||
|
||||
def firstByContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByContainsNoMatch(db.conn.jsonFirstByContains(TEST_TABLE, Map.Map1("value", "indigo")))
|
||||
|
||||
def writeFirstByContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByContains(TEST_TABLE, writer, Map.Map1("value", "indigo"))
|
||||
checkFirstByContainsNoMatch(output.toString)
|
||||
|
||||
private def checkFirstByJsonPathMatchOne(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => assertEquals(JsonDocument.two, json, "An incorrect document was returned")
|
||||
case Dialect.POSTGRESQL => assertTrue(json.contains(docId("two")), s"An incorrect document was returned ($json)")
|
||||
|
||||
def firstByJsonPathMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByJsonPathMatchOne(db.conn.jsonFirstByJsonPath(TEST_TABLE, "$.numValue ? (@ == 10)"))
|
||||
|
||||
def writeFirstByJsonPathMatchOne(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByJsonPath(TEST_TABLE, writer, "$.numValue ? (@ == 10)")
|
||||
checkFirstByJsonPathMatchOne(output.toString)
|
||||
|
||||
private def checkFirstByJsonPathMatchMany(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE =>
|
||||
assertTrue(json.contains(JsonDocument.four) || json.contains(JsonDocument.five),
|
||||
s"Expected document 'four' or 'five' ($json)")
|
||||
case Dialect.POSTGRESQL =>
|
||||
assertTrue(json.contains(docId("four")) || json.contains(docId("five")),
|
||||
s"Expected document 'four' or 'five' ($json)")
|
||||
|
||||
def firstByJsonPathMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByJsonPathMatchMany(db.conn.jsonFirstByJsonPath(TEST_TABLE, "$.numValue ? (@ > 10)"))
|
||||
|
||||
def writeFirstByJsonPathMatchMany(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByJsonPath(TEST_TABLE, writer, "$.numValue ? (@ > 10)")
|
||||
checkFirstByJsonPathMatchMany(output.toString)
|
||||
|
||||
private def checkFirstByJsonPathMatchOrdered(json: String): Unit =
|
||||
Configuration.dialect() match
|
||||
case Dialect.SQLITE => assertEquals(JsonDocument.four, json, "An incorrect document was returned")
|
||||
case Dialect.POSTGRESQL => assertTrue(json.contains(docId("four")), s"An incorrect document was returned ($json)")
|
||||
|
||||
def firstByJsonPathMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByJsonPathMatchOrdered(db.conn.jsonFirstByJsonPath(TEST_TABLE, "$.numValue ? (@ > 10)",
|
||||
Field.named("id DESC") :: Nil))
|
||||
|
||||
def writeFirstByJsonPathMatchOrdered(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByJsonPath(TEST_TABLE, writer, "$.numValue ? (@ > 10)", Field.named("id DESC") :: Nil)
|
||||
checkFirstByJsonPathMatchOrdered(output.toString)
|
||||
|
||||
private def checkFirstByJsonPathNoMatch(json: String): Unit =
|
||||
assertEquals("{}", json, "There should have been no document returned")
|
||||
|
||||
def firstByJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
checkFirstByJsonPathNoMatch(db.conn.jsonFirstByJsonPath(TEST_TABLE, "$.numValue ? (@ > 100)"))
|
||||
|
||||
def writeFirstByJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val output = StringWriter()
|
||||
val writer = PrintWriter(output)
|
||||
db.conn.writeJsonFirstByJsonPath(TEST_TABLE, writer, "$.numValue ? (@ > 100)")
|
||||
checkFirstByJsonPathNoMatch(output.toString)
|
||||
3
src/scala/src/test/scala/integration/NumIdDocument.scala
Normal file
3
src/scala/src/test/scala/integration/NumIdDocument.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
class NumIdDocument(val key: Int = 0, val text: String = "")
|
||||
65
src/scala/src/test/scala/integration/PatchFunctions.scala
Normal file
65
src/scala/src/test/scala/integration/PatchFunctions.scala
Normal file
@@ -0,0 +1,65 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
object PatchFunctions:
|
||||
|
||||
def byIdMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
db.conn.patchById(TEST_TABLE, "one", Map.Map1("numValue", 44))
|
||||
val doc = db.conn.findById[String, JsonDocument](TEST_TABLE, "one")
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("one", doc.get.id, "An incorrect document was returned")
|
||||
assertEquals(44, doc.get.numValue, "The document was not patched")
|
||||
|
||||
def byIdNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsById(TEST_TABLE, "forty-seven"), "Document with ID \"forty-seven\" should not exist")
|
||||
db.conn.patchById(TEST_TABLE, "forty-seven", Map.Map1("foo", "green")) // no exception = pass
|
||||
|
||||
def byFieldsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
db.conn.patchByFields(TEST_TABLE, Field.equal("value", "purple") :: Nil, Map.Map1("numValue", 77))
|
||||
assertEquals(2L, db.conn.countByFields(TEST_TABLE, Field.equal("numValue", 77) :: Nil),
|
||||
"There should have been 2 documents with numeric value 77")
|
||||
|
||||
def byFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val fields = Field.equal("value", "burgundy") :: Nil
|
||||
assertFalse(db.conn.existsByFields(TEST_TABLE, fields), "There should be no documents with value of \"burgundy\"")
|
||||
db.conn.patchByFields(TEST_TABLE, fields, Map.Map1("foo", "green")) // no exception = pass
|
||||
|
||||
def byContainsMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val contains = Map.Map1("value", "another")
|
||||
db.conn.patchByContains(TEST_TABLE, contains, Map.Map1("numValue", 12))
|
||||
val doc = db.conn.findFirstByContains[JsonDocument, Map.Map1[String, String]](TEST_TABLE, contains)
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("two", doc.get.id, "The incorrect document was returned")
|
||||
assertEquals(12, doc.get.numValue, "The document was not updated")
|
||||
|
||||
def byContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val contains = Map.Map1("value", "updated")
|
||||
assertFalse(db.conn.existsByContains(TEST_TABLE, contains), "There should be no matching documents")
|
||||
db.conn.patchByContains(TEST_TABLE, contains, Map.Map1("sub.foo", "green")) // no exception = pass
|
||||
|
||||
def byJsonPathMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val path = "$.numValue ? (@ > 10)"
|
||||
db.conn.patchByJsonPath(TEST_TABLE, path, Map.Map1("value", "blue"))
|
||||
val docs = db.conn.findByJsonPath[JsonDocument](TEST_TABLE, path)
|
||||
assertEquals(2, docs.size, "There should have been two documents returned")
|
||||
docs.foreach { doc =>
|
||||
assertTrue(("four" :: "five" :: Nil).contains(doc.id), s"An incorrect document was returned (${doc.id})")
|
||||
assertEquals("blue", doc.value, s"The value for ID ${doc.id} was incorrect")
|
||||
}
|
||||
|
||||
def byJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val path = "$.numValue ? (@ > 100)"
|
||||
assertFalse(db.conn.existsByJsonPath(TEST_TABLE, path), "There should be no documents with numeric values over 100")
|
||||
db.conn.patchByJsonPath(TEST_TABLE, path, Map.Map1("value", "blue")) // no exception = pass
|
||||
45
src/scala/src/test/scala/integration/PgDB.scala
Normal file
45
src/scala/src/test/scala/integration/PgDB.scala
Normal file
@@ -0,0 +1,45 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import solutions.bitbadger.documents.{Configuration, Parameter, ParameterType}
|
||||
import solutions.bitbadger.documents.scala.Results
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
import java.sql.Connection
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* A wrapper for a throwaway PostgreSQL database
|
||||
*/
|
||||
class PgDB extends ThrowawayDatabase:
|
||||
|
||||
Configuration.setConnectionString(PgDB.connString("postgres"))
|
||||
Using(Configuration.dbConn()) { conn => conn.customNonQuery(s"CREATE DATABASE $dbName") }
|
||||
|
||||
Configuration.setConnectionString(PgDB.connString(dbName))
|
||||
|
||||
override val conn: Connection = Configuration.dbConn()
|
||||
|
||||
conn.ensureTable(TEST_TABLE)
|
||||
|
||||
override def close(): Unit =
|
||||
conn.close()
|
||||
Configuration.setConnectionString(PgDB.connString("postgres"))
|
||||
Using(Configuration.dbConn()) { conn => conn.customNonQuery(s"DROP DATABASE $dbName") }
|
||||
Configuration.setConnectionString(null)
|
||||
|
||||
override def dbObjectExists(name: String): Boolean =
|
||||
conn.customScalar("SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = :name) AS it",
|
||||
Parameter(":name", ParameterType.STRING, name) :: Nil, Results.toExists)
|
||||
|
||||
|
||||
object PgDB:
|
||||
|
||||
/**
|
||||
* Create a connection string for the given database
|
||||
*
|
||||
* @param database The database to which the library should connect
|
||||
* @return The connection string for the database
|
||||
*/
|
||||
private def connString(database: String): String =
|
||||
s"jdbc:postgresql://localhost/$database?user=postgres&password=postgres"
|
||||
43
src/scala/src/test/scala/integration/PostgreSQLCountIT.scala
Normal file
43
src/scala/src/test/scala/integration/PostgreSQLCountIT.scala
Normal file
@@ -0,0 +1,43 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
@DisplayName("Scala | PostgreSQL: Count")
|
||||
class PostgreSQLCountIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("all counts all documents")
|
||||
def all(): Unit =
|
||||
Using(PgDB()) { db => CountFunctions.all(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields counts documents by a numeric value")
|
||||
def byFieldsNumeric(): Unit =
|
||||
Using(PgDB()) { db => CountFunctions.byFieldsNumeric(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields counts documents by a alphanumeric value")
|
||||
def byFieldsAlpha(): Unit =
|
||||
Using(PgDB()) { db => CountFunctions.byFieldsAlpha(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains counts documents when matches are found")
|
||||
def byContainsMatch(): Unit =
|
||||
Using(PgDB()) { db => CountFunctions.byContainsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains counts documents when no matches are found")
|
||||
def byContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => CountFunctions.byContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath counts documents when matches are found")
|
||||
def byJsonPathMatch(): Unit =
|
||||
Using(PgDB()) { db => CountFunctions.byJsonPathMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath counts documents when no matches are found")
|
||||
def byJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => CountFunctions.byJsonPathNoMatch(db) }
|
||||
@@ -0,0 +1,83 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
@DisplayName("Scala | PostgreSQL: Custom")
|
||||
class PostgreSQLCustomIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with empty list")
|
||||
def listEmpty(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.listEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with a non-empty list")
|
||||
def listAll(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.listAll(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonArray succeeds with empty array")
|
||||
def jsonArrayEmpty(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.jsonArrayEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonArray succeeds with a single-item array")
|
||||
def jsonArraySingle(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.jsonArraySingle(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonArray succeeds with a multi-item array")
|
||||
def jsonArrayMany(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.jsonArrayMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeJsonArray succeeds with empty array")
|
||||
def writeJsonArrayEmpty(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.writeJsonArrayEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeJsonArray succeeds with a single-item array")
|
||||
def writeJsonArraySingle(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.writeJsonArraySingle(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeJsonArray succeeds with a multi-item array")
|
||||
def writeJsonArrayMany(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.writeJsonArrayMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when document not found")
|
||||
def singleNone(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.singleNone(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when a document is found")
|
||||
def singleOne(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.singleOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonSingle succeeds when document not found")
|
||||
def jsonSingleNone(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.jsonSingleNone(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonSingle succeeds when a document is found")
|
||||
def jsonSingleOne(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.jsonSingleOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes changes")
|
||||
def nonQueryChanges(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.nonQueryChanges(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes no changes when where clause matches nothing")
|
||||
def nonQueryNoChanges(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.nonQueryNoChanges(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("scalar succeeds")
|
||||
def scalar(): Unit =
|
||||
Using(PgDB()) { db => CustomFunctions.scalar(db) }
|
||||
@@ -0,0 +1,31 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Definition` object / `ensure*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: Definition")
|
||||
class PostgreSQLDefinitionIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable creates table and index")
|
||||
def ensureTable(): Unit =
|
||||
Using(PgDB()) { db => DefinitionFunctions.ensureTable(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureFieldIndex creates an index")
|
||||
def ensureFieldIndex(): Unit =
|
||||
Using(PgDB()) { db => DefinitionFunctions.ensureFieldIndex(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndex creates a full index")
|
||||
def ensureDocumentIndexFull(): Unit =
|
||||
Using(PgDB()) { db => DefinitionFunctions.ensureDocumentIndexFull(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndex creates an optimized index")
|
||||
def ensureDocumentIndexOptimized(): Unit =
|
||||
Using(PgDB()) { db => DefinitionFunctions.ensureDocumentIndexOptimized(db) }
|
||||
@@ -0,0 +1,51 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Delete` object / `deleteBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: Delete")
|
||||
class PostgreSQLDeleteIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId deletes a matching ID")
|
||||
def byIdMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byIdMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds when no ID matches")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields deletes matching documents")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains deletes matching documents")
|
||||
def byContainsMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byContainsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains succeeds when no documents match")
|
||||
def byContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath deletes matching documents")
|
||||
def byJsonPathMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byJsonPathMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath succeeds when no documents match")
|
||||
def byJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => DeleteFunctions.byJsonPathNoMatch(db) }
|
||||
@@ -0,0 +1,56 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: Document")
|
||||
class PostgreSQLDocumentIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("insert works with default values")
|
||||
def insertDefault(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.insertDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert fails with duplicate key")
|
||||
def insertDupe(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.insertDupe(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with numeric auto IDs")
|
||||
def insertNumAutoId(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.insertNumAutoId(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with UUID auto ID")
|
||||
def insertUUIDAutoId(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.insertUUIDAutoId(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with random string auto ID")
|
||||
def insertStringAutoId(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.insertStringAutoId(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("save updates an existing document")
|
||||
def saveMatch(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.saveMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("save inserts a new document")
|
||||
def saveNoMatch(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.saveNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("update replaces an existing document")
|
||||
def updateMatch(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.updateMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("update succeeds when no document exists")
|
||||
def updateNoMatch(): Unit =
|
||||
Using(PgDB()) { db => DocumentFunctions.updateNoMatch(db) }
|
||||
@@ -0,0 +1,51 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Exists` object / `existsBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: Exists")
|
||||
class PostgreSQLExistsIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns true when a document matches the ID")
|
||||
def byIdMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byIdMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns false when no document matches the ID")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields returns true when documents match")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields returns false when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains returns true when documents match")
|
||||
def byContainsMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byContainsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains returns false when no documents match")
|
||||
def byContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath returns true when documents match")
|
||||
def byJsonPathMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byJsonPathMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath returns false when no documents match")
|
||||
def byJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => ExistsFunctions.byJsonPathNoMatch(db) }
|
||||
171
src/scala/src/test/scala/integration/PostgreSQLFindIT.scala
Normal file
171
src/scala/src/test/scala/integration/PostgreSQLFindIT.scala
Normal file
@@ -0,0 +1,171 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Find` object / `find*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: Find")
|
||||
class PostgreSQLFindIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("all retrieves all documents")
|
||||
def allDefault(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.allDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all sorts data ascending")
|
||||
def allAscending(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.allAscending(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all sorts data descending")
|
||||
def allDescending(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.allDescending(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all sorts data numerically")
|
||||
def allNumOrder(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.allNumOrder(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all succeeds with an empty table")
|
||||
def allEmpty(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.allEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a string ID")
|
||||
def byIdString(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byIdString(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a numeric ID")
|
||||
def byIdNumber(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byIdNumber(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns null when a matching ID is not found")
|
||||
def byIdNotFound(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byIdNotFound(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves ordered matching documents")
|
||||
def byFieldsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with a numeric IN clause")
|
||||
def byFieldsMatchNumIn(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byFieldsMatchNumIn(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with an IN_ARRAY comparison")
|
||||
def byFieldsMatchInArray(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byFieldsMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match an IN_ARRAY comparison")
|
||||
def byFieldsNoMatchInArray(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byFieldsNoMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains retrieves matching documents")
|
||||
def byContainsMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byContainsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains retrieves ordered matching documents")
|
||||
def byContainsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byContainsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains succeeds when no documents match")
|
||||
def byContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath retrieves matching documents")
|
||||
def byJsonPathMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byJsonPathMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath retrieves ordered matching documents")
|
||||
def byJsonPathMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byJsonPathMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath succeeds when no documents match")
|
||||
def byJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.byJsonPathNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document")
|
||||
def firstByFieldsMatchOne(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByFieldsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many")
|
||||
def firstByFieldsMatchMany(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByFieldsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many (ordered)")
|
||||
def firstByFieldsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields returns null when no document matches")
|
||||
def firstByFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains retrieves a matching document")
|
||||
def firstByContainsMatchOne(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByContainsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains retrieves a matching document among many")
|
||||
def firstByContainsMatchMany(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByContainsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains retrieves a matching document among many (ordered)")
|
||||
def firstByContainsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByContainsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains returns null when no document matches")
|
||||
def firstByContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath retrieves a matching document")
|
||||
def firstByJsonPathMatchOne(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByJsonPathMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath retrieves a matching document among many")
|
||||
def firstByJsonPathMatchMany(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByJsonPathMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath retrieves a matching document among many (ordered)")
|
||||
def firstByJsonPathMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByJsonPathMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath returns null when no document matches")
|
||||
def firstByJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => FindFunctions.firstByJsonPathNoMatch(db) }
|
||||
301
src/scala/src/test/scala/integration/PostgreSQLJsonIT.scala
Normal file
301
src/scala/src/test/scala/integration/PostgreSQLJsonIT.scala
Normal file
@@ -0,0 +1,301 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Json` object / `json*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: Json")
|
||||
class PostgreSQLJsonIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("all retrieves all documents")
|
||||
def allDefault(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.allDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all succeeds with an empty table")
|
||||
def allEmpty(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.allEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a string ID")
|
||||
def byIdString(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byIdString(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a numeric ID")
|
||||
def byIdNumber(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byIdNumber(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns null when a matching ID is not found")
|
||||
def byIdNotFound(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byIdNotFound(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves ordered matching documents")
|
||||
def byFieldsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with a numeric IN clause")
|
||||
def byFieldsMatchNumIn(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byFieldsMatchNumIn(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with an IN_ARRAY comparison")
|
||||
def byFieldsMatchInArray(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byFieldsMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match an IN_ARRAY comparison")
|
||||
def byFieldsNoMatchInArray(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byFieldsNoMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains retrieves matching documents")
|
||||
def byContainsMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byContainsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains retrieves ordered matching documents")
|
||||
def byContainsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byContainsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains succeeds when no documents match")
|
||||
def byContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath retrieves matching documents")
|
||||
def byJsonPathMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byJsonPathMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath retrieves ordered matching documents")
|
||||
def byJsonPathMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byJsonPathMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath succeeds when no documents match")
|
||||
def byJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.byJsonPathNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document")
|
||||
def firstByFieldsMatchOne(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByFieldsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many")
|
||||
def firstByFieldsMatchMany(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByFieldsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many (ordered)")
|
||||
def firstByFieldsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields returns null when no document matches")
|
||||
def firstByFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains retrieves a matching document")
|
||||
def firstByContainsMatchOne(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByContainsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains retrieves a matching document among many")
|
||||
def firstByContainsMatchMany(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByContainsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains retrieves a matching document among many (ordered)")
|
||||
def firstByContainsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByContainsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains returns null when no document matches")
|
||||
def firstByContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath retrieves a matching document")
|
||||
def firstByJsonPathMatchOne(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByJsonPathMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath retrieves a matching document among many")
|
||||
def firstByJsonPathMatchMany(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByJsonPathMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath retrieves a matching document among many (ordered)")
|
||||
def firstByJsonPathMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByJsonPathMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath returns null when no document matches")
|
||||
def firstByJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.firstByJsonPathNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeAll retrieves all documents")
|
||||
def writeAllDefault(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeAllDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeAll succeeds with an empty table")
|
||||
def writeAllEmpty(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeAllEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeById retrieves a document via a string ID")
|
||||
def writeByIdString(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByIdString(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeById retrieves a document via a numeric ID")
|
||||
def writeByIdNumber(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByIdNumber(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeById returns null when a matching ID is not found")
|
||||
def writeByIdNotFound(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByIdNotFound(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves matching documents")
|
||||
def writeByFieldsMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves ordered matching documents")
|
||||
def writeByFieldsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves matching documents with a numeric IN clause")
|
||||
def writeByFieldsMatchNumIn(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByFieldsMatchNumIn(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields succeeds when no documents match")
|
||||
def writeByFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves matching documents with an IN_ARRAY comparison")
|
||||
def writeByFieldsMatchInArray(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByFieldsMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields succeeds when no documents match an IN_ARRAY comparison")
|
||||
def writeByFieldsNoMatchInArray(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByFieldsNoMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByContains retrieves matching documents")
|
||||
def writeByContainsMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByContainsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByContains retrieves ordered matching documents")
|
||||
def writeByContainsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByContainsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByContains succeeds when no documents match")
|
||||
def writeByContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByJsonPath retrieves matching documents")
|
||||
def writeByJsonPathMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByJsonPathMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByJsonPath retrieves ordered matching documents")
|
||||
def writeByJsonPathMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByJsonPathMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByJsonPath succeeds when no documents match")
|
||||
def writeByJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeByJsonPathNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields retrieves a matching document")
|
||||
def writeFirstByFieldsMatchOne(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByFieldsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields retrieves a matching document among many")
|
||||
def writeFirstByFieldsMatchMany(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByFieldsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields retrieves a matching document among many (ordered)")
|
||||
def writeFirstByFieldsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields returns null when no document matches")
|
||||
def writeFirstByFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByContains retrieves a matching document")
|
||||
def writeFirstByContainsMatchOne(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByContainsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByContains retrieves a matching document among many")
|
||||
def writeFirstByContainsMatchMany(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByContainsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByContains retrieves a matching document among many (ordered)")
|
||||
def writeFirstByContainsMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByContainsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByContains returns null when no document matches")
|
||||
def writeFirstByContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByJsonPath retrieves a matching document")
|
||||
def writeFirstByJsonPathMatchOne(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByJsonPathMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByJsonPath retrieves a matching document among many")
|
||||
def writeFirstByJsonPathMatchMany(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByJsonPathMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByJsonPath retrieves a matching document among many (ordered)")
|
||||
def writeFirstByJsonPathMatchOrdered(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByJsonPathMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByJsonPath returns null when no document matches")
|
||||
def writeFirstByJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => JsonFunctions.writeFirstByJsonPathNoMatch(db) }
|
||||
51
src/scala/src/test/scala/integration/PostgreSQLPatchIT.scala
Normal file
51
src/scala/src/test/scala/integration/PostgreSQLPatchIT.scala
Normal file
@@ -0,0 +1,51 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Patch` object / `patchBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: Patch")
|
||||
class PostgreSQLPatchIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId patches an existing document")
|
||||
def byIdMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byIdMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds for a non-existent document")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields patches matching document")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains patches matching document")
|
||||
def byContainsMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byContainsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains succeeds when no documents match")
|
||||
def byContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath patches matching document")
|
||||
def byJsonPathMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byJsonPathMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath succeeds when no documents match")
|
||||
def byJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => PatchFunctions. byJsonPathNoMatch(db) }
|
||||
@@ -0,0 +1,71 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | PostgreSQL: RemoveFields")
|
||||
class PostgreSQLRemoveFieldsIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId removes fields from an existing document")
|
||||
def byIdMatchFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byIdMatchFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds when fields do not exist on an existing document")
|
||||
def byIdMatchNoFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byIdMatchNoFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds when no document exists")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields removes fields from matching documents")
|
||||
def byFieldsMatchFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byFieldsMatchFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when fields do not exist on matching documents")
|
||||
def byFieldsMatchNoFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byFieldsMatchNoFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no matching documents exist")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains removes fields from matching documents")
|
||||
def byContainsMatchFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byContainsMatchFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains succeeds when fields do not exist on matching documents")
|
||||
def byContainsMatchNoFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byContainsMatchNoFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains succeeds when no matching documents exist")
|
||||
def byContainsNoMatch(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byContainsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath removes fields from matching documents")
|
||||
def byJsonPathMatchFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byJsonPathMatchFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath succeeds when fields do not exist on matching documents")
|
||||
def byJsonPathMatchNoFields(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byJsonPathMatchNoFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath succeeds when no matching documents exist")
|
||||
def byJsonPathNoMatch(): Unit =
|
||||
Using(PgDB()) { db => RemoveFieldsFunctions. byJsonPathNoMatch(db) }
|
||||
@@ -0,0 +1,92 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
object RemoveFieldsFunctions:
|
||||
|
||||
def byIdMatchFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
db.conn.removeFieldsById(TEST_TABLE, "two", "sub" :: "value" :: Nil)
|
||||
val doc = db.conn.findById[String, JsonDocument](TEST_TABLE, "two")
|
||||
assertTrue(doc.isDefined, "There should have been a document returned")
|
||||
assertEquals("", doc.get.value, "The value should have been empty")
|
||||
assertNull(doc.get.sub, "The sub-document should have been removed")
|
||||
|
||||
def byIdMatchNoFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsByFields(TEST_TABLE, Field.exists("a_field_that_does_not_exist") :: Nil))
|
||||
db.conn.removeFieldsById(TEST_TABLE, "one", "a_field_that_does_not_exist" :: Nil) // no exception = pass
|
||||
|
||||
def byIdNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsById(TEST_TABLE, "fifty"))
|
||||
db.conn.removeFieldsById(TEST_TABLE, "fifty", "sub" :: Nil) // no exception = pass
|
||||
|
||||
def byFieldsMatchFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val fields = Field.equal("numValue", 17) :: Nil
|
||||
db.conn.removeFieldsByFields(TEST_TABLE, fields, "sub" :: Nil)
|
||||
val doc = db.conn.findFirstByFields[JsonDocument](TEST_TABLE, fields)
|
||||
assertTrue(doc.isDefined, "The document should have been returned")
|
||||
assertEquals("four", doc.get.id, "An incorrect document was returned")
|
||||
assertNull(doc.get.sub, "The sub-document should have been removed")
|
||||
|
||||
def byFieldsMatchNoFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsByFields(TEST_TABLE, Field.exists("nada") :: Nil))
|
||||
db.conn.removeFieldsByFields(TEST_TABLE, Field.equal("numValue", 17) :: Nil, "nada" :: Nil) // no exn = pass
|
||||
|
||||
def byFieldsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val fields = Field.notEqual("missing", "nope") :: Nil
|
||||
assertFalse(db.conn.existsByFields(TEST_TABLE, fields))
|
||||
db.conn.removeFieldsByFields(TEST_TABLE, fields, "value" :: Nil) // no exception = pass
|
||||
|
||||
def byContainsMatchFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val criteria = Map.Map1("sub", Map.Map1("foo", "green"))
|
||||
db.conn.removeFieldsByContains(TEST_TABLE, criteria, "value" :: Nil)
|
||||
val docs = db.conn.findByContains[JsonDocument, Map.Map1[String, Map.Map1[String, String]]](TEST_TABLE, criteria)
|
||||
assertEquals(2, docs.size, "There should have been 2 documents returned")
|
||||
docs.foreach { doc =>
|
||||
assertTrue(("two" :: "four" :: Nil).contains(doc.id), s"An incorrect document was returned (${doc.id})")
|
||||
assertEquals("", doc.value, "The value should have been empty")
|
||||
}
|
||||
|
||||
def byContainsMatchNoFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsByFields(TEST_TABLE, Field.exists("invalid_field") :: Nil))
|
||||
db.conn.removeFieldsByContains(TEST_TABLE, Map.Map1("sub", Map.Map1("foo", "green")), "invalid_field" :: Nil)
|
||||
// no exception = pass
|
||||
|
||||
def byContainsNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val contains = Map.Map1("value", "substantial")
|
||||
assertFalse(db.conn.existsByContains(TEST_TABLE, contains))
|
||||
db.conn.removeFieldsByContains(TEST_TABLE, contains, "numValue" :: Nil)
|
||||
|
||||
def byJsonPathMatchFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val path = "$.value ? (@ == \"purple\")"
|
||||
db.conn.removeFieldsByJsonPath(TEST_TABLE, path, "sub" :: Nil)
|
||||
val docs = db.conn.findByJsonPath[JsonDocument](TEST_TABLE, path)
|
||||
assertEquals(2, docs.size, "There should have been 2 documents returned")
|
||||
docs.foreach { doc =>
|
||||
assertTrue(("four" :: "five" :: Nil).contains(doc.id), s"An incorrect document was returned (${doc.id})")
|
||||
assertNull(doc.sub, "The sub-document should have been removed")
|
||||
}
|
||||
|
||||
def byJsonPathMatchNoFields(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
assertFalse(db.conn.existsByFields(TEST_TABLE, Field.exists("submarine") :: Nil))
|
||||
db.conn.removeFieldsByJsonPath(TEST_TABLE, "$.value ? (@ == \"purple\")", "submarine" :: Nil) // no exn = pass
|
||||
|
||||
def byJsonPathNoMatch(db: ThrowawayDatabase): Unit =
|
||||
JsonDocument.load(db)
|
||||
val path = "$.value ? (@ == \"mauve\")"
|
||||
assertFalse(db.conn.existsByJsonPath(TEST_TABLE, path))
|
||||
db.conn.removeFieldsByJsonPath(TEST_TABLE, path, "value" :: Nil) // no exception = pass
|
||||
|
||||
35
src/scala/src/test/scala/integration/SQLiteCountIT.scala
Normal file
35
src/scala/src/test/scala/integration/SQLiteCountIT.scala
Normal file
@@ -0,0 +1,35 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
@DisplayName("Scala | SQLite: Count")
|
||||
class SQLiteCountIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("all counts all documents")
|
||||
def all(): Unit =
|
||||
Using(SQLiteDB()) { db => CountFunctions.all(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields counts documents by a numeric value")
|
||||
def byFieldsNumeric(): Unit =
|
||||
Using(SQLiteDB()) { db => CountFunctions.byFieldsNumeric(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields counts documents by a alphanumeric value")
|
||||
def byFieldsAlpha(): Unit =
|
||||
Using(SQLiteDB()) { db => CountFunctions.byFieldsAlpha(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails")
|
||||
def byContainsMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => CountFunctions.byContainsMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails")
|
||||
def byJsonPathMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => CountFunctions.byJsonPathMatch(db)) }
|
||||
83
src/scala/src/test/scala/integration/SQLiteCustomIT.scala
Normal file
83
src/scala/src/test/scala/integration/SQLiteCustomIT.scala
Normal file
@@ -0,0 +1,83 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
@DisplayName("Scala | SQLite: Custom")
|
||||
class SQLiteCustomIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with empty list")
|
||||
def listEmpty(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.listEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("list succeeds with a non-empty list")
|
||||
def listAll(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.listAll(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonArray succeeds with empty array")
|
||||
def jsonArrayEmpty(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.jsonArrayEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonArray succeeds with a single-item array")
|
||||
def jsonArraySingle(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.jsonArraySingle(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonArray succeeds with a multi-item array")
|
||||
def jsonArrayMany(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.jsonArrayMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeJsonArray succeeds with empty array")
|
||||
def writeJsonArrayEmpty(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.writeJsonArrayEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeJsonArray succeeds with a single-item array")
|
||||
def writeJsonArraySingle(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.writeJsonArraySingle(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeJsonArray succeeds with a multi-item array")
|
||||
def writeJsonArrayMany(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.writeJsonArrayMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when document not found")
|
||||
def singleNone(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.singleNone(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("single succeeds when a document is found")
|
||||
def singleOne(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.singleOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonSingle succeeds when document not found")
|
||||
def jsonSingleNone(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.jsonSingleNone(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonSingle succeeds when a document is found")
|
||||
def jsonSingleOne(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.jsonSingleOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes changes")
|
||||
def nonQueryChanges(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.nonQueryChanges(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("nonQuery makes no changes when where clause matches nothing")
|
||||
def nonQueryNoChanges(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.nonQueryNoChanges(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("scalar succeeds")
|
||||
def scalar(): Unit =
|
||||
Using(SQLiteDB()) { db => CustomFunctions.scalar(db) }
|
||||
30
src/scala/src/test/scala/integration/SQLiteDB.scala
Normal file
30
src/scala/src/test/scala/integration/SQLiteDB.scala
Normal file
@@ -0,0 +1,30 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import solutions.bitbadger.documents.{Configuration, Parameter, ParameterType}
|
||||
import solutions.bitbadger.documents.scala.Results
|
||||
import solutions.bitbadger.documents.scala.extensions.*
|
||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||
|
||||
import java.io.File
|
||||
import java.sql.Connection
|
||||
|
||||
/**
|
||||
* A wrapper for a throwaway SQLite database
|
||||
*/
|
||||
class SQLiteDB extends ThrowawayDatabase:
|
||||
|
||||
Configuration.setConnectionString(s"jdbc:sqlite:$dbName.db")
|
||||
|
||||
override val conn: Connection = Configuration.dbConn()
|
||||
|
||||
conn.ensureTable(TEST_TABLE)
|
||||
|
||||
override def close(): Unit =
|
||||
conn.close()
|
||||
File(s"$dbName.db").delete()
|
||||
Configuration.setConnectionString(null)
|
||||
|
||||
override def dbObjectExists(name: String): Boolean =
|
||||
conn.customScalar[Boolean]("SELECT EXISTS (SELECT 1 FROM sqlite_master WHERE name = :name) AS it",
|
||||
Parameter(":name", ParameterType.STRING, name) :: Nil, Results.toExists)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Definition` object / `ensure*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: Definition")
|
||||
class SQLiteDefinitionIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable creates table and index")
|
||||
def ensureTable(): Unit =
|
||||
Using(SQLiteDB()) { db => DefinitionFunctions.ensureTable(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureFieldIndex creates an index")
|
||||
def ensureFieldIndex(): Unit =
|
||||
Using(SQLiteDB()) { db => DefinitionFunctions.ensureFieldIndex(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndex creates a full index")
|
||||
def ensureDocumentIndexFull(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => DefinitionFunctions.ensureDocumentIndexFull(db))
|
||||
}
|
||||
43
src/scala/src/test/scala/integration/SQLiteDeleteIT.scala
Normal file
43
src/scala/src/test/scala/integration/SQLiteDeleteIT.scala
Normal file
@@ -0,0 +1,43 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Delete` object / `deleteBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: Delete")
|
||||
class SQLiteDeleteIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId deletes a matching ID")
|
||||
def byIdMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DeleteFunctions.byIdMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds when no ID matches")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DeleteFunctions.byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields deletes matching documents")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DeleteFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DeleteFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails")
|
||||
def byContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => DeleteFunctions.byContainsMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails")
|
||||
def byJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => DeleteFunctions.byJsonPathMatch(db)) }
|
||||
56
src/scala/src/test/scala/integration/SQLiteDocumentIT.scala
Normal file
56
src/scala/src/test/scala/integration/SQLiteDocumentIT.scala
Normal file
@@ -0,0 +1,56 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: Document")
|
||||
class SQLiteDocumentIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("insert works with default values")
|
||||
def insertDefault(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.insertDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert fails with duplicate key")
|
||||
def insertDupe(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.insertDupe(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with numeric auto IDs")
|
||||
def insertNumAutoId(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.insertNumAutoId(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with UUID auto ID")
|
||||
def insertUUIDAutoId(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.insertUUIDAutoId(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("insert succeeds with random string auto ID")
|
||||
def insertStringAutoId(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.insertStringAutoId(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("save updates an existing document")
|
||||
def saveMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.saveMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("save inserts a new document")
|
||||
def saveNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.saveNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("update replaces an existing document")
|
||||
def updateMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.updateMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("update succeeds when no document exists")
|
||||
def updateNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => DocumentFunctions.updateNoMatch(db) }
|
||||
43
src/scala/src/test/scala/integration/SQLiteExistsIT.scala
Normal file
43
src/scala/src/test/scala/integration/SQLiteExistsIT.scala
Normal file
@@ -0,0 +1,43 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Exists` object / `existsBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: Exists")
|
||||
class SQLiteExistsIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns true when a document matches the ID")
|
||||
def byIdMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => ExistsFunctions.byIdMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns false when no document matches the ID")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => ExistsFunctions.byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields returns true when documents match")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => ExistsFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields returns false when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => ExistsFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails")
|
||||
def byContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => ExistsFunctions.byContainsMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails")
|
||||
def byJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => ExistsFunctions.byJsonPathMatch(db)) }
|
||||
127
src/scala/src/test/scala/integration/SQLiteFindIT.scala
Normal file
127
src/scala/src/test/scala/integration/SQLiteFindIT.scala
Normal file
@@ -0,0 +1,127 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Find` object / `find*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: Find")
|
||||
class SQLiteFindIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("all retrieves all documents")
|
||||
def allDefault(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.allDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all sorts data ascending")
|
||||
def allAscending(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.allAscending(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all sorts data descending")
|
||||
def allDescending(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.allDescending(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all sorts data numerically")
|
||||
def allNumOrder(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.allNumOrder(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all succeeds with an empty table")
|
||||
def allEmpty(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.allEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a string ID")
|
||||
def byIdString(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byIdString(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a numeric ID")
|
||||
def byIdNumber(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byIdNumber(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns null when a matching ID is not found")
|
||||
def byIdNotFound(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byIdNotFound(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves ordered matching documents")
|
||||
def byFieldsMatchOrdered(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with a numeric IN clause")
|
||||
def byFieldsMatchNumIn(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byFieldsMatchNumIn(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with an IN_ARRAY comparison")
|
||||
def byFieldsMatchInArray(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byFieldsMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match an IN_ARRAY comparison")
|
||||
def byFieldsNoMatchInArray(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.byFieldsNoMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails")
|
||||
def byContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => FindFunctions.byContainsMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails")
|
||||
def byJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => FindFunctions.byJsonPathMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document")
|
||||
def firstByFieldsMatchOne(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.firstByFieldsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many")
|
||||
def firstByFieldsMatchMany(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.firstByFieldsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many (ordered)")
|
||||
def firstByFieldsMatchOrdered(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.firstByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields returns null when no document matches")
|
||||
def firstByFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => FindFunctions.firstByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains fails")
|
||||
def firstByContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => FindFunctions.firstByContainsMatchOne(db))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath fails")
|
||||
def firstByJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => FindFunctions.firstByJsonPathMatchOne(db))
|
||||
}
|
||||
211
src/scala/src/test/scala/integration/SQLiteJsonIT.scala
Normal file
211
src/scala/src/test/scala/integration/SQLiteJsonIT.scala
Normal file
@@ -0,0 +1,211 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Json` object / `json*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: Json")
|
||||
class SQLiteJsonIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("all retrieves all documents")
|
||||
def allDefault(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.allDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("all succeeds with an empty table")
|
||||
def allEmpty(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.allEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a string ID")
|
||||
def byIdString(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byIdString(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId retrieves a document via a numeric ID")
|
||||
def byIdNumber(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byIdNumber(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId returns null when a matching ID is not found")
|
||||
def byIdNotFound(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byIdNotFound(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves ordered matching documents")
|
||||
def byFieldsMatchOrdered(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with a numeric IN clause")
|
||||
def byFieldsMatchNumIn(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byFieldsMatchNumIn(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields retrieves matching documents with an IN_ARRAY comparison")
|
||||
def byFieldsMatchInArray(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byFieldsMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match an IN_ARRAY comparison")
|
||||
def byFieldsNoMatchInArray(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.byFieldsNoMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails")
|
||||
def byContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => JsonFunctions.byContainsMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails")
|
||||
def byJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => JsonFunctions.byJsonPathMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document")
|
||||
def firstByFieldsMatchOne(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.firstByFieldsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many")
|
||||
def firstByFieldsMatchMany(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.firstByFieldsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields retrieves a matching document among many (ordered)")
|
||||
def firstByFieldsMatchOrdered(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.firstByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByFields returns null when no document matches")
|
||||
def firstByFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.firstByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByContains fails")
|
||||
def firstByContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => JsonFunctions.firstByContainsMatchOne(db))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("firstByJsonPath fails")
|
||||
def firstByJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => JsonFunctions.firstByJsonPathMatchOne(db))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("writeAll retrieves all documents")
|
||||
def writeAllDefault(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeAllDefault(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeAll succeeds with an empty table")
|
||||
def writeAllEmpty(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeAllEmpty(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeById retrieves a document via a string ID")
|
||||
def writeByIdString(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByIdString(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeById retrieves a document via a numeric ID")
|
||||
def writeByIdNumber(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByIdNumber(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeById returns null when a matching ID is not found")
|
||||
def writeByIdNotFound(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByIdNotFound(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves matching documents")
|
||||
def writeByFieldsMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves ordered matching documents")
|
||||
def writeByFieldsMatchOrdered(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves matching documents with a numeric IN clause")
|
||||
def writeByFieldsMatchNumIn(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByFieldsMatchNumIn(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields succeeds when no documents match")
|
||||
def writeByFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields retrieves matching documents with an IN_ARRAY comparison")
|
||||
def writeByFieldsMatchInArray(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByFieldsMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByFields succeeds when no documents match an IN_ARRAY comparison")
|
||||
def writeByFieldsNoMatchInArray(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeByFieldsNoMatchInArray(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByContains fails")
|
||||
def writeByContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => JsonFunctions.writeByContainsMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeByJsonPath fails")
|
||||
def writeByJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => JsonFunctions.writeByJsonPathMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields retrieves a matching document")
|
||||
def writeFirstByFieldsMatchOne(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeFirstByFieldsMatchOne(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields retrieves a matching document among many")
|
||||
def writeFirstByFieldsMatchMany(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeFirstByFieldsMatchMany(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields retrieves a matching document among many (ordered)")
|
||||
def writeFirstByFieldsMatchOrdered(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeFirstByFieldsMatchOrdered(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByFields returns null when no document matches")
|
||||
def writeFirstByFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => JsonFunctions.writeFirstByFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByContains fails")
|
||||
def writeFirstByContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => JsonFunctions.writeFirstByContainsMatchOne(db))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("writeFirstByJsonPath fails")
|
||||
def writeFirstByJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => JsonFunctions.writeFirstByJsonPathMatchOne(db))
|
||||
}
|
||||
44
src/scala/src/test/scala/integration/SQLitePatchIT.scala
Normal file
44
src/scala/src/test/scala/integration/SQLitePatchIT.scala
Normal file
@@ -0,0 +1,44 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `Patch` object / `patchBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: Patch")
|
||||
class SQLitePatchIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId patches an existing document")
|
||||
def byIdMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => PatchFunctions.byIdMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds for a non-existent document")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => PatchFunctions.byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields patches matching document")
|
||||
def byFieldsMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => PatchFunctions.byFieldsMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no documents match")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => PatchFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails")
|
||||
def byContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => PatchFunctions.byContainsMatch(db)) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails")
|
||||
def byJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db => assertThrows(classOf[DocumentException], () => PatchFunctions.byJsonPathMatch(db)) }
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import org.junit.jupiter.api.{DisplayName, Test}
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
|
||||
import scala.util.Using
|
||||
|
||||
/**
|
||||
* SQLite integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
|
||||
*/
|
||||
@DisplayName("Scala | SQLite: RemoveFields")
|
||||
class SQLiteRemoveFieldsIT:
|
||||
|
||||
@Test
|
||||
@DisplayName("byId removes fields from an existing document")
|
||||
def byIdMatchFields(): Unit =
|
||||
Using(SQLiteDB()) { db => RemoveFieldsFunctions.byIdMatchFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds when fields do not exist on an existing document")
|
||||
def byIdMatchNoFields(): Unit =
|
||||
Using(SQLiteDB()) { db => RemoveFieldsFunctions.byIdMatchNoFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byId succeeds when no document exists")
|
||||
def byIdNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => RemoveFieldsFunctions.byIdNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields removes fields from matching documents")
|
||||
def byFieldsMatchFields(): Unit =
|
||||
Using(SQLiteDB()) { db => RemoveFieldsFunctions.byFieldsMatchFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when fields do not exist on matching documents")
|
||||
def byFieldsMatchNoFields(): Unit =
|
||||
Using(SQLiteDB()) { db => RemoveFieldsFunctions.byFieldsMatchNoFields(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields succeeds when no matching documents exist")
|
||||
def byFieldsNoMatch(): Unit =
|
||||
Using(SQLiteDB()) { db => RemoveFieldsFunctions.byFieldsNoMatch(db) }
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails")
|
||||
def byContainsFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => RemoveFieldsFunctions.byContainsMatchFields(db))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails")
|
||||
def byJsonPathFails(): Unit =
|
||||
Using(SQLiteDB()) { db =>
|
||||
assertThrows(classOf[DocumentException], () => RemoveFieldsFunctions.byJsonPathMatchFields(db))
|
||||
}
|
||||
3
src/scala/src/test/scala/integration/SubDocument.scala
Normal file
3
src/scala/src/test/scala/integration/SubDocument.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
class SubDocument(val foo: String = "", val bar: String = "")
|
||||
28
src/scala/src/test/scala/integration/ThrowawayDatabase.scala
Normal file
28
src/scala/src/test/scala/integration/ThrowawayDatabase.scala
Normal file
@@ -0,0 +1,28 @@
|
||||
package solutions.bitbadger.documents.scala.tests.integration
|
||||
|
||||
import solutions.bitbadger.documents.AutoId
|
||||
import solutions.bitbadger.documents.java.DocumentConfig
|
||||
|
||||
import java.sql.Connection
|
||||
|
||||
/**
|
||||
* Common trait for PostgreSQL and SQLite throwaway databases
|
||||
*/
|
||||
trait ThrowawayDatabase extends AutoCloseable:
|
||||
|
||||
/** The database connection for the throwaway database */
|
||||
def conn: Connection
|
||||
|
||||
/**
|
||||
* Determine if a database object exists
|
||||
*
|
||||
* @param name The name of the object whose existence should be checked
|
||||
* @return True if the object exists, false if not
|
||||
*/
|
||||
def dbObjectExists(name: String): Boolean
|
||||
|
||||
/** The name for the throwaway database */
|
||||
val dbName = s"throwaway_${AutoId.generateRandomString(8)}"
|
||||
|
||||
// Use a Jackson-based document serializer for testing
|
||||
DocumentConfig.setSerializer(JacksonDocumentSerializer())
|
||||
3
src/scala/src/test/scala/package.scala
Normal file
3
src/scala/src/test/scala/package.scala
Normal file
@@ -0,0 +1,3 @@
|
||||
package solutions.bitbadger.documents.scala.tests
|
||||
|
||||
def TEST_TABLE = "test_table"
|
||||
Reference in New Issue
Block a user