Initial Development #1
@ -1,5 +1,7 @@
|
|||||||
package solutions.bitbadger.documents
|
package solutions.bitbadger.documents
|
||||||
|
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A field and its comparison
|
* A field and its comparison
|
||||||
*
|
*
|
||||||
@ -44,6 +46,7 @@ class Field<T> private constructor(
|
|||||||
* @param format Whether the value should be retrieved as JSON or SQL (optional, default SQL)
|
* @param format Whether the value should be retrieved as JSON or SQL (optional, default SQL)
|
||||||
* @return The path for the field
|
* @return The path for the field
|
||||||
*/
|
*/
|
||||||
|
@JvmOverloads
|
||||||
fun path(dialect: Dialect, format: FieldFormat = FieldFormat.SQL): String =
|
fun path(dialect: Dialect, format: FieldFormat = FieldFormat.SQL): String =
|
||||||
(if (qualifier == null) "" else "${qualifier}.") + nameToPath(name, dialect, format)
|
(if (qualifier == null) "" else "${qualifier}.") + nameToPath(name, dialect, format)
|
||||||
|
|
||||||
@ -65,6 +68,7 @@ class Field<T> private constructor(
|
|||||||
* @return The `WHERE` clause for this field
|
* @return The `WHERE` clause for this field
|
||||||
* @throws DocumentException If the field has no parameter name or the database dialect has not been set
|
* @throws DocumentException If the field has no parameter name or the database dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun toWhere(): String {
|
fun toWhere(): String {
|
||||||
if (parameterName == null && !listOf(Op.EXISTS, Op.NOT_EXISTS).contains(comparison.op))
|
if (parameterName == null && !listOf(Op.EXISTS, Op.NOT_EXISTS).contains(comparison.op))
|
||||||
throw DocumentException("Parameter for $name must be specified")
|
throw DocumentException("Parameter for $name must be specified")
|
||||||
|
@ -28,7 +28,9 @@ object CountQuery {
|
|||||||
* @param fields The field comparisons for the count
|
* @param fields The field comparisons for the count
|
||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to count documents matching the given fields
|
* @return A query to count documents matching the given fields
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
|
@ -27,7 +27,9 @@ object DeleteQuery {
|
|||||||
* @param tableName The table from which documents should be deleted (may include schema)
|
* @param tableName The table from which documents should be deleted (may include schema)
|
||||||
* @param docId The ID of the document (optional, used for type checking)
|
* @param docId The ID of the document (optional, used for type checking)
|
||||||
* @return A query to delete a document by its ID
|
* @return A query to delete a document by its ID
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
@ -40,7 +42,9 @@ object DeleteQuery {
|
|||||||
* @param fields The field comparisons for documents to be deleted
|
* @param fields The field comparisons for documents to be deleted
|
||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to delete documents matching for the given fields
|
* @return A query to delete documents matching for the given fields
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
|
@ -26,7 +26,9 @@ object ExistsQuery {
|
|||||||
* @param tableName The table in which existence should be checked (may include schema)
|
* @param tableName The table in which existence should be checked (may include schema)
|
||||||
* @param docId The ID of the document (optional, used for type checking)
|
* @param docId The ID of the document (optional, used for type checking)
|
||||||
* @return A query to determine document existence by ID
|
* @return A query to determine document existence by ID
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
@ -39,7 +41,9 @@ object ExistsQuery {
|
|||||||
* @param fields The field comparisons for the existence check
|
* @param fields The field comparisons for the existence check
|
||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to determine document existence for the given fields
|
* @return A query to determine document existence for the given fields
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
|
@ -28,7 +28,9 @@ object FindQuery {
|
|||||||
* @param tableName The table from which documents should be retrieved (may include schema)
|
* @param tableName The table from which documents should be retrieved (may include schema)
|
||||||
* @param docId The ID of the document (optional, used for type checking)
|
* @param docId The ID of the document (optional, used for type checking)
|
||||||
* @return A query to retrieve a document by its ID
|
* @return A query to retrieve a document by its ID
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
@ -41,7 +43,9 @@ object FindQuery {
|
|||||||
* @param fields The field comparisons for matching documents to retrieve
|
* @param fields The field comparisons for matching documents to retrieve
|
||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to retrieve documents matching the given fields
|
* @return A query to retrieve documents matching the given fields
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
@file:JvmName("QueryUtils")
|
@file:JvmName("QueryUtils")
|
||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
import solutions.bitbadger.documents.Configuration
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.Dialect
|
import kotlin.jvm.Throws
|
||||||
import solutions.bitbadger.documents.Field
|
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
|
||||||
|
|
||||||
// ~~~ TOP-LEVEL FUNCTIONS FOR THE QUERY PACKAGE ~~~
|
// ~~~ TOP-LEVEL FUNCTIONS FOR THE QUERY PACKAGE ~~~
|
||||||
|
|
||||||
@ -24,7 +22,9 @@ fun statementWhere(statement: String, where: String) =
|
|||||||
* @param statement The SQL statement to be run against a document by its ID
|
* @param statement The SQL statement to be run against a document by its ID
|
||||||
* @param docId The ID of the document targeted
|
* @param docId The ID of the document targeted
|
||||||
* @returns A query addressing a document by its ID
|
* @returns A query addressing a document by its ID
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun <TKey> byId(statement: String, docId: TKey) =
|
fun <TKey> byId(statement: String, docId: TKey) =
|
||||||
statementWhere(statement, Where.byId(docId = docId))
|
statementWhere(statement, Where.byId(docId = docId))
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ fun <TKey> byId(statement: String, docId: TKey) =
|
|||||||
* @param howMatched Whether to match any or all of the field conditions (optional; default ALL)
|
* @param howMatched Whether to match any or all of the field conditions (optional; default ALL)
|
||||||
* @return A query addressing documents by field matching conditions
|
* @return A query addressing documents by field matching conditions
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(statement: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(statement: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
statementWhere(statement, Where.byFields(fields, howMatched))
|
statementWhere(statement, Where.byFields(fields, howMatched))
|
||||||
@ -47,6 +48,7 @@ fun byFields(statement: String, fields: Collection<Field<*>>, howMatched: FieldM
|
|||||||
* @param dialect The SQL dialect for the generated clause
|
* @param dialect The SQL dialect for the generated clause
|
||||||
* @return An `ORDER BY` clause for the given fields
|
* @return An `ORDER BY` clause for the given fields
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun orderBy(fields: Collection<Field<*>>, dialect: Dialect? = null): String {
|
fun orderBy(fields: Collection<Field<*>>, dialect: Dialect? = null): String {
|
||||||
val mode = dialect ?: Configuration.dialect("generate ORDER BY clause")
|
val mode = dialect ?: Configuration.dialect("generate ORDER BY clause")
|
||||||
|
@ -18,7 +18,9 @@ object Where {
|
|||||||
* @param fields The fields to be queried
|
* @param fields The fields to be queried
|
||||||
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
||||||
* @return A `WHERE` clause fragment to match the given fields
|
* @return A `WHERE` clause fragment to match the given fields
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
@ -29,7 +31,10 @@ object Where {
|
|||||||
*
|
*
|
||||||
* @param parameterName The parameter name to use for the ID placeholder (optional, defaults to ":id")
|
* @param parameterName The parameter name to use for the ID placeholder (optional, defaults to ":id")
|
||||||
* @param docId The ID value (optional; used for type determinations, string assumed if not provided)
|
* @param docId The ID value (optional; used for type determinations, string assumed if not provided)
|
||||||
|
* @return A `WHERE` clause fragment to match the document's ID
|
||||||
|
* @throws DocumentException If the dialect has not been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <TKey> byId(parameterName: String = ":id", docId: TKey? = null) =
|
fun <TKey> byId(parameterName: String = ":id", docId: TKey? = null) =
|
||||||
|
@ -5,6 +5,7 @@ import org.junit.jupiter.api.AfterEach;
|
|||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import solutions.bitbadger.documents.*;
|
import solutions.bitbadger.documents.*;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -22,7 +23,7 @@ final public class FieldTest {
|
|||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
Configuration.setConnectionString(null);
|
ForceDialect.none();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~~~ INSTANCE METHODS ~~~
|
// ~~~ INSTANCE METHODS ~~~
|
||||||
@ -71,7 +72,7 @@ final public class FieldTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for simple unqualified PostgreSQL field")
|
@DisplayName("path generates for simple unqualified field | PostgreSQL")
|
||||||
public void pathPostgresSimpleUnqualified() {
|
public void pathPostgresSimpleUnqualified() {
|
||||||
assertEquals("data->>'SomethingCool'",
|
assertEquals("data->>'SomethingCool'",
|
||||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||||
@ -79,7 +80,7 @@ final public class FieldTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for simple qualified PostgreSQL field")
|
@DisplayName("path generates for simple qualified field | PostgreSQL")
|
||||||
public void pathPostgresSimpleQualified() {
|
public void pathPostgresSimpleQualified() {
|
||||||
assertEquals("this.data->>'SomethingElse'",
|
assertEquals("this.data->>'SomethingElse'",
|
||||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||||
@ -87,14 +88,14 @@ final public class FieldTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for nested unqualified PostgreSQL field")
|
@DisplayName("path generates for nested unqualified field | PostgreSQL")
|
||||||
public void pathPostgresNestedUnqualified() {
|
public void pathPostgresNestedUnqualified() {
|
||||||
assertEquals("data#>>'{My,Nested,Field}'",
|
assertEquals("data#>>'{My,Nested,Field}'",
|
||||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct");
|
Field.equal("My.Nested.Field", "howdy").path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for nested qualified PostgreSQL field")
|
@DisplayName("path generates for nested qualified field | PostgreSQL")
|
||||||
public void pathPostgresNestedQualified() {
|
public void pathPostgresNestedQualified() {
|
||||||
assertEquals("bird.data#>>'{Nest,Away}'",
|
assertEquals("bird.data#>>'{Nest,Away}'",
|
||||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||||
@ -102,14 +103,14 @@ final public class FieldTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for simple unqualified SQLite field")
|
@DisplayName("path generates for simple unqualified field | SQLite")
|
||||||
public void pathSQLiteSimpleUnqualified() {
|
public void pathSQLiteSimpleUnqualified() {
|
||||||
assertEquals("data->>'SomethingCool'",
|
assertEquals("data->>'SomethingCool'",
|
||||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct");
|
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for simple qualified SQLite field")
|
@DisplayName("path generates for simple qualified field | SQLite")
|
||||||
public void pathSQLiteSimpleQualified() {
|
public void pathSQLiteSimpleQualified() {
|
||||||
assertEquals("this.data->>'SomethingElse'",
|
assertEquals("this.data->>'SomethingElse'",
|
||||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.SQLITE, FieldFormat.SQL),
|
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||||
@ -117,14 +118,14 @@ final public class FieldTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for nested unqualified SQLite field")
|
@DisplayName("path generates for nested unqualified field | SQLite")
|
||||||
public void pathSQLiteNestedUnqualified() {
|
public void pathSQLiteNestedUnqualified() {
|
||||||
assertEquals("data->'My'->'Nested'->>'Field'",
|
assertEquals("data->'My'->'Nested'->>'Field'",
|
||||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct");
|
Field.equal("My.Nested.Field", "howdy").path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("path generates for nested qualified SQLite field")
|
@DisplayName("path generates for nested qualified field | SQLite")
|
||||||
public void pathSQLiteNestedQualified() {
|
public void pathSQLiteNestedQualified() {
|
||||||
assertEquals("bird.data->'Nest'->>'Away'",
|
assertEquals("bird.data->'Nest'->>'Away'",
|
||||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.SQLITE, FieldFormat.SQL),
|
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||||
@ -132,190 +133,196 @@ final public class FieldTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for exists w/o qualifier (PostgreSQL)")
|
@DisplayName("toWhere generates for exists w/o qualifier | PostgreSQL")
|
||||||
public void toWhereExistsNoQualPostgres() {
|
public void toWhereExistsNoQualPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for exists w/o qualifier (SQLite)")
|
@DisplayName("toWhere generates for exists w/o qualifier | SQLite")
|
||||||
public void toWhereExistsNoQualSQLite() {
|
public void toWhereExistsNoQualSQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for not-exists w/o qualifier (PostgreSQL)")
|
@DisplayName("toWhere generates for not-exists w/o qualifier | PostgreSQL")
|
||||||
public void toWhereNotExistsNoQualPostgres() {
|
public void toWhereNotExistsNoQualPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for not-exists w/o qualifier (SQLite)")
|
@DisplayName("toWhere generates for not-exists w/o qualifier | SQLite")
|
||||||
public void toWhereNotExistsNoQualSQLite() {
|
public void toWhereNotExistsNoQualSQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, numeric range (PostgreSQL)")
|
@DisplayName("toWhere generates for BETWEEN w/o qualifier, numeric range | PostgreSQL")
|
||||||
public void toWhereBetweenNoQualNumericPostgres() {
|
public void toWhereBetweenNoQualNumericPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("(data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
assertEquals("(data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||||
Field.between("age", 13, 17, "@age").toWhere(), "Field WHERE clause not generated correctly");
|
Field.between("age", 13, 17, "@age").toWhere(), "Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, alphanumeric range (PostgreSQL)")
|
@DisplayName("toWhere generates for BETWEEN w/o qualifier, alphanumeric range | PostgreSQL")
|
||||||
public void toWhereBetweenNoQualAlphaPostgres() {
|
public void toWhereBetweenNoQualAlphaPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("data->>'city' BETWEEN :citymin AND :citymax",
|
assertEquals("data->>'city' BETWEEN :citymin AND :citymax",
|
||||||
Field.between("city", "Atlanta", "Chicago", ":city").toWhere(),
|
Field.between("city", "Atlanta", "Chicago", ":city").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier (SQLite)")
|
@DisplayName("toWhere generates for BETWEEN w/o qualifier | SQLite")
|
||||||
public void toWhereBetweenNoQualSQLite() {
|
public void toWhereBetweenNoQualSQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("data->>'age' BETWEEN @agemin AND @agemax", Field.between("age", 13, 17, "@age").toWhere(),
|
assertEquals("data->>'age' BETWEEN @agemin AND @agemax", Field.between("age", 13, 17, "@age").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, numeric range (PostgreSQL)")
|
@DisplayName("toWhere generates for BETWEEN w/ qualifier, numeric range | PostgreSQL")
|
||||||
public void toWhereBetweenQualNumericPostgres() {
|
public void toWhereBetweenQualNumericPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("(test.data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
assertEquals("(test.data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||||
Field.between("age", 13, 17, "@age").withQualifier("test").toWhere(),
|
Field.between("age", 13, 17, "@age").withQualifier("test").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, alphanumeric range (PostgreSQL)")
|
@DisplayName("toWhere generates for BETWEEN w/ qualifier, alphanumeric range | PostgreSQL")
|
||||||
public void toWhereBetweenQualAlphaPostgres() {
|
public void toWhereBetweenQualAlphaPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("unit.data->>'city' BETWEEN :citymin AND :citymax",
|
assertEquals("unit.data->>'city' BETWEEN :citymin AND :citymax",
|
||||||
Field.between("city", "Atlanta", "Chicago", ":city").withQualifier("unit").toWhere(),
|
Field.between("city", "Atlanta", "Chicago", ":city").withQualifier("unit").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier (SQLite)")
|
@DisplayName("toWhere generates for BETWEEN w/ qualifier | SQLite")
|
||||||
public void toWhereBetweenQualSQLite() {
|
public void toWhereBetweenQualSQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("my.data->>'age' BETWEEN @agemin AND @agemax",
|
assertEquals("my.data->>'age' BETWEEN @agemin AND @agemax",
|
||||||
Field.between("age", 13, 17, "@age").withQualifier("my").toWhere(),
|
Field.between("age", 13, 17, "@age").withQualifier("my").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for IN/any, numeric values (PostgreSQL)")
|
@DisplayName("toWhere generates for IN/any, numeric values | PostgreSQL")
|
||||||
public void toWhereAnyNumericPostgres() {
|
public void toWhereAnyNumericPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)",
|
assertEquals("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)",
|
||||||
Field.any("even", List.of(2, 4, 6), ":nbr").toWhere(),
|
Field.any("even", List.of(2, 4, 6), ":nbr").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for IN/any, alphanumeric values (PostgreSQL)")
|
@DisplayName("toWhere generates for IN/any, alphanumeric values | PostgreSQL")
|
||||||
public void toWhereAnyAlphaPostgres() {
|
public void toWhereAnyAlphaPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||||
Field.any("test", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
Field.any("test", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for IN/any (SQLite)")
|
@DisplayName("toWhere generates for IN/any | SQLite")
|
||||||
public void toWhereAnySQLite() {
|
public void toWhereAnySQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||||
Field.any("test", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
Field.any("test", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for inArray (PostgreSQL)")
|
@DisplayName("toWhere generates for inArray | PostgreSQL")
|
||||||
public void toWhereInArrayPostgres() {
|
public void toWhereInArrayPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]",
|
assertEquals("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]",
|
||||||
Field.inArray("even", "tbl", List.of(2, 4, 6, 8), ":it").toWhere(),
|
Field.inArray("even", "tbl", List.of(2, 4, 6, 8), ":it").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for inArray (SQLite)")
|
@DisplayName("toWhere generates for inArray | SQLite")
|
||||||
public void toWhereInArraySQLite() {
|
public void toWhereInArraySQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("EXISTS (SELECT 1 FROM json_each(tbl.data, '$.test') WHERE value IN (:city_0, :city_1))",
|
assertEquals("EXISTS (SELECT 1 FROM json_each(tbl.data, '$.test') WHERE value IN (:city_0, :city_1))",
|
||||||
Field.inArray("test", "tbl", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
Field.inArray("test", "tbl", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for others w/o qualifier (PostgreSQL)")
|
@DisplayName("toWhere generates for others w/o qualifier | PostgreSQL")
|
||||||
public void toWhereOtherNoQualPostgres() {
|
public void toWhereOtherNoQualPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for others w/o qualifier (SQLite)")
|
@DisplayName("toWhere generates for others w/o qualifier | SQLite")
|
||||||
public void toWhereOtherNoQualSQLite() {
|
public void toWhereOtherNoQualSQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates no-parameter w/ qualifier (PostgreSQL)")
|
@DisplayName("toWhere generates no-parameter w/ qualifier | PostgreSQL")
|
||||||
public void toWhereNoParamWithQualPostgres() {
|
public void toWhereNoParamWithQualPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates no-parameter w/ qualifier (SQLite)")
|
@DisplayName("toWhere generates no-parameter w/ qualifier | SQLite")
|
||||||
public void toWhereNoParamWithQualSQLite() {
|
public void toWhereNoParamWithQualSQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates parameter w/ qualifier (PostgreSQL)")
|
@DisplayName("toWhere generates parameter w/ qualifier | PostgreSQL")
|
||||||
public void toWhereParamWithQualPostgres() {
|
public void toWhereParamWithQualPostgres() throws DocumentException {
|
||||||
Configuration.setConnectionString(":postgresql:");
|
ForceDialect.postgres();
|
||||||
assertEquals("(q.data->>'le_field')::numeric <= :it",
|
assertEquals("(q.data->>'le_field')::numeric <= :it",
|
||||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates parameter w/ qualifier (SQLite)")
|
@DisplayName("toWhere generates parameter w/ qualifier | SQLite")
|
||||||
public void toWhereParamWithQualSQLite() {
|
public void toWhereParamWithQualSQLite() throws DocumentException {
|
||||||
Configuration.setConnectionString(":sqlite:");
|
ForceDialect.sqlite();
|
||||||
assertEquals("q.data->>'le_field' <= :it",
|
assertEquals("q.data->>'le_field' <= :it",
|
||||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
||||||
"Field WHERE clause not generated correctly");
|
"Field WHERE clause not generated correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("toWhere fails when dialect is not set")
|
||||||
|
public void toWhereFailsNoDialect() {
|
||||||
|
assertThrows(DocumentException.class, () -> Field.equal("a", "oops").toWhere());
|
||||||
|
}
|
||||||
|
|
||||||
// ~~~ STATIC TESTS ~~~
|
// ~~~ STATIC TESTS ~~~
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("equal constructs a field w/o parameter name")
|
@DisplayName("equal constructs a field w/o parameter name")
|
||||||
public void equalCtor() {
|
public void equalCtor() {
|
||||||
Field<Integer> field = Field.equal("Test", 14);
|
final Field<Integer> field = Field.equal("Test", 14);
|
||||||
assertEquals("Test", field.getName(), "Field name not filled correctly");
|
assertEquals("Test", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.EQUAL, field.getComparison().getOp(), "Field comparison operation 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(14, field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -326,7 +333,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("equal constructs a field w/ parameter name")
|
@DisplayName("equal constructs a field w/ parameter name")
|
||||||
public void equalParameterCtor() {
|
public void equalParameterCtor() {
|
||||||
Field<Integer> field = Field.equal("Test", 14, ":w");
|
final Field<Integer> field = Field.equal("Test", 14, ":w");
|
||||||
assertEquals("Test", field.getName(), "Field name not filled correctly");
|
assertEquals("Test", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.EQUAL, field.getComparison().getOp(), "Field comparison operation 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(14, field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -337,7 +344,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("greater constructs a field w/o parameter name")
|
@DisplayName("greater constructs a field w/o parameter name")
|
||||||
public void greaterCtor() {
|
public void greaterCtor() {
|
||||||
Field<String> field = Field.greater("Great", "night");
|
final Field<String> field = Field.greater("Great", "night");
|
||||||
assertEquals("Great", field.getName(), "Field name not filled correctly");
|
assertEquals("Great", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.GREATER, field.getComparison().getOp(), "Field comparison operation 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("night", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -348,7 +355,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("greater constructs a field w/ parameter name")
|
@DisplayName("greater constructs a field w/ parameter name")
|
||||||
public void greaterParameterCtor() {
|
public void greaterParameterCtor() {
|
||||||
Field<String> field = Field.greater("Great", "night", ":yeah");
|
final Field<String> field = Field.greater("Great", "night", ":yeah");
|
||||||
assertEquals("Great", field.getName(), "Field name not filled correctly");
|
assertEquals("Great", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.GREATER, field.getComparison().getOp(), "Field comparison operation 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("night", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -359,7 +366,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("greaterOrEqual constructs a field w/o parameter name")
|
@DisplayName("greaterOrEqual constructs a field w/o parameter name")
|
||||||
public void greaterOrEqualCtor() {
|
public void greaterOrEqualCtor() {
|
||||||
Field<Long> field = Field.greaterOrEqual("Nice", 88L);
|
final Field<Long> field = Field.greaterOrEqual("Nice", 88L);
|
||||||
assertEquals("Nice", field.getName(), "Field name not filled correctly");
|
assertEquals("Nice", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison().getOp(),
|
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison().getOp(),
|
||||||
"Field comparison operation not filled correctly");
|
"Field comparison operation not filled correctly");
|
||||||
@ -371,7 +378,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("greaterOrEqual constructs a field w/ parameter name")
|
@DisplayName("greaterOrEqual constructs a field w/ parameter name")
|
||||||
public void greaterOrEqualParameterCtor() {
|
public void greaterOrEqualParameterCtor() {
|
||||||
Field<Long> field = Field.greaterOrEqual("Nice", 88L, ":nice");
|
final Field<Long> field = Field.greaterOrEqual("Nice", 88L, ":nice");
|
||||||
assertEquals("Nice", field.getName(), "Field name not filled correctly");
|
assertEquals("Nice", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison().getOp(),
|
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison().getOp(),
|
||||||
"Field comparison operation not filled correctly");
|
"Field comparison operation not filled correctly");
|
||||||
@ -383,7 +390,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("less constructs a field w/o parameter name")
|
@DisplayName("less constructs a field w/o parameter name")
|
||||||
public void lessCtor() {
|
public void lessCtor() {
|
||||||
Field<String> field = Field.less("Lesser", "seven");
|
final Field<String> field = Field.less("Lesser", "seven");
|
||||||
assertEquals("Lesser", field.getName(), "Field name not filled correctly");
|
assertEquals("Lesser", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.LESS, field.getComparison().getOp(), "Field comparison operation 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("seven", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -394,7 +401,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("less constructs a field w/ parameter name")
|
@DisplayName("less constructs a field w/ parameter name")
|
||||||
public void lessParameterCtor() {
|
public void lessParameterCtor() {
|
||||||
Field<String> field = Field.less("Lesser", "seven", ":max");
|
final Field<String> field = Field.less("Lesser", "seven", ":max");
|
||||||
assertEquals("Lesser", field.getName(), "Field name not filled correctly");
|
assertEquals("Lesser", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.LESS, field.getComparison().getOp(), "Field comparison operation 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("seven", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -405,7 +412,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("lessOrEqual constructs a field w/o parameter name")
|
@DisplayName("lessOrEqual constructs a field w/o parameter name")
|
||||||
public void lessOrEqualCtor() {
|
public void lessOrEqualCtor() {
|
||||||
Field<String> field = Field.lessOrEqual("Nobody", "KNOWS");
|
final Field<String> field = Field.lessOrEqual("Nobody", "KNOWS");
|
||||||
assertEquals("Nobody", field.getName(), "Field name not filled correctly");
|
assertEquals("Nobody", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.LESS_OR_EQUAL, field.getComparison().getOp(),
|
assertEquals(Op.LESS_OR_EQUAL, field.getComparison().getOp(),
|
||||||
"Field comparison operation not filled correctly");
|
"Field comparison operation not filled correctly");
|
||||||
@ -417,7 +424,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("lessOrEqual constructs a field w/ parameter name")
|
@DisplayName("lessOrEqual constructs a field w/ parameter name")
|
||||||
public void lessOrEqualParameterCtor() {
|
public void lessOrEqualParameterCtor() {
|
||||||
Field<String> field = Field.lessOrEqual("Nobody", "KNOWS", ":nope");
|
final Field<String> field = Field.lessOrEqual("Nobody", "KNOWS", ":nope");
|
||||||
assertEquals("Nobody", field.getName(), "Field name not filled correctly");
|
assertEquals("Nobody", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.LESS_OR_EQUAL, field.getComparison().getOp(),
|
assertEquals(Op.LESS_OR_EQUAL, field.getComparison().getOp(),
|
||||||
"Field comparison operation not filled correctly");
|
"Field comparison operation not filled correctly");
|
||||||
@ -429,7 +436,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("notEqual constructs a field w/o parameter name")
|
@DisplayName("notEqual constructs a field w/o parameter name")
|
||||||
public void notEqualCtor() {
|
public void notEqualCtor() {
|
||||||
Field<String> field = Field.notEqual("Park", "here");
|
final Field<String> field = Field.notEqual("Park", "here");
|
||||||
assertEquals("Park", field.getName(), "Field name not filled correctly");
|
assertEquals("Park", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.NOT_EQUAL, field.getComparison().getOp(), "Field comparison operation 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("here", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -440,7 +447,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("notEqual constructs a field w/ parameter name")
|
@DisplayName("notEqual constructs a field w/ parameter name")
|
||||||
public void notEqualParameterCtor() {
|
public void notEqualParameterCtor() {
|
||||||
Field<String> field = Field.notEqual("Park", "here", ":now");
|
final Field<String> field = Field.notEqual("Park", "here", ":now");
|
||||||
assertEquals("Park", field.getName(), "Field name not filled correctly");
|
assertEquals("Park", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.NOT_EQUAL, field.getComparison().getOp(), "Field comparison operation 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("here", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -451,7 +458,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("between constructs a field w/o parameter name")
|
@DisplayName("between constructs a field w/o parameter name")
|
||||||
public void betweenCtor() {
|
public void betweenCtor() {
|
||||||
Field<Pair<Integer, Integer>> field = Field.between("Age", 18, 49);
|
final Field<Pair<Integer, Integer>> field = Field.between("Age", 18, 49);
|
||||||
assertEquals("Age", field.getName(), "Field name not filled correctly");
|
assertEquals("Age", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.BETWEEN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
assertEquals(Op.BETWEEN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||||
assertEquals(18, field.getComparison().getValue().getFirst(),
|
assertEquals(18, field.getComparison().getValue().getFirst(),
|
||||||
@ -465,7 +472,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("between constructs a field w/ parameter name")
|
@DisplayName("between constructs a field w/ parameter name")
|
||||||
public void betweenParameterCtor() {
|
public void betweenParameterCtor() {
|
||||||
Field<Pair<Integer, Integer>> field = Field.between("Age", 18, 49, ":limit");
|
final Field<Pair<Integer, Integer>> field = Field.between("Age", 18, 49, ":limit");
|
||||||
assertEquals("Age", field.getName(), "Field name not filled correctly");
|
assertEquals("Age", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.BETWEEN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
assertEquals(Op.BETWEEN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||||
assertEquals(18, field.getComparison().getValue().getFirst(),
|
assertEquals(18, field.getComparison().getValue().getFirst(),
|
||||||
@ -479,7 +486,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("any constructs a field w/o parameter name")
|
@DisplayName("any constructs a field w/o parameter name")
|
||||||
public void anyCtor() {
|
public void anyCtor() {
|
||||||
Field<Collection<Integer>> field = Field.any("Here", List.of(8, 16, 32));
|
final Field<Collection<Integer>> field = Field.any("Here", List.of(8, 16, 32));
|
||||||
assertEquals("Here", field.getName(), "Field name not filled correctly");
|
assertEquals("Here", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.IN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
assertEquals(Op.IN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||||
assertEquals(List.of(8, 16, 32), field.getComparison().getValue(),
|
assertEquals(List.of(8, 16, 32), field.getComparison().getValue(),
|
||||||
@ -491,7 +498,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("any constructs a field w/ parameter name")
|
@DisplayName("any constructs a field w/ parameter name")
|
||||||
public void anyParameterCtor() {
|
public void anyParameterCtor() {
|
||||||
Field<Collection<Integer>> field = Field.any("Here", List.of(8, 16, 32), ":list");
|
final Field<Collection<Integer>> field = Field.any("Here", List.of(8, 16, 32), ":list");
|
||||||
assertEquals("Here", field.getName(), "Field name not filled correctly");
|
assertEquals("Here", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.IN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
assertEquals(Op.IN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||||
assertEquals(List.of(8, 16, 32), field.getComparison().getValue(),
|
assertEquals(List.of(8, 16, 32), field.getComparison().getValue(),
|
||||||
@ -503,7 +510,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("inArray constructs a field w/o parameter name")
|
@DisplayName("inArray constructs a field w/o parameter name")
|
||||||
public void inArrayCtor() {
|
public void inArrayCtor() {
|
||||||
Field<Pair<String, Collection<String>>> field = Field.inArray("ArrayField", "table", List.of("z"));
|
final Field<Pair<String, Collection<String>>> field = Field.inArray("ArrayField", "table", List.of("z"));
|
||||||
assertEquals("ArrayField", field.getName(), "Field name not filled correctly");
|
assertEquals("ArrayField", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.IN_ARRAY, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
assertEquals(Op.IN_ARRAY, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||||
assertEquals("table", field.getComparison().getValue().getFirst(),
|
assertEquals("table", field.getComparison().getValue().getFirst(),
|
||||||
@ -517,7 +524,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("inArray constructs a field w/ parameter name")
|
@DisplayName("inArray constructs a field w/ parameter name")
|
||||||
public void inArrayParameterCtor() {
|
public void inArrayParameterCtor() {
|
||||||
Field<Pair<String, Collection<String>>> field = Field.inArray("ArrayField", "table", List.of("z"), ":a");
|
final Field<Pair<String, Collection<String>>> field = Field.inArray("ArrayField", "table", List.of("z"), ":a");
|
||||||
assertEquals("ArrayField", field.getName(), "Field name not filled correctly");
|
assertEquals("ArrayField", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.IN_ARRAY, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
assertEquals(Op.IN_ARRAY, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||||
assertEquals("table", field.getComparison().getValue().getFirst(),
|
assertEquals("table", field.getComparison().getValue().getFirst(),
|
||||||
@ -531,7 +538,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("exists constructs a field")
|
@DisplayName("exists constructs a field")
|
||||||
public void existsCtor() {
|
public void existsCtor() {
|
||||||
Field<String> field = Field.exists("Groovy");
|
final Field<String> field = Field.exists("Groovy");
|
||||||
assertEquals("Groovy", field.getName(), "Field name not filled correctly");
|
assertEquals("Groovy", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.EXISTS, field.getComparison().getOp(), "Field comparison operation 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");
|
assertEquals("", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -542,7 +549,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("notExists constructs a field")
|
@DisplayName("notExists constructs a field")
|
||||||
public void notExistsCtor() {
|
public void notExistsCtor() {
|
||||||
Field<String> field = Field.notExists("Groovy");
|
final Field<String> field = Field.notExists("Groovy");
|
||||||
assertEquals("Groovy", field.getName(), "Field name not filled correctly");
|
assertEquals("Groovy", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.NOT_EXISTS, field.getComparison().getOp(), "Field comparison operation 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");
|
assertEquals("", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
@ -553,7 +560,7 @@ final public class FieldTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("named constructs a field")
|
@DisplayName("named constructs a field")
|
||||||
public void namedCtor() {
|
public void namedCtor() {
|
||||||
Field<String> field = Field.named("Tacos");
|
final Field<String> field = Field.named("Tacos");
|
||||||
assertEquals("Tacos", field.getName(), "Field name not filled correctly");
|
assertEquals("Tacos", field.getName(), "Field name not filled correctly");
|
||||||
assertEquals(Op.EQUAL, field.getComparison().getOp(), "Field comparison operation 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");
|
assertEquals("", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||||
|
@ -18,7 +18,7 @@ import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
|||||||
* Unit tests for the `Count` object
|
* Unit tests for the `Count` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("JVM | Java | Query | CountQuery")
|
@DisplayName("JVM | Java | Query | CountQuery")
|
||||||
public class CountQueryTest {
|
final public class CountQueryTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the connection string (resets Dialect)
|
* Clear the connection string (resets Dialect)
|
||||||
@ -37,7 +37,7 @@ public class CountQueryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly | PostgreSQL")
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
public void byFieldsPostgres() {
|
public void byFieldsPostgres() throws DocumentException {
|
||||||
ForceDialect.postgres();
|
ForceDialect.postgres();
|
||||||
assertEquals(String.format("SELECT COUNT(*) AS it FROM %s WHERE data->>'test' = :field0", TEST_TABLE),
|
assertEquals(String.format("SELECT COUNT(*) AS it FROM %s WHERE data->>'test' = :field0", TEST_TABLE),
|
||||||
CountQuery.byFields(TEST_TABLE, List.of(Field.equal("test", "", ":field0"))),
|
CountQuery.byFields(TEST_TABLE, List.of(Field.equal("test", "", ":field0"))),
|
||||||
@ -46,7 +46,7 @@ public class CountQueryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly | SQLite")
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
public void byFieldsSQLite() {
|
public void byFieldsSQLite() throws DocumentException {
|
||||||
ForceDialect.sqlite();
|
ForceDialect.sqlite();
|
||||||
assertEquals(String.format("SELECT COUNT(*) AS it FROM %s WHERE data->>'test' = :field0", TEST_TABLE),
|
assertEquals(String.format("SELECT COUNT(*) AS it FROM %s WHERE data->>'test' = :field0", TEST_TABLE),
|
||||||
CountQuery.byFields(TEST_TABLE, List.of(Field.equal("test", "", ":field0"))),
|
CountQuery.byFields(TEST_TABLE, List.of(Field.equal("test", "", ":field0"))),
|
||||||
|
@ -19,7 +19,7 @@ import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
|||||||
* Unit tests for the `Definition` object
|
* Unit tests for the `Definition` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("JVM | Java | Query | DefinitionQuery")
|
@DisplayName("JVM | Java | Query | DefinitionQuery")
|
||||||
public class DefinitionQueryTest {
|
final public class DefinitionQueryTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the connection string (resets Dialect)
|
* Clear the connection string (resets Dialect)
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
package solutions.bitbadger.documents.java.query;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
|
import solutions.bitbadger.documents.Field;
|
||||||
|
import solutions.bitbadger.documents.query.DeleteQuery;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the `Delete` object
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | DeleteQuery")
|
||||||
|
final public class DeleteQueryTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the connection string (resets Dialect)
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
|
public void byIdPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("DELETE FROM %s WHERE data->>'id' = :id", TEST_TABLE), DeleteQuery.byId(TEST_TABLE),
|
||||||
|
"Delete query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
|
public void byIdSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("DELETE FROM %s WHERE data->>'id' = :id", TEST_TABLE), DeleteQuery.byId(TEST_TABLE),
|
||||||
|
"Delete query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
|
public void byFieldsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("DELETE FROM %s WHERE data->>'a' = :b", TEST_TABLE),
|
||||||
|
DeleteQuery.byFields(TEST_TABLE, List.of(Field.equal("a", "", ":b"))),
|
||||||
|
"Delete query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
|
public void byFieldsSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("DELETE FROM %s WHERE data->>'a' = :b", TEST_TABLE),
|
||||||
|
DeleteQuery.byFields(TEST_TABLE, List.of(Field.equal("a", "", ":b"))),
|
||||||
|
"Delete query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
|
public void byContainsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("DELETE FROM %s WHERE data @> :criteria", TEST_TABLE),
|
||||||
|
DeleteQuery.byContains(TEST_TABLE), "Delete query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains fails | SQLite")
|
||||||
|
public void byContainsSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> DeleteQuery.byContains(TEST_TABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
|
public void byJsonPathPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("DELETE FROM %s WHERE jsonb_path_exists(data, :path::jsonpath)", TEST_TABLE),
|
||||||
|
DeleteQuery.byJsonPath(TEST_TABLE), "Delete query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
|
public void byJsonPathSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> DeleteQuery.byJsonPath(TEST_TABLE));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
package solutions.bitbadger.documents.java.query;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.AutoId;
|
||||||
|
import solutions.bitbadger.documents.Configuration;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
|
import solutions.bitbadger.documents.query.DocumentQuery;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the `Document` object
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | DocumentQuery")
|
||||||
|
final public class DocumentQueryTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the connection string (resets Dialect)
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates no auto ID | PostgreSQL")
|
||||||
|
public void insertNoAutoPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("INSERT INTO %s VALUES (:data)", TEST_TABLE), DocumentQuery.insert(TEST_TABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates no auto ID | SQLite")
|
||||||
|
public void insertNoAutoSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("INSERT INTO %s VALUES (:data)", TEST_TABLE), DocumentQuery.insert(TEST_TABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates auto number | PostgreSQL")
|
||||||
|
public void insertAutoNumberPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("INSERT INTO %1$s VALUES (:data::jsonb || ('{\"id\":' "
|
||||||
|
+ "|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM %1$s) || '}')::jsonb)",
|
||||||
|
TEST_TABLE),
|
||||||
|
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates auto number | SQLite")
|
||||||
|
public void insertAutoNumberSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("INSERT INTO %1$s VALUES (json_set(:data, '$.id', "
|
||||||
|
+ "(SELECT coalesce(max(data->>'id'), 0) + 1 FROM %1$s)))", TEST_TABLE),
|
||||||
|
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates auto UUID | PostgreSQL")
|
||||||
|
public void insertAutoUUIDPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
final String query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID);
|
||||||
|
assertTrue(query.startsWith(String.format("INSERT INTO %s VALUES (:data::jsonb || '{\"id\":\"", TEST_TABLE)),
|
||||||
|
String.format("Query start not correct (actual: %s)", query));
|
||||||
|
assertTrue(query.endsWith("\"}')"), "Query end not correct");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates auto UUID | SQLite")
|
||||||
|
public void insertAutoUUIDSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
final String query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID);
|
||||||
|
assertTrue(query.startsWith(String.format("INSERT INTO %s VALUES (json_set(:data, '$.id', '", TEST_TABLE)),
|
||||||
|
String.format("Query start not correct (actual: %s)", query));
|
||||||
|
assertTrue(query.endsWith("'))"), "Query end not correct");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates auto random string | PostgreSQL")
|
||||||
|
public void insertAutoRandomPostgres() throws DocumentException {
|
||||||
|
try {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
Configuration.idStringLength = 8;
|
||||||
|
final String query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING);
|
||||||
|
final String start = String.format("INSERT INTO %s VALUES (:data::jsonb || '{\"id\":\"", TEST_TABLE);
|
||||||
|
final String end = "\"}')";
|
||||||
|
assertTrue(query.startsWith(start), String.format("Query start not correct (actual: %s)", query));
|
||||||
|
assertTrue(query.endsWith(end), "Query end not correct");
|
||||||
|
assertEquals(8, query.replace(start, "").replace(end, "").length(), "Random string length incorrect");
|
||||||
|
} finally {
|
||||||
|
Configuration.idStringLength = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert generates auto random string | SQLite")
|
||||||
|
public void insertAutoRandomSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
final String query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING);
|
||||||
|
final String start = String.format("INSERT INTO %s VALUES (json_set(:data, '$.id', '", TEST_TABLE);
|
||||||
|
final String end = "'))";
|
||||||
|
assertTrue(query.startsWith(start), String.format("Query start not correct (actual: %s)", query));
|
||||||
|
assertTrue(query.endsWith(end), "Query end not correct");
|
||||||
|
assertEquals(Configuration.idStringLength, query.replace(start, "").replace(end, "").length(),
|
||||||
|
"Random string length incorrect");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("insert fails when no dialect is set")
|
||||||
|
public void insertFailsUnknown() {
|
||||||
|
assertThrows(DocumentException.class, () -> DocumentQuery.insert(TEST_TABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("save generates correctly")
|
||||||
|
public void save() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format(
|
||||||
|
"INSERT INTO %s VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
||||||
|
TEST_TABLE),
|
||||||
|
DocumentQuery.save(TEST_TABLE), "INSERT ON CONFLICT UPDATE statement not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("update generates successfully")
|
||||||
|
public void update() {
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = :data", TEST_TABLE), DocumentQuery.update(TEST_TABLE),
|
||||||
|
"Update query not constructed correctly");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package solutions.bitbadger.documents.java.query;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
|
import solutions.bitbadger.documents.Field;
|
||||||
|
import solutions.bitbadger.documents.query.ExistsQuery;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the `Exists` object
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | ExistsQuery")
|
||||||
|
final public class ExistsQueryTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the connection string (resets Dialect)
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
|
public void byIdPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("SELECT EXISTS (SELECT 1 FROM %s WHERE data->>'id' = :id) AS it", TEST_TABLE),
|
||||||
|
ExistsQuery.byId(TEST_TABLE), "Exists query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
|
public void byIdSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("SELECT EXISTS (SELECT 1 FROM %s WHERE data->>'id' = :id) AS it", TEST_TABLE),
|
||||||
|
ExistsQuery.byId(TEST_TABLE), "Exists query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
|
public void byFieldsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM %s WHERE (data->>'it')::numeric = :test) AS it", TEST_TABLE),
|
||||||
|
ExistsQuery.byFields(TEST_TABLE, List.of(Field.equal("it", 7, ":test"))),
|
||||||
|
"Exists query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
|
public void byFieldsSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("SELECT EXISTS (SELECT 1 FROM %s WHERE data->>'it' = :test) AS it", TEST_TABLE),
|
||||||
|
ExistsQuery.byFields(TEST_TABLE, List.of(Field.equal("it", 7, ":test"))),
|
||||||
|
"Exists query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
|
public void byContainsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("SELECT EXISTS (SELECT 1 FROM %s WHERE data @> :criteria) AS it", TEST_TABLE),
|
||||||
|
ExistsQuery.byContains(TEST_TABLE), "Exists query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains fails | SQLite")
|
||||||
|
public void byContainsSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> ExistsQuery.byContains(TEST_TABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
|
public void byJsonPathPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM %s WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
||||||
|
TEST_TABLE),
|
||||||
|
ExistsQuery.byJsonPath(TEST_TABLE), "Exists query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
|
public void byJsonPathSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> ExistsQuery.byJsonPath(TEST_TABLE));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package solutions.bitbadger.documents.java.query;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
|
import solutions.bitbadger.documents.Field;
|
||||||
|
import solutions.bitbadger.documents.query.FindQuery;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the `Find` object
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | FindQuery")
|
||||||
|
final public class FindQueryTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the connection string (resets Dialect)
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("all generates correctly")
|
||||||
|
public void all() {
|
||||||
|
assertEquals(String.format("SELECT data FROM %s", TEST_TABLE), FindQuery.all(TEST_TABLE),
|
||||||
|
"Find query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
|
public void byIdPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("SELECT data FROM %s WHERE data->>'id' = :id", TEST_TABLE),
|
||||||
|
FindQuery.byId(TEST_TABLE), "Find query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
|
public void byIdSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("SELECT data FROM %s WHERE data->>'id' = :id", TEST_TABLE),
|
||||||
|
FindQuery.byId(TEST_TABLE), "Find query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
|
public void byFieldsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(
|
||||||
|
String.format("SELECT data FROM %s WHERE data->>'a' = :b AND (data->>'c')::numeric < :d", TEST_TABLE),
|
||||||
|
FindQuery.byFields(TEST_TABLE, List.of(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||||
|
"Find query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
|
public void byFieldsSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("SELECT data FROM %s WHERE data->>'a' = :b AND data->>'c' < :d", TEST_TABLE),
|
||||||
|
FindQuery.byFields(TEST_TABLE, List.of(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||||
|
"Find query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
|
public void byContainsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("SELECT data FROM %s WHERE data @> :criteria", TEST_TABLE),
|
||||||
|
FindQuery.byContains(TEST_TABLE), "Find query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains fails | SQLite")
|
||||||
|
public void byContainsSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> FindQuery.byContains(TEST_TABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
|
public void byJsonPathPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("SELECT data FROM %s WHERE jsonb_path_exists(data, :path::jsonpath)", TEST_TABLE),
|
||||||
|
FindQuery.byJsonPath(TEST_TABLE), "Find query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
|
public void byJsonPathSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> FindQuery.byJsonPath(TEST_TABLE));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package solutions.bitbadger.documents.java.query;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
|
import solutions.bitbadger.documents.Field;
|
||||||
|
import solutions.bitbadger.documents.query.PatchQuery;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the `Patch` object
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | PatchQuery")
|
||||||
|
final public class PatchQueryTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the dialect
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
|
public void byIdPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = data || :data WHERE data->>'id' = :id", TEST_TABLE),
|
||||||
|
PatchQuery.byId(TEST_TABLE), "Patch query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
|
public void byIdSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format(
|
||||||
|
"UPDATE %s SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id", TEST_TABLE),
|
||||||
|
PatchQuery.byId(TEST_TABLE), "Patch query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
|
public void byFieldsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = data || :data WHERE data->>'z' = :y", TEST_TABLE),
|
||||||
|
PatchQuery.byFields(TEST_TABLE, List.of(Field.equal("z", "", ":y"))),
|
||||||
|
"Patch query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
|
public void byFieldsSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format(
|
||||||
|
"UPDATE %s SET data = json_patch(data, json(:data)) WHERE data->>'z' = :y", TEST_TABLE),
|
||||||
|
PatchQuery.byFields(TEST_TABLE, List.of(Field.equal("z", "", ":y"))),
|
||||||
|
"Patch query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
|
public void byContainsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = data || :data WHERE data @> :criteria", TEST_TABLE),
|
||||||
|
PatchQuery.byContains(TEST_TABLE), "Patch query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains fails | SQLite")
|
||||||
|
public void byContainsSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> PatchQuery.byContains(TEST_TABLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
|
public void byJsonPathPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
|
TEST_TABLE),
|
||||||
|
PatchQuery.byJsonPath(TEST_TABLE), "Patch query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
|
public void byJsonPathSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> PatchQuery.byJsonPath(TEST_TABLE));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
package solutions.bitbadger.documents.java.query;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.Dialect;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
|
import solutions.bitbadger.documents.Field;
|
||||||
|
import solutions.bitbadger.documents.FieldMatch;
|
||||||
|
import solutions.bitbadger.documents.query.QueryUtils;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the package-level query functions, presented as `QueryUtils` for Java-compatible use
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | QueryUtils")
|
||||||
|
final public class QueryUtilsTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the connection string (resets Dialect)
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("statementWhere generates correctly")
|
||||||
|
public void statementWhere() {
|
||||||
|
assertEquals("x WHERE y", QueryUtils.statementWhere("x", "y"), "Statements not combined correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates a numeric ID query | PostgreSQL")
|
||||||
|
public void byIdNumericPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("test WHERE (data->>'id')::numeric = :id", QueryUtils.byId("test", 9));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates an alphanumeric ID query | PostgreSQL")
|
||||||
|
public void byIdAlphaPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("unit WHERE data->>'id' = :id", QueryUtils.byId("unit", "18"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates ID query | SQLite")
|
||||||
|
public void byIdSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("yo WHERE data->>'id' = :id", QueryUtils.byId("yo", 27));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates default field query | PostgreSQL")
|
||||||
|
public void byFieldsMultipleDefaultPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
|
||||||
|
QueryUtils.byFields("this", List.of(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates default field query | SQLite")
|
||||||
|
public void byFieldsMultipleDefaultSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
|
||||||
|
QueryUtils.byFields("this", List.of(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates ANY field query | PostgreSQL")
|
||||||
|
public void byFieldsMultipleAnyPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
|
||||||
|
QueryUtils.byFields("that", List.of(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
||||||
|
FieldMatch.ANY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates ANY field query | SQLite")
|
||||||
|
public void byFieldsMultipleAnySQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
|
||||||
|
QueryUtils.byFields("that", List.of(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
||||||
|
FieldMatch.ANY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates for no fields")
|
||||||
|
public void orderByNone() throws DocumentException {
|
||||||
|
assertEquals("", QueryUtils.orderBy(List.of(), Dialect.POSTGRESQL),
|
||||||
|
"ORDER BY should have been blank (PostgreSQL)");
|
||||||
|
assertEquals("", QueryUtils.orderBy(List.of(), Dialect.SQLITE), "ORDER BY should have been blank (SQLite)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates single, no direction | PostgreSQL")
|
||||||
|
public void orderBySinglePostgres() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY data->>'TestField'",
|
||||||
|
QueryUtils.orderBy(List.of(Field.named("TestField")), Dialect.POSTGRESQL),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates single, no direction | SQLite")
|
||||||
|
public void orderBySingleSQLite() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY data->>'TestField'",
|
||||||
|
QueryUtils.orderBy(List.of(Field.named("TestField")), Dialect.SQLITE),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates multiple with direction | PostgreSQL")
|
||||||
|
public void orderByMultiplePostgres() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||||
|
QueryUtils.orderBy(List.of(
|
||||||
|
Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
||||||
|
Dialect.POSTGRESQL),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates multiple with direction | SQLite")
|
||||||
|
public void orderByMultipleSQLite() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY data->'Nested'->'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||||
|
QueryUtils.orderBy(List.of(
|
||||||
|
Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
||||||
|
Dialect.SQLITE),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates numeric ordering | PostgreSQL")
|
||||||
|
public void orderByNumericPostgres() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY (data->>'Test')::numeric",
|
||||||
|
QueryUtils.orderBy(List.of(Field.named("n:Test")), Dialect.POSTGRESQL),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates numeric ordering | SQLite")
|
||||||
|
public void orderByNumericSQLite() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY data->>'Test'", QueryUtils.orderBy(List.of(Field.named("n:Test")), Dialect.SQLITE),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates case-insensitive ordering | PostgreSQL")
|
||||||
|
public void orderByCIPostgres() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY LOWER(data#>>'{Test,Field}') DESC NULLS FIRST",
|
||||||
|
QueryUtils.orderBy(List.of(Field.named("i:Test.Field DESC NULLS FIRST")), Dialect.POSTGRESQL),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("orderBy generates case-insensitive ordering | SQLite")
|
||||||
|
public void orderByCISQLite() throws DocumentException {
|
||||||
|
assertEquals(" ORDER BY data->'Test'->>'Field' COLLATE NOCASE ASC NULLS LAST",
|
||||||
|
QueryUtils.orderBy(List.of(Field.named("i:Test.Field ASC NULLS LAST")), Dialect.SQLITE),
|
||||||
|
"ORDER BY not constructed correctly");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package solutions.bitbadger.documents.java.query;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
|
import solutions.bitbadger.documents.Field;
|
||||||
|
import solutions.bitbadger.documents.Parameter;
|
||||||
|
import solutions.bitbadger.documents.ParameterType;
|
||||||
|
import solutions.bitbadger.documents.query.RemoveFieldsQuery;
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the `RemoveFields` object
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | RemoveFieldsQuery")
|
||||||
|
final public class RemoveFieldsQueryTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the dialect
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
|
public void byIdPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = data - :name::text[] WHERE data->>'id' = :id", TEST_TABLE),
|
||||||
|
RemoveFieldsQuery.byId(TEST_TABLE, List.of(new Parameter<>(":name", ParameterType.STRING, "{a,z}"))),
|
||||||
|
"Remove Fields query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
|
public void byIdSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = json_remove(data, :name0, :name1) WHERE data->>'id' = :id",
|
||||||
|
TEST_TABLE),
|
||||||
|
RemoveFieldsQuery.byId(TEST_TABLE, List.of(new Parameter<>(":name0", ParameterType.STRING, "a"),
|
||||||
|
new Parameter<>(":name1", ParameterType.STRING, "z"))),
|
||||||
|
"Remove Field query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
|
public void byFieldsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = data - :name::text[] WHERE data->>'f' > :g", TEST_TABLE),
|
||||||
|
RemoveFieldsQuery.byFields(TEST_TABLE, List.of(new Parameter<>(":name", ParameterType.STRING, "{b,c}")),
|
||||||
|
List.of(Field.greater("f", "", ":g"))),
|
||||||
|
"Remove Field query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
|
public void byFieldsSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = json_remove(data, :name0, :name1) WHERE data->>'f' > :g",
|
||||||
|
TEST_TABLE),
|
||||||
|
RemoveFieldsQuery.byFields(TEST_TABLE, List.of(new Parameter<>(":name0", ParameterType.STRING, "b"),
|
||||||
|
new Parameter<>(":name1", ParameterType.STRING, "c")),
|
||||||
|
List.of(Field.greater("f", "", ":g"))),
|
||||||
|
"Remove Field query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
|
public void byContainsPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format("UPDATE %s SET data = data - :name::text[] WHERE data @> :criteria", TEST_TABLE),
|
||||||
|
RemoveFieldsQuery.byContains(TEST_TABLE,
|
||||||
|
List.of(new Parameter<>(":name", ParameterType.STRING, "{m,n}"))),
|
||||||
|
"Remove Field query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byContains fails | SQLite")
|
||||||
|
public void byContainsSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> RemoveFieldsQuery.byContains(TEST_TABLE, List.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
|
public void byJsonPathPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals(String.format(
|
||||||
|
"UPDATE %s SET data = data - :name::text[] WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
|
TEST_TABLE),
|
||||||
|
RemoveFieldsQuery.byJsonPath(TEST_TABLE,
|
||||||
|
List.of(new Parameter<>(":name", ParameterType.STRING, "{o,p}"))),
|
||||||
|
"Remove Field query not constructed correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
|
public void byJsonPathSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, () -> RemoveFieldsQuery.byJsonPath(TEST_TABLE, List.of()));
|
||||||
|
}
|
||||||
|
}
|
@ -4,10 +4,10 @@ import org.junit.jupiter.api.AfterEach
|
|||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import solutions.bitbadger.documents.Configuration
|
|
||||||
import solutions.bitbadger.documents.Dialect
|
|
||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
|
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,87 +16,89 @@ import kotlin.test.assertEquals
|
|||||||
@DisplayName("JVM | Kotlin | Query | DeleteQuery")
|
@DisplayName("JVM | Kotlin | Query | DeleteQuery")
|
||||||
class DeleteQueryTest {
|
class DeleteQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
|
||||||
private val tbl = "test_table"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the connection string (resets Dialect)
|
* Clear the connection string (resets Dialect)
|
||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
fun byIdPostgres() {
|
fun byIdPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
"DELETE FROM $TEST_TABLE WHERE data->>'id' = :id",
|
||||||
DeleteQuery.byId<String>(tbl), "Delete query not constructed correctly"
|
DeleteQuery.byId<String>(TEST_TABLE), "Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (SQLite)")
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
fun byIdSQLite() {
|
fun byIdSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
"DELETE FROM $TEST_TABLE WHERE data->>'id' = :id",
|
||||||
DeleteQuery.byId<String>(tbl), "Delete query not constructed correctly"
|
DeleteQuery.byId<String>(TEST_TABLE), "Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
fun byFieldsPostgres() {
|
fun byFieldsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'a' = :b", DeleteQuery.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
"DELETE FROM $TEST_TABLE WHERE data->>'a' = :b",
|
||||||
|
DeleteQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"))),
|
||||||
"Delete query not constructed correctly"
|
"Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (SQLite)")
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
fun byFieldsSQLite() {
|
fun byFieldsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'a' = :b", DeleteQuery.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
"DELETE FROM $TEST_TABLE WHERE data->>'a' = :b",
|
||||||
|
DeleteQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"))),
|
||||||
"Delete query not constructed correctly"
|
"Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data @> :criteria", DeleteQuery.byContains(tbl), "Delete query not constructed correctly"
|
"DELETE FROM $TEST_TABLE WHERE data @> :criteria",
|
||||||
)
|
DeleteQuery.byContains(TEST_TABLE),
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("byContains fails (SQLite)")
|
|
||||||
fun byContainsSQLite() {
|
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
|
||||||
assertThrows<DocumentException> { DeleteQuery.byContains(tbl) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
|
||||||
fun byJsonPathPostgres() {
|
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
|
||||||
assertEquals(
|
|
||||||
"DELETE FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)", DeleteQuery.byJsonPath(tbl),
|
|
||||||
"Delete query not constructed correctly"
|
"Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byContains fails | SQLite")
|
||||||
|
fun byContainsSQLite() {
|
||||||
|
ForceDialect.sqlite()
|
||||||
|
assertThrows<DocumentException> { DeleteQuery.byContains(TEST_TABLE) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
|
fun byJsonPathPostgres() {
|
||||||
|
ForceDialect.postgres()
|
||||||
|
assertEquals(
|
||||||
|
"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")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { DeleteQuery.byJsonPath(tbl) }
|
assertThrows<DocumentException> { DeleteQuery.byJsonPath(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,9 @@ import org.junit.jupiter.api.Test
|
|||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import solutions.bitbadger.documents.AutoId
|
import solutions.bitbadger.documents.AutoId
|
||||||
import solutions.bitbadger.documents.Configuration
|
import solutions.bitbadger.documents.Configuration
|
||||||
import solutions.bitbadger.documents.Dialect
|
|
||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
|
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
@ -17,92 +18,90 @@ import kotlin.test.assertTrue
|
|||||||
@DisplayName("JVM | Kotlin | Query | DocumentQuery")
|
@DisplayName("JVM | Kotlin | Query | DocumentQuery")
|
||||||
class DocumentQueryTest {
|
class DocumentQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
|
||||||
private val tbl = "test_table"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the connection string (resets Dialect)
|
* Clear the connection string (resets Dialect)
|
||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates no auto ID (PostgreSQL)")
|
@DisplayName("insert generates no auto ID | PostgreSQL")
|
||||||
fun insertNoAutoPostgres() {
|
fun insertNoAutoPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("INSERT INTO $tbl VALUES (:data)", DocumentQuery.insert(tbl))
|
assertEquals("INSERT INTO $TEST_TABLE VALUES (:data)", DocumentQuery.insert(TEST_TABLE))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates no auto ID (SQLite)")
|
@DisplayName("insert generates no auto ID | SQLite")
|
||||||
fun insertNoAutoSQLite() {
|
fun insertNoAutoSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals("INSERT INTO $tbl VALUES (:data)", DocumentQuery.insert(tbl))
|
assertEquals("INSERT INTO $TEST_TABLE VALUES (:data)", DocumentQuery.insert(TEST_TABLE))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates auto number (PostgreSQL)")
|
@DisplayName("insert generates auto number | PostgreSQL")
|
||||||
fun insertAutoNumberPostgres() {
|
fun insertAutoNumberPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (:data::jsonb || ('{\"id\":' " +
|
"INSERT INTO $TEST_TABLE VALUES (:data::jsonb || ('{\"id\":' " +
|
||||||
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $tbl) || '}')::jsonb)",
|
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $TEST_TABLE) || '}')::jsonb)",
|
||||||
DocumentQuery.insert(tbl, AutoId.NUMBER)
|
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates auto number (SQLite)")
|
@DisplayName("insert generates auto number | SQLite")
|
||||||
fun insertAutoNumberSQLite() {
|
fun insertAutoNumberSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (json_set(:data, '$.id', " +
|
"INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$.id', " +
|
||||||
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $tbl)))",
|
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $TEST_TABLE)))",
|
||||||
DocumentQuery.insert(tbl, AutoId.NUMBER)
|
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates auto UUID (PostgreSQL)")
|
@DisplayName("insert generates auto UUID | PostgreSQL")
|
||||||
fun insertAutoUUIDPostgres() {
|
fun insertAutoUUIDPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
val query = DocumentQuery.insert(tbl, AutoId.UUID)
|
val query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
query.startsWith("INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\""),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
)
|
)
|
||||||
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates auto UUID (SQLite)")
|
@DisplayName("insert generates auto UUID | SQLite")
|
||||||
fun insertAutoUUIDSQLite() {
|
fun insertAutoUUIDSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
val query = DocumentQuery.insert(tbl, AutoId.UUID)
|
val query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
query.startsWith("INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$.id', '"),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
)
|
)
|
||||||
assertTrue(query.endsWith("'))"), "Query end not correct")
|
assertTrue(query.endsWith("'))"), "Query end not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates auto random string (PostgreSQL)")
|
@DisplayName("insert generates auto random string | PostgreSQL")
|
||||||
fun insertAutoRandomPostgres() {
|
fun insertAutoRandomPostgres() {
|
||||||
try {
|
try {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
Configuration.idStringLength = 8
|
Configuration.idStringLength = 8
|
||||||
val query = DocumentQuery.insert(tbl, AutoId.RANDOM_STRING)
|
val query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
query.startsWith("INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\""),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
)
|
)
|
||||||
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
||||||
assertEquals(
|
assertEquals(
|
||||||
8,
|
8,
|
||||||
query.replace("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\"", "").replace("\"}')", "").length,
|
query.replace("INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\"", "")
|
||||||
|
.replace("\"}')", "").length,
|
||||||
"Random string length incorrect"
|
"Random string length incorrect"
|
||||||
)
|
)
|
||||||
} finally {
|
} finally {
|
||||||
@ -111,18 +110,18 @@ class DocumentQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates auto random string (SQLite)")
|
@DisplayName("insert generates auto random string | SQLite")
|
||||||
fun insertAutoRandomSQLite() {
|
fun insertAutoRandomSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
val query = DocumentQuery.insert(tbl, AutoId.RANDOM_STRING)
|
val query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
query.startsWith("INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$.id', '"),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
)
|
)
|
||||||
assertTrue(query.endsWith("'))"), "Query end not correct")
|
assertTrue(query.endsWith("'))"), "Query end not correct")
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Configuration.idStringLength,
|
Configuration.idStringLength,
|
||||||
query.replace("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '", "").replace("'))", "").length,
|
query.replace("INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$.id', '", "").replace("'))", "").length,
|
||||||
"Random string length incorrect"
|
"Random string length incorrect"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -130,21 +129,25 @@ class DocumentQueryTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("insert fails when no dialect is set")
|
@DisplayName("insert fails when no dialect is set")
|
||||||
fun insertFailsUnknown() {
|
fun insertFailsUnknown() {
|
||||||
assertThrows<DocumentException> { DocumentQuery.insert(tbl) }
|
assertThrows<DocumentException> { DocumentQuery.insert(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("save generates correctly")
|
@DisplayName("save generates correctly")
|
||||||
fun save() {
|
fun save() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
"INSERT INTO $TEST_TABLE VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
||||||
DocumentQuery.save(tbl), "INSERT ON CONFLICT UPDATE statement not constructed correctly"
|
DocumentQuery.save(TEST_TABLE), "INSERT ON CONFLICT UPDATE statement not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("update generates successfully")
|
@DisplayName("update generates successfully")
|
||||||
fun update() =
|
fun update() =
|
||||||
assertEquals("UPDATE $tbl SET data = :data", DocumentQuery.update(tbl), "Update query not constructed correctly")
|
assertEquals(
|
||||||
|
"UPDATE $TEST_TABLE SET data = :data",
|
||||||
|
DocumentQuery.update(TEST_TABLE),
|
||||||
|
"Update query not constructed correctly"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -8,98 +8,98 @@ import solutions.bitbadger.documents.Configuration
|
|||||||
import solutions.bitbadger.documents.Dialect
|
import solutions.bitbadger.documents.Dialect
|
||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
|
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the `Exists` object
|
* Unit tests for the `Exists` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Exists")
|
@DisplayName("JVM | Kotlin | Query | ExistsQuery")
|
||||||
class ExistsQueryTest {
|
class ExistsQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
|
||||||
private val tbl = "test_table"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the connection string (resets Dialect)
|
* Clear the connection string (resets Dialect)
|
||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
fun byIdPostgres() {
|
fun byIdPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data->>'id' = :id) AS it",
|
||||||
ExistsQuery.byId<String>(tbl), "Exists query not constructed correctly"
|
ExistsQuery.byId<String>(TEST_TABLE), "Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (SQLite)")
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
fun byIdSQLite() {
|
fun byIdSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data->>'id' = :id) AS it",
|
||||||
ExistsQuery.byId<String>(tbl), "Exists query not constructed correctly"
|
ExistsQuery.byId<String>(TEST_TABLE), "Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
fun byFieldsPostgres() {
|
fun byFieldsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE (data->>'it')::numeric = :test) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE (data->>'it')::numeric = :test) AS it",
|
||||||
ExistsQuery.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
ExistsQuery.byFields(TEST_TABLE, listOf(Field.equal("it", 7, ":test"))),
|
||||||
"Exists query not constructed correctly"
|
"Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (SQLite)")
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
fun byFieldsSQLite() {
|
fun byFieldsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'it' = :test) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data->>'it' = :test) AS it",
|
||||||
ExistsQuery.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
ExistsQuery.byFields(TEST_TABLE, listOf(Field.equal("it", 7, ":test"))),
|
||||||
"Exists query not constructed correctly"
|
"Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data @> :criteria) AS it", ExistsQuery.byContains(tbl),
|
"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE data @> :criteria) AS it",
|
||||||
|
ExistsQuery.byContains(TEST_TABLE),
|
||||||
"Exists query not constructed correctly"
|
"Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails | SQLite")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { ExistsQuery.byContains(tbl) }
|
assertThrows<DocumentException> { ExistsQuery.byContains(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
fun byJsonPathPostgres() {
|
fun byJsonPathPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
||||||
ExistsQuery.byJsonPath(tbl), "Exists query not constructed correctly"
|
ExistsQuery.byJsonPath(TEST_TABLE), "Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { ExistsQuery.byJsonPath(tbl) }
|
assertThrows<DocumentException> { ExistsQuery.byJsonPath(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,9 @@ import org.junit.jupiter.api.AfterEach
|
|||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import solutions.bitbadger.documents.Configuration
|
|
||||||
import solutions.bitbadger.documents.Dialect
|
|
||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
import solutions.bitbadger.documents.support.TEST_TABLE
|
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ class FindQueryTest {
|
|||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -31,9 +30,9 @@ class FindQueryTest {
|
|||||||
assertEquals("SELECT data FROM $TEST_TABLE", FindQuery.all(TEST_TABLE), "Find query not constructed correctly")
|
assertEquals("SELECT data FROM $TEST_TABLE", FindQuery.all(TEST_TABLE), "Find query not constructed correctly")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
fun byIdPostgres() {
|
fun byIdPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id",
|
||||||
FindQuery.byId<String>(TEST_TABLE), "Find query not constructed correctly"
|
FindQuery.byId<String>(TEST_TABLE), "Find query not constructed correctly"
|
||||||
@ -41,9 +40,9 @@ class FindQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (SQLite)")
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
fun byIdSQLite() {
|
fun byIdSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id",
|
||||||
FindQuery.byId<String>(TEST_TABLE), "Find query not constructed correctly"
|
FindQuery.byId<String>(TEST_TABLE), "Find query not constructed correctly"
|
||||||
@ -51,9 +50,9 @@ class FindQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
fun byFieldsPostgres() {
|
fun byFieldsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND (data->>'c')::numeric < :d",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND (data->>'c')::numeric < :d",
|
||||||
FindQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
FindQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||||
@ -62,9 +61,9 @@ class FindQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (SQLite)")
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
fun byFieldsSQLite() {
|
fun byFieldsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND data->>'c' < :d",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND data->>'c' < :d",
|
||||||
FindQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
FindQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||||
@ -73,9 +72,9 @@ class FindQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $TEST_TABLE WHERE data @> :criteria", FindQuery.byContains(TEST_TABLE),
|
"SELECT data FROM $TEST_TABLE WHERE data @> :criteria", FindQuery.byContains(TEST_TABLE),
|
||||||
"Find query not constructed correctly"
|
"Find query not constructed correctly"
|
||||||
@ -83,16 +82,16 @@ class FindQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails | SQLite")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { FindQuery.byContains(TEST_TABLE) }
|
assertThrows<DocumentException> { FindQuery.byContains(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
fun byJsonPathPostgres() {
|
fun byJsonPathPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)",
|
"SELECT data FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
FindQuery.byJsonPath(TEST_TABLE),
|
FindQuery.byJsonPath(TEST_TABLE),
|
||||||
@ -101,9 +100,9 @@ class FindQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { FindQuery.byJsonPath(TEST_TABLE) }
|
assertThrows<DocumentException> { FindQuery.byJsonPath(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ import org.junit.jupiter.api.AfterEach
|
|||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import solutions.bitbadger.documents.Configuration
|
|
||||||
import solutions.bitbadger.documents.Dialect
|
|
||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
|
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,90 +16,87 @@ import kotlin.test.assertEquals
|
|||||||
@DisplayName("JVM | Kotlin | Query | PatchQuery")
|
@DisplayName("JVM | Kotlin | Query | PatchQuery")
|
||||||
class PatchQueryTest {
|
class PatchQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
|
||||||
private val tbl = "test_table"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the dialect
|
* Reset the dialect
|
||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
fun byIdPostgres() {
|
fun byIdPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE data->>'id' = :id",
|
"UPDATE $TEST_TABLE SET data = data || :data WHERE data->>'id' = :id",
|
||||||
PatchQuery.byId<String>(tbl), "Patch query not constructed correctly"
|
PatchQuery.byId<String>(TEST_TABLE), "Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (SQLite)")
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
fun byIdSQLite() {
|
fun byIdSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id",
|
"UPDATE $TEST_TABLE SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id",
|
||||||
PatchQuery.byId<String>(tbl), "Patch query not constructed correctly"
|
PatchQuery.byId<String>(TEST_TABLE), "Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
fun byFieldsPostgres() {
|
fun byFieldsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE data->>'z' = :y",
|
"UPDATE $TEST_TABLE SET data = data || :data WHERE data->>'z' = :y",
|
||||||
PatchQuery.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
PatchQuery.byFields(TEST_TABLE, listOf(Field.equal("z", "", ":y"))),
|
||||||
"Patch query not constructed correctly"
|
"Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (SQLite)")
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
fun byFieldsSQLite() {
|
fun byFieldsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'z' = :y",
|
"UPDATE $TEST_TABLE SET data = json_patch(data, json(:data)) WHERE data->>'z' = :y",
|
||||||
PatchQuery.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
PatchQuery.byFields(TEST_TABLE, listOf(Field.equal("z", "", ":y"))),
|
||||||
"Patch query not constructed correctly"
|
"Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE data @> :criteria", PatchQuery.byContains(tbl),
|
"UPDATE $TEST_TABLE SET data = data || :data WHERE data @> :criteria", PatchQuery.byContains(TEST_TABLE),
|
||||||
"Patch query not constructed correctly"
|
"Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails | SQLite")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { PatchQuery.byContains(tbl) }
|
assertThrows<DocumentException> { PatchQuery.byContains(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
fun byJsonPathPostgres() {
|
fun byJsonPathPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)",
|
"UPDATE $TEST_TABLE SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
PatchQuery.byJsonPath(tbl), "Patch query not constructed correctly"
|
PatchQuery.byJsonPath(TEST_TABLE), "Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { PatchQuery.byJsonPath(tbl) }
|
assertThrows<DocumentException> { PatchQuery.byJsonPath(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@ package solutions.bitbadger.documents.query
|
|||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import solutions.bitbadger.documents.Configuration
|
|
||||||
import solutions.bitbadger.documents.Dialect
|
import solutions.bitbadger.documents.Dialect
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
import solutions.bitbadger.documents.FieldMatch
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +20,7 @@ class QueryTest {
|
|||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -29,30 +29,30 @@ class QueryTest {
|
|||||||
assertEquals("x WHERE y", statementWhere("x", "y"), "Statements not combined correctly")
|
assertEquals("x WHERE y", statementWhere("x", "y"), "Statements not combined correctly")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates a numeric ID query (PostgreSQL)")
|
@DisplayName("byId generates a numeric ID query | PostgreSQL")
|
||||||
fun byIdNumericPostgres() {
|
fun byIdNumericPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("test WHERE (data->>'id')::numeric = :id", byId("test", 9))
|
assertEquals("test WHERE (data->>'id')::numeric = :id", byId("test", 9))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates an alphanumeric ID query (PostgreSQL)")
|
@DisplayName("byId generates an alphanumeric ID query | PostgreSQL")
|
||||||
fun byIdAlphaPostgres() {
|
fun byIdAlphaPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("unit WHERE data->>'id' = :id", byId("unit", "18"))
|
assertEquals("unit WHERE data->>'id' = :id", byId("unit", "18"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates ID query (SQLite)")
|
@DisplayName("byId generates ID query | SQLite")
|
||||||
fun byIdSQLite() {
|
fun byIdSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals("yo WHERE data->>'id' = :id", byId("yo", 27))
|
assertEquals("yo WHERE data->>'id' = :id", byId("yo", 27))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates default field query (PostgreSQL)")
|
@DisplayName("byFields generates default field query | PostgreSQL")
|
||||||
fun byFieldsMultipleDefaultPostgres() {
|
fun byFieldsMultipleDefaultPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
|
"this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
|
||||||
byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
||||||
@ -60,9 +60,9 @@ class QueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates default field query (SQLite)")
|
@DisplayName("byFields generates default field query | SQLite")
|
||||||
fun byFieldsMultipleDefaultSQLite() {
|
fun byFieldsMultipleDefaultSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
|
"this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
|
||||||
byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
||||||
@ -70,9 +70,9 @@ class QueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates ANY field query (PostgreSQL)")
|
@DisplayName("byFields generates ANY field query | PostgreSQL")
|
||||||
fun byFieldsMultipleAnyPostgres() {
|
fun byFieldsMultipleAnyPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
|
"that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
|
||||||
byFields(
|
byFields(
|
||||||
@ -83,9 +83,9 @@ class QueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates ANY field query (SQLite)")
|
@DisplayName("byFields generates ANY field query | SQLite")
|
||||||
fun byFieldsMultipleAnySQLite() {
|
fun byFieldsMultipleAnySQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
|
"that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
|
||||||
byFields(
|
byFields(
|
||||||
@ -103,7 +103,7 @@ class QueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates single, no direction for PostgreSQL")
|
@DisplayName("orderBy generates single, no direction | PostgreSQL")
|
||||||
fun orderBySinglePostgres() =
|
fun orderBySinglePostgres() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY data->>'TestField'",
|
" ORDER BY data->>'TestField'",
|
||||||
@ -111,7 +111,7 @@ class QueryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates single, no direction for SQLite")
|
@DisplayName("orderBy generates single, no direction | SQLite")
|
||||||
fun orderBySingleSQLite() =
|
fun orderBySingleSQLite() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY data->>'TestField'", orderBy(listOf(Field.named("TestField")), Dialect.SQLITE),
|
" ORDER BY data->>'TestField'", orderBy(listOf(Field.named("TestField")), Dialect.SQLITE),
|
||||||
@ -119,7 +119,7 @@ class QueryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates multiple with direction for PostgreSQL")
|
@DisplayName("orderBy generates multiple with direction | PostgreSQL")
|
||||||
fun orderByMultiplePostgres() =
|
fun orderByMultiplePostgres() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
|
" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||||
@ -131,7 +131,7 @@ class QueryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates multiple with direction for SQLite")
|
@DisplayName("orderBy generates multiple with direction | SQLite")
|
||||||
fun orderByMultipleSQLite() =
|
fun orderByMultipleSQLite() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY data->'Nested'->'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
|
" ORDER BY data->'Nested'->'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||||
@ -143,7 +143,7 @@ class QueryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates numeric ordering PostgreSQL")
|
@DisplayName("orderBy generates numeric ordering | PostgreSQL")
|
||||||
fun orderByNumericPostgres() =
|
fun orderByNumericPostgres() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY (data->>'Test')::numeric",
|
" ORDER BY (data->>'Test')::numeric",
|
||||||
@ -151,7 +151,7 @@ class QueryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates numeric ordering for SQLite")
|
@DisplayName("orderBy generates numeric ordering | SQLite")
|
||||||
fun orderByNumericSQLite() =
|
fun orderByNumericSQLite() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY data->>'Test'", orderBy(listOf(Field.named("n:Test")), Dialect.SQLITE),
|
" ORDER BY data->>'Test'", orderBy(listOf(Field.named("n:Test")), Dialect.SQLITE),
|
||||||
@ -159,7 +159,7 @@ class QueryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates case-insensitive ordering for PostgreSQL")
|
@DisplayName("orderBy generates case-insensitive ordering | PostgreSQL")
|
||||||
fun orderByCIPostgres() =
|
fun orderByCIPostgres() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY LOWER(data#>>'{Test,Field}') DESC NULLS FIRST",
|
" ORDER BY LOWER(data#>>'{Test,Field}') DESC NULLS FIRST",
|
||||||
@ -168,7 +168,7 @@ class QueryTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates case-insensitive ordering for SQLite")
|
@DisplayName("orderBy generates case-insensitive ordering | SQLite")
|
||||||
fun orderByCISQLite() =
|
fun orderByCISQLite() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
" ORDER BY data->'Test'->>'Field' COLLATE NOCASE ASC NULLS LAST",
|
" ORDER BY data->'Test'->>'Field' COLLATE NOCASE ASC NULLS LAST",
|
||||||
|
@ -5,6 +5,8 @@ import org.junit.jupiter.api.DisplayName
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
|
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,36 +15,33 @@ import kotlin.test.assertEquals
|
|||||||
@DisplayName("JVM | Kotlin | Query | RemoveFieldsQuery")
|
@DisplayName("JVM | Kotlin | Query | RemoveFieldsQuery")
|
||||||
class RemoveFieldsQueryTest {
|
class RemoveFieldsQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
|
||||||
private val tbl = "test_table"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the dialect
|
* Reset the dialect
|
||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
@DisplayName("byId generates correctly | PostgreSQL")
|
||||||
fun byIdPostgres() {
|
fun byIdPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'id' = :id",
|
"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE data->>'id' = :id",
|
||||||
RemoveFieldsQuery.byId<String>(tbl, listOf(Parameter(":name", ParameterType.STRING, "{a,z}"))),
|
RemoveFieldsQuery.byId<String>(TEST_TABLE, listOf(Parameter(":name", ParameterType.STRING, "{a,z}"))),
|
||||||
"Remove Fields query not constructed correctly"
|
"Remove Fields query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (SQLite)")
|
@DisplayName("byId generates correctly | SQLite")
|
||||||
fun byIdSQLite() {
|
fun byIdSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'id' = :id",
|
"UPDATE $TEST_TABLE SET data = json_remove(data, :name0, :name1) WHERE data->>'id' = :id",
|
||||||
RemoveFieldsQuery.byId<String>(
|
RemoveFieldsQuery.byId<String>(
|
||||||
tbl,
|
TEST_TABLE,
|
||||||
listOf(
|
listOf(
|
||||||
Parameter(":name0", ParameterType.STRING, "a"),
|
Parameter(":name0", ParameterType.STRING, "a"),
|
||||||
Parameter(":name1", ParameterType.STRING, "z")
|
Parameter(":name1", ParameterType.STRING, "z")
|
||||||
@ -53,13 +52,13 @@ class RemoveFieldsQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
@DisplayName("byFields generates correctly | PostgreSQL")
|
||||||
fun byFieldsPostgres() {
|
fun byFieldsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'f' > :g",
|
"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE data->>'f' > :g",
|
||||||
RemoveFieldsQuery.byFields(
|
RemoveFieldsQuery.byFields(
|
||||||
tbl,
|
TEST_TABLE,
|
||||||
listOf(Parameter(":name", ParameterType.STRING, "{b,c}")),
|
listOf(Parameter(":name", ParameterType.STRING, "{b,c}")),
|
||||||
listOf(Field.greater("f", "", ":g"))
|
listOf(Field.greater("f", "", ":g"))
|
||||||
),
|
),
|
||||||
@ -68,13 +67,13 @@ class RemoveFieldsQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (SQLite)")
|
@DisplayName("byFields generates correctly | SQLite")
|
||||||
fun byFieldsSQLite() {
|
fun byFieldsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'f' > :g",
|
"UPDATE $TEST_TABLE SET data = json_remove(data, :name0, :name1) WHERE data->>'f' > :g",
|
||||||
RemoveFieldsQuery.byFields(
|
RemoveFieldsQuery.byFields(
|
||||||
tbl,
|
TEST_TABLE,
|
||||||
listOf(Parameter(":name0", ParameterType.STRING, "b"), Parameter(":name1", ParameterType.STRING, "c")),
|
listOf(Parameter(":name0", ParameterType.STRING, "b"), Parameter(":name1", ParameterType.STRING, "c")),
|
||||||
listOf(Field.greater("f", "", ":g"))
|
listOf(Field.greater("f", "", ":g"))
|
||||||
),
|
),
|
||||||
@ -83,38 +82,38 @@ class RemoveFieldsQueryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
@DisplayName("byContains generates correctly | PostgreSQL")
|
||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data @> :criteria",
|
"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE data @> :criteria",
|
||||||
RemoveFieldsQuery.byContains(tbl, listOf(Parameter(":name", ParameterType.STRING, "{m,n}"))),
|
RemoveFieldsQuery.byContains(TEST_TABLE, listOf(Parameter(":name", ParameterType.STRING, "{m,n}"))),
|
||||||
"Remove Field query not constructed correctly"
|
"Remove Field query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails | SQLite")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { RemoveFieldsQuery.byContains(tbl, listOf()) }
|
assertThrows<DocumentException> { RemoveFieldsQuery.byContains(TEST_TABLE, listOf()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
@DisplayName("byJsonPath generates correctly | PostgreSQL")
|
||||||
fun byJsonPathPostgres() {
|
fun byJsonPathPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE jsonb_path_exists(data, :path::jsonpath)",
|
"UPDATE $TEST_TABLE SET data = data - :name::text[] WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
RemoveFieldsQuery.byJsonPath(tbl, listOf(Parameter(":name", ParameterType.STRING, "{o,p}"))),
|
RemoveFieldsQuery.byJsonPath(TEST_TABLE, listOf(Parameter(":name", ParameterType.STRING, "{o,p}"))),
|
||||||
"Remove Field query not constructed correctly"
|
"Remove Field query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails | SQLite")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { RemoveFieldsQuery.byJsonPath(tbl, listOf()) }
|
assertThrows<DocumentException> { RemoveFieldsQuery.byJsonPath(TEST_TABLE, listOf()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user