Initial Development #1
@ -21,7 +21,7 @@ object Configuration {
|
|||||||
var idStringLength = 16
|
var idStringLength = 16
|
||||||
|
|
||||||
/** The derived dialect value from the connection string */
|
/** The derived dialect value from the connection string */
|
||||||
internal var dialectValue: Dialect? = null
|
private var dialectValue: Dialect? = null
|
||||||
|
|
||||||
/** The connection string for the JDBC connection */
|
/** The connection string for the JDBC connection */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@ -35,12 +35,13 @@ object Configuration {
|
|||||||
* Retrieve a new connection to the configured database
|
* Retrieve a new connection to the configured database
|
||||||
*
|
*
|
||||||
* @return A new connection to the configured database
|
* @return A new connection to the configured database
|
||||||
* @throws IllegalArgumentException If the connection string is not set before calling this
|
* @throws DocumentException If the connection string is not set before calling this
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun dbConn(): Connection {
|
fun dbConn(): Connection {
|
||||||
if (connectionString == null) {
|
if (connectionString == null) {
|
||||||
throw IllegalArgumentException("Please provide a connection string before attempting data access")
|
throw DocumentException("Please provide a connection string before attempting data access")
|
||||||
}
|
}
|
||||||
return DriverManager.getConnection(connectionString)
|
return DriverManager.getConnection(connectionString)
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package solutions.bitbadger.documents
|
package solutions.bitbadger.documents
|
||||||
|
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SQL dialect to use when building queries
|
* The SQL dialect to use when building queries
|
||||||
*/
|
*/
|
||||||
enum class Dialect {
|
enum class Dialect {
|
||||||
/** PostgreSQL */
|
/** PostgreSQL */
|
||||||
POSTGRESQL,
|
POSTGRESQL,
|
||||||
|
|
||||||
/** SQLite */
|
/** SQLite */
|
||||||
SQLITE;
|
SQLITE;
|
||||||
|
|
||||||
@ -18,6 +21,8 @@ enum class Dialect {
|
|||||||
* @return The dialect for the connection string
|
* @return The dialect for the connection string
|
||||||
* @throws DocumentException If the dialect cannot be determined
|
* @throws DocumentException If the dialect cannot be determined
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun deriveFromConnectionString(connectionString: String): Dialect =
|
fun deriveFromConnectionString(connectionString: String): Dialect =
|
||||||
when {
|
when {
|
||||||
connectionString.contains(":sqlite:") -> SQLITE
|
connectionString.contains(":sqlite:") -> SQLITE
|
||||||
|
@ -6,4 +6,4 @@ package solutions.bitbadger.documents
|
|||||||
* @param message The message for the exception
|
* @param message The message for the exception
|
||||||
* @param cause The underlying exception (optional)
|
* @param cause The underlying exception (optional)
|
||||||
*/
|
*/
|
||||||
class DocumentException(message: String, cause: Throwable? = null) : Exception(message, cause)
|
class DocumentException @JvmOverloads constructor(message: String, cause: Throwable? = null) : Exception(message, cause)
|
||||||
|
@ -118,7 +118,6 @@ class Field<T> private constructor(
|
|||||||
|
|
||||||
is ComparisonInArray<*> -> {
|
is ComparisonInArray<*> -> {
|
||||||
val mkString = Configuration.dialect("append parameters for InArray") == Dialect.POSTGRESQL
|
val mkString = Configuration.dialect("append parameters for InArray") == Dialect.POSTGRESQL
|
||||||
// TODO: I think this is actually Pair<String, Collection<*>>
|
|
||||||
comparison.value.second.forEachIndexed { index, item ->
|
comparison.value.second.forEachIndexed { index, item ->
|
||||||
if (mkString) {
|
if (mkString) {
|
||||||
existing.add(Parameter("${parameterName}_$index", ParameterType.STRING, "$item"))
|
existing.add(Parameter("${parameterName}_$index", ParameterType.STRING, "$item"))
|
||||||
|
@ -6,6 +6,7 @@ package solutions.bitbadger.documents
|
|||||||
enum class FieldFormat {
|
enum class FieldFormat {
|
||||||
/** Retrieve the field as a SQL value (string in PostgreSQL, best guess in SQLite */
|
/** Retrieve the field as a SQL value (string in PostgreSQL, best guess in SQLite */
|
||||||
SQL,
|
SQL,
|
||||||
|
|
||||||
/** Retrieve the field as a JSON value */
|
/** Retrieve the field as a JSON value */
|
||||||
JSON
|
JSON
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ package solutions.bitbadger.documents
|
|||||||
enum class FieldMatch(val sql: String) {
|
enum class FieldMatch(val sql: String) {
|
||||||
/** Match any of the field criteria (`OR`) */
|
/** Match any of the field criteria (`OR`) */
|
||||||
ANY("OR"),
|
ANY("OR"),
|
||||||
|
|
||||||
/** Match all the field criteria (`AND`) */
|
/** Match all the field criteria (`AND`) */
|
||||||
ALL("AND"),
|
ALL("AND"),
|
||||||
}
|
}
|
||||||
|
@ -6,24 +6,34 @@ package solutions.bitbadger.documents
|
|||||||
enum class Op(val sql: String) {
|
enum class Op(val sql: String) {
|
||||||
/** Compare using equality */
|
/** Compare using equality */
|
||||||
EQUAL("="),
|
EQUAL("="),
|
||||||
|
|
||||||
/** Compare using greater-than */
|
/** Compare using greater-than */
|
||||||
GREATER(">"),
|
GREATER(">"),
|
||||||
|
|
||||||
/** Compare using greater-than-or-equal-to */
|
/** Compare using greater-than-or-equal-to */
|
||||||
GREATER_OR_EQUAL(">="),
|
GREATER_OR_EQUAL(">="),
|
||||||
|
|
||||||
/** Compare using less-than */
|
/** Compare using less-than */
|
||||||
LESS("<"),
|
LESS("<"),
|
||||||
|
|
||||||
/** Compare using less-than-or-equal-to */
|
/** Compare using less-than-or-equal-to */
|
||||||
LESS_OR_EQUAL("<="),
|
LESS_OR_EQUAL("<="),
|
||||||
|
|
||||||
/** Compare using inequality */
|
/** Compare using inequality */
|
||||||
NOT_EQUAL("<>"),
|
NOT_EQUAL("<>"),
|
||||||
|
|
||||||
/** Compare between two values */
|
/** Compare between two values */
|
||||||
BETWEEN("BETWEEN"),
|
BETWEEN("BETWEEN"),
|
||||||
|
|
||||||
/** Compare existence in a list of values */
|
/** Compare existence in a list of values */
|
||||||
IN("IN"),
|
IN("IN"),
|
||||||
|
|
||||||
/** Compare overlap between an array and a list of values */
|
/** Compare overlap between an array and a list of values */
|
||||||
IN_ARRAY("??|"),
|
IN_ARRAY("??|"),
|
||||||
|
|
||||||
/** Compare existence */
|
/** Compare existence */
|
||||||
EXISTS("IS NOT NULL"),
|
EXISTS("IS NOT NULL"),
|
||||||
|
|
||||||
/** Compare nonexistence */
|
/** Compare nonexistence */
|
||||||
NOT_EXISTS("IS NULL")
|
NOT_EXISTS("IS NULL")
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package solutions.bitbadger.documents
|
|||||||
|
|
||||||
import java.sql.PreparedStatement
|
import java.sql.PreparedStatement
|
||||||
import java.sql.Types
|
import java.sql.Types
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A parameter to use for a query
|
* A parameter to use for a query
|
||||||
@ -22,7 +23,9 @@ class Parameter<T>(val name: String, val type: ParameterType, val value: T) {
|
|||||||
*
|
*
|
||||||
* @param stmt The prepared statement to which this parameter should be bound
|
* @param stmt The prepared statement to which this parameter should be bound
|
||||||
* @param index The index (1-based) to which the parameter should be bound
|
* @param index The index (1-based) to which the parameter should be bound
|
||||||
|
* @throws DocumentException If a number parameter is given a non-numeric value
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun bind(stmt: PreparedStatement, index: Int) {
|
fun bind(stmt: PreparedStatement, index: Int) {
|
||||||
when (type) {
|
when (type) {
|
||||||
ParameterType.NUMBER -> {
|
ParameterType.NUMBER -> {
|
||||||
@ -33,7 +36,7 @@ class Parameter<T>(val name: String, val type: ParameterType, val value: T) {
|
|||||||
is Int -> stmt.setInt(index, value)
|
is Int -> stmt.setInt(index, value)
|
||||||
is Long -> stmt.setLong(index, value)
|
is Long -> stmt.setLong(index, value)
|
||||||
else -> throw DocumentException(
|
else -> throw DocumentException(
|
||||||
"Number parameter must be Byte, Short, Int, or Long (${value!!::class.simpleName})"
|
"Number parameter must be Byte, Short, Int, or Long (${value::class.simpleName})"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import solutions.bitbadger.documents.*
|
|||||||
import solutions.bitbadger.documents.jvm.*
|
import solutions.bitbadger.documents.jvm.*
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.sql.ResultSet
|
import java.sql.ResultSet
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
// ~~~ CUSTOM QUERIES ~~~
|
// ~~~ CUSTOM QUERIES ~~~
|
||||||
|
|
||||||
@ -17,7 +18,9 @@ import java.sql.ResultSet
|
|||||||
* @param clazz The class of the document to be returned
|
* @param clazz The class of the document to be returned
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return A list of results for the given query
|
* @return A list of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun <TDoc> Connection.customList(
|
fun <TDoc> Connection.customList(
|
||||||
query: String,
|
query: String,
|
||||||
parameters: Collection<Parameter<*>> = listOf(),
|
parameters: Collection<Parameter<*>> = listOf(),
|
||||||
@ -34,7 +37,9 @@ fun <TDoc> Connection.customList(
|
|||||||
* @param clazz The class of the document to be returned
|
* @param clazz The class of the document to be returned
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return The document if one matches the query, `null` otherwise
|
* @return The document if one matches the query, `null` otherwise
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun <TDoc> Connection.customSingle(
|
fun <TDoc> Connection.customSingle(
|
||||||
query: String,
|
query: String,
|
||||||
parameters: Collection<Parameter<*>> = listOf(),
|
parameters: Collection<Parameter<*>> = listOf(),
|
||||||
@ -48,7 +53,9 @@ fun <TDoc> Connection.customSingle(
|
|||||||
*
|
*
|
||||||
* @param query The query to retrieve the results
|
* @param query The query to retrieve the results
|
||||||
* @param parameters Parameters to use for the query
|
* @param parameters Parameters to use for the query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
||||||
Custom.nonQuery(query, parameters, this)
|
Custom.nonQuery(query, parameters, this)
|
||||||
|
|
||||||
@ -60,7 +67,9 @@ fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>
|
|||||||
* @param clazz The class of the document to be returned
|
* @param clazz The class of the document to be returned
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return The scalar value from the query
|
* @return The scalar value from the query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun <T : Any> Connection.customScalar(
|
fun <T : Any> Connection.customScalar(
|
||||||
query: String,
|
query: String,
|
||||||
parameters: Collection<Parameter<*>> = listOf(),
|
parameters: Collection<Parameter<*>> = listOf(),
|
||||||
@ -109,7 +118,7 @@ fun Connection.ensureDocumentIndex(tableName: String, indexType: DocumentIndex)
|
|||||||
* @param document The document to be inserted
|
* @param document The document to be inserted
|
||||||
*/
|
*/
|
||||||
fun <TDoc> Connection.insert(tableName: String, document: TDoc) =
|
fun <TDoc> Connection.insert(tableName: String, document: TDoc) =
|
||||||
Document.insert<TDoc>(tableName, document, this)
|
Document.insert(tableName, document, this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
||||||
@ -137,7 +146,9 @@ fun <TKey, TDoc> Connection.update(tableName: String, docId: TKey, document: TDo
|
|||||||
*
|
*
|
||||||
* @param tableName The name of the table in which documents should be counted
|
* @param tableName The name of the table in which documents should be counted
|
||||||
* @return A count of the documents in the table
|
* @return A count of the documents in the table
|
||||||
|
* @throws DocumentException If any dependent process does
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
fun Connection.countAll(tableName: String) =
|
fun Connection.countAll(tableName: String) =
|
||||||
Count.all(tableName, this)
|
Count.all(tableName, this)
|
||||||
|
|
||||||
@ -148,7 +159,9 @@ fun Connection.countAll(tableName: String) =
|
|||||||
* @param fields The fields which should be compared
|
* @param fields The fields which should be compared
|
||||||
* @param howMatched How the fields should be matched
|
* @param howMatched How the fields should be matched
|
||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
|
* @throws DocumentException If the dialect has not been configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun Connection.countByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun Connection.countByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
Count.byFields(tableName, fields, howMatched, this)
|
Count.byFields(tableName, fields, howMatched, this)
|
||||||
|
@ -4,6 +4,7 @@ import solutions.bitbadger.documents.*
|
|||||||
import solutions.bitbadger.documents.query.CountQuery
|
import solutions.bitbadger.documents.query.CountQuery
|
||||||
import solutions.bitbadger.documents.extensions.customScalar
|
import solutions.bitbadger.documents.extensions.customScalar
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to count documents
|
* Functions to count documents
|
||||||
@ -16,7 +17,9 @@ object Count {
|
|||||||
* @param tableName The name of the table in which documents should be counted
|
* @param tableName The name of the table in which documents should be counted
|
||||||
* @param conn The connection over which documents should be counted
|
* @param conn The connection over which documents should be counted
|
||||||
* @return A count of the documents in the table
|
* @return A count of the documents in the table
|
||||||
|
* @throws DocumentException If any dependent process does
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun all(tableName: String, conn: Connection) =
|
fun all(tableName: String, conn: Connection) =
|
||||||
conn.customScalar(CountQuery.all(tableName), listOf(), Long::class.java, Results::toCount)
|
conn.customScalar(CountQuery.all(tableName), listOf(), Long::class.java, Results::toCount)
|
||||||
@ -26,7 +29,9 @@ object Count {
|
|||||||
*
|
*
|
||||||
* @param tableName The name of the table in which documents should be counted
|
* @param tableName The name of the table in which documents should be counted
|
||||||
* @return A count of the documents in the table
|
* @return A count of the documents in the table
|
||||||
|
* @throws DocumentException If no connection string has been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun all(tableName: String) =
|
fun all(tableName: String) =
|
||||||
Configuration.dbConn().use { all(tableName, it) }
|
Configuration.dbConn().use { all(tableName, it) }
|
||||||
@ -39,7 +44,9 @@ object Count {
|
|||||||
* @param howMatched How the fields should be matched
|
* @param howMatched How the fields should be matched
|
||||||
* @param conn The connection on which the deletion should be executed
|
* @param conn The connection on which the deletion should be executed
|
||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
|
* @throws DocumentException If no dialect has been configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(
|
fun byFields(
|
||||||
@ -64,7 +71,9 @@ object Count {
|
|||||||
* @param fields The fields which should be compared
|
* @param fields The fields which should be compared
|
||||||
* @param howMatched How the fields should be matched
|
* @param howMatched How the fields should be matched
|
||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
|
* @throws DocumentException If no connection string has 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) =
|
||||||
@ -79,6 +88,7 @@ object Count {
|
|||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
* @throws DocumentException If called on a SQLite connection
|
* @throws DocumentException If called on a SQLite connection
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
@ -94,8 +104,9 @@ object Count {
|
|||||||
* @param tableName The name of the table in which documents should be counted
|
* @param tableName The name of the table in which documents should be counted
|
||||||
* @param criteria The object for which JSON containment should be checked
|
* @param criteria The object for which JSON containment should be checked
|
||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
* @throws DocumentException If called on a SQLite connection
|
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TContains> byContains(tableName: String, criteria: TContains) =
|
fun <TContains> byContains(tableName: String, criteria: TContains) =
|
||||||
Configuration.dbConn().use { byContains(tableName, criteria, it) }
|
Configuration.dbConn().use { byContains(tableName, criteria, it) }
|
||||||
@ -109,6 +120,7 @@ object Count {
|
|||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
* @throws DocumentException If called on a SQLite connection
|
* @throws DocumentException If called on a SQLite connection
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
@ -124,8 +136,9 @@ object Count {
|
|||||||
* @param tableName The name of the table in which documents should be counted
|
* @param tableName The name of the table in which documents should be counted
|
||||||
* @param path The JSON path comparison to match
|
* @param path The JSON path comparison to match
|
||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
* @throws DocumentException If called on a SQLite connection
|
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String, path: String) =
|
fun byJsonPath(tableName: String, path: String) =
|
||||||
Configuration.dbConn().use { byJsonPath(tableName, path, it) }
|
Configuration.dbConn().use { byJsonPath(tableName, path, it) }
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package solutions.bitbadger.documents.jvm
|
package solutions.bitbadger.documents.jvm
|
||||||
|
|
||||||
import solutions.bitbadger.documents.Configuration
|
import solutions.bitbadger.documents.Configuration
|
||||||
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Parameter
|
import solutions.bitbadger.documents.Parameter
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.sql.ResultSet
|
import java.sql.ResultSet
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
object Custom {
|
object Custom {
|
||||||
|
|
||||||
@ -16,7 +18,9 @@ object Custom {
|
|||||||
* @param conn The connection over which the query should be executed
|
* @param conn The connection over which the query should be executed
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return A list of results for the given query
|
* @return A list of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TDoc> list(
|
fun <TDoc> list(
|
||||||
query: String,
|
query: String,
|
||||||
@ -34,7 +38,9 @@ object Custom {
|
|||||||
* @param clazz The class of the document to be returned
|
* @param clazz The class of the document to be returned
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return A list of results for the given query
|
* @return A list of results for the given query
|
||||||
|
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TDoc> list(
|
fun <TDoc> list(
|
||||||
query: String,
|
query: String,
|
||||||
@ -52,7 +58,9 @@ object Custom {
|
|||||||
* @param conn The connection over which the query should be executed
|
* @param conn The connection over which the query should be executed
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return The document if one matches the query, `null` otherwise
|
* @return The document if one matches the query, `null` otherwise
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TDoc> single(
|
fun <TDoc> single(
|
||||||
query: String,
|
query: String,
|
||||||
@ -70,7 +78,9 @@ object Custom {
|
|||||||
* @param clazz The class of the document to be returned
|
* @param clazz The class of the document to be returned
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return The document if one matches the query, `null` otherwise
|
* @return The document if one matches the query, `null` otherwise
|
||||||
|
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TDoc> single(
|
fun <TDoc> single(
|
||||||
query: String,
|
query: String,
|
||||||
@ -85,7 +95,9 @@ object Custom {
|
|||||||
* @param query The query to retrieve the results
|
* @param query The query to retrieve the results
|
||||||
* @param conn The connection over which the query should be executed
|
* @param conn The connection over which the query should be executed
|
||||||
* @param parameters Parameters to use for the query
|
* @param parameters Parameters to use for the query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun nonQuery(query: String, parameters: Collection<Parameter<*>> = listOf(), conn: Connection) {
|
fun nonQuery(query: String, parameters: Collection<Parameter<*>> = listOf(), conn: Connection) {
|
||||||
Parameters.apply(conn, query, parameters).use { it.executeUpdate() }
|
Parameters.apply(conn, query, parameters).use { it.executeUpdate() }
|
||||||
@ -96,7 +108,9 @@ object Custom {
|
|||||||
*
|
*
|
||||||
* @param query The query to retrieve the results
|
* @param query The query to retrieve the results
|
||||||
* @param parameters Parameters to use for the query
|
* @param parameters Parameters to use for the query
|
||||||
|
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun nonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
fun nonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
||||||
@ -110,7 +124,9 @@ object Custom {
|
|||||||
* @param conn The connection over which the query should be executed
|
* @param conn The connection over which the query should be executed
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return The scalar value from the query
|
* @return The scalar value from the query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <T : Any> scalar(
|
fun <T : Any> scalar(
|
||||||
query: String,
|
query: String,
|
||||||
@ -132,7 +148,10 @@ object Custom {
|
|||||||
* @param parameters Parameters to use for the query
|
* @param parameters Parameters to use for the query
|
||||||
* @param mapFunc The mapping function between the document and the domain item
|
* @param mapFunc The mapping function between the document and the domain item
|
||||||
* @return The scalar value from the query
|
* @return The scalar value from the query
|
||||||
|
* @throws DocumentException If no connection string has been set, or if parameters are invalid
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun <T : Any> scalar(
|
fun <T : Any> scalar(
|
||||||
query: String,
|
query: String,
|
||||||
parameters: Collection<Parameter<*>> = listOf(),
|
parameters: Collection<Parameter<*>> = listOf(),
|
||||||
|
@ -6,6 +6,7 @@ import solutions.bitbadger.documents.DocumentIndex
|
|||||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||||
import solutions.bitbadger.documents.query.DefinitionQuery
|
import solutions.bitbadger.documents.query.DefinitionQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to define tables and indexes
|
* Functions to define tables and indexes
|
||||||
@ -17,7 +18,9 @@ object Definition {
|
|||||||
*
|
*
|
||||||
* @param tableName The table whose existence should be ensured (may include schema)
|
* @param tableName The table whose existence should be ensured (may include schema)
|
||||||
* @param conn The connection on which the query should be executed
|
* @param conn The connection on which the query should be executed
|
||||||
|
* @throws DocumentException If the dialect is not configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ensureTable(tableName: String, conn: Connection) =
|
fun ensureTable(tableName: String, conn: Connection) =
|
||||||
Configuration.dialect("ensure $tableName exists").let {
|
Configuration.dialect("ensure $tableName exists").let {
|
||||||
@ -29,7 +32,9 @@ object Definition {
|
|||||||
* Create a document table if necessary
|
* Create a document table if necessary
|
||||||
*
|
*
|
||||||
* @param tableName The table whose existence should be ensured (may include schema)
|
* @param tableName The table whose existence should be ensured (may include schema)
|
||||||
|
* @throws DocumentException If no connection string has been set
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ensureTable(tableName: String) =
|
fun ensureTable(tableName: String) =
|
||||||
Configuration.dbConn().use { ensureTable(tableName, it) }
|
Configuration.dbConn().use { ensureTable(tableName, it) }
|
||||||
@ -41,7 +46,9 @@ object Definition {
|
|||||||
* @param indexName The name of the index to create
|
* @param indexName The name of the index to create
|
||||||
* @param fields One or more fields to be indexed
|
* @param fields One or more fields to be indexed
|
||||||
* @param conn The connection on which the query should be executed
|
* @param conn The connection on which the query should be executed
|
||||||
|
* @throws DocumentException If any dependent process does
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>, conn: Connection) =
|
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>, conn: Connection) =
|
||||||
conn.customNonQuery(DefinitionQuery.ensureIndexOn(tableName, indexName, fields))
|
conn.customNonQuery(DefinitionQuery.ensureIndexOn(tableName, indexName, fields))
|
||||||
@ -52,7 +59,9 @@ object Definition {
|
|||||||
* @param tableName The table to be indexed (may include schema)
|
* @param tableName The table to be indexed (may include schema)
|
||||||
* @param indexName The name of the index to create
|
* @param indexName The name of the index to create
|
||||||
* @param fields One or more fields to be indexed
|
* @param fields One or more fields to be indexed
|
||||||
|
* @throws DocumentException If no connection string has been set, or if any dependent process does
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>) =
|
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>) =
|
||||||
Configuration.dbConn().use { ensureFieldIndex(tableName, indexName, fields, it) }
|
Configuration.dbConn().use { ensureFieldIndex(tableName, indexName, fields, it) }
|
||||||
@ -75,7 +84,7 @@ object Definition {
|
|||||||
*
|
*
|
||||||
* @param tableName The table to be indexed (may include schema)
|
* @param tableName The table to be indexed (may include schema)
|
||||||
* @param indexType The type of index to ensure
|
* @param indexType The type of index to ensure
|
||||||
* @throws DocumentException If called on a SQLite connection
|
* @throws DocumentException If no connection string has been set, or if called on a SQLite connection
|
||||||
*/
|
*/
|
||||||
@Throws(DocumentException::class)
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -17,18 +17,18 @@ import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
|||||||
*/
|
*/
|
||||||
final public class CountFunctions {
|
final public class CountFunctions {
|
||||||
|
|
||||||
public static void all(ThrowawayDatabase db) {
|
public static void all(ThrowawayDatabase db) throws DocumentException {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(5L, countAll(db.getConn(), TEST_TABLE), "There should have been 5 documents in the table");
|
assertEquals(5L, countAll(db.getConn(), TEST_TABLE), "There should have been 5 documents in the table");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byFieldsNumeric(ThrowawayDatabase db) {
|
public static void byFieldsNumeric(ThrowawayDatabase db) throws DocumentException {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(3L, countByFields(db.getConn(), TEST_TABLE, List.of(Field.between("numValue", 10, 20))),
|
assertEquals(3L, countByFields(db.getConn(), TEST_TABLE, List.of(Field.between("numValue", 10, 20))),
|
||||||
"There should have been 3 matching documents");
|
"There should have been 3 matching documents");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byFieldsAlpha(ThrowawayDatabase db) {
|
public static void byFieldsAlpha(ThrowawayDatabase db) throws DocumentException {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(1L, countByFields(db.getConn(), TEST_TABLE, List.of(Field.between("value", "aardvark", "apple"))),
|
assertEquals(1L, countByFields(db.getConn(), TEST_TABLE, List.of(Field.between("value", "aardvark", "apple"))),
|
||||||
"There should have been 1 matching document");
|
"There should have been 1 matching document");
|
||||||
|
@ -14,7 +14,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("all counts all documents")
|
@DisplayName("all counts all documents")
|
||||||
public void all() {
|
public void all() throws DocumentException {
|
||||||
try (PgDB db = new PgDB()) {
|
try (PgDB db = new PgDB()) {
|
||||||
CountFunctions.all(db);
|
CountFunctions.all(db);
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields counts documents by a numeric value")
|
@DisplayName("byFields counts documents by a numeric value")
|
||||||
public void byFieldsNumeric() {
|
public void byFieldsNumeric() throws DocumentException {
|
||||||
try (PgDB db = new PgDB()) {
|
try (PgDB db = new PgDB()) {
|
||||||
CountFunctions.byFieldsNumeric(db);
|
CountFunctions.byFieldsNumeric(db);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields counts documents by a alphanumeric value")
|
@DisplayName("byFields counts documents by a alphanumeric value")
|
||||||
public void byFieldsAlpha() {
|
public void byFieldsAlpha() throws DocumentException {
|
||||||
try (PgDB db = new PgDB()) {
|
try (PgDB db = new PgDB()) {
|
||||||
CountFunctions.byFieldsAlpha(db);
|
CountFunctions.byFieldsAlpha(db);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("all counts all documents")
|
@DisplayName("all counts all documents")
|
||||||
public void all() {
|
public void all() throws DocumentException {
|
||||||
try (SQLiteDB db = new SQLiteDB()) {
|
try (SQLiteDB db = new SQLiteDB()) {
|
||||||
CountFunctions.all(db);
|
CountFunctions.all(db);
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields counts documents by a numeric value")
|
@DisplayName("byFields counts documents by a numeric value")
|
||||||
public void byFieldsNumeric() {
|
public void byFieldsNumeric() throws DocumentException {
|
||||||
try (SQLiteDB db = new SQLiteDB()) {
|
try (SQLiteDB db = new SQLiteDB()) {
|
||||||
CountFunctions.byFieldsNumeric(db);
|
CountFunctions.byFieldsNumeric(db);
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields counts documents by a alphanumeric value")
|
@DisplayName("byFields counts documents by a alphanumeric value")
|
||||||
public void byFieldsAlpha() {
|
public void byFieldsAlpha() throws DocumentException {
|
||||||
try (SQLiteDB db = new SQLiteDB()) {
|
try (SQLiteDB db = new SQLiteDB()) {
|
||||||
CountFunctions.byFieldsAlpha(db);
|
CountFunctions.byFieldsAlpha(db);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,172 @@
|
|||||||
|
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.FieldMatch;
|
||||||
|
import solutions.bitbadger.documents.query.Where;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the `Where` object
|
||||||
|
*/
|
||||||
|
@DisplayName("JVM | Java | Query | Where")
|
||||||
|
final public class WhereTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the connection string (resets Dialect)
|
||||||
|
*/
|
||||||
|
@AfterEach
|
||||||
|
public void cleanUp() {
|
||||||
|
ForceDialect.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields is blank when given no fields")
|
||||||
|
public void byFieldsBlankIfEmpty() throws DocumentException {
|
||||||
|
assertEquals("", Where.byFields(List.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates one numeric field | PostgreSQL")
|
||||||
|
public void byFieldsOneFieldPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("(data->>'it')::numeric = :that", Where.byFields(List.of(Field.equal("it", 9, ":that"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates one alphanumeric field | PostgreSQL")
|
||||||
|
public void byFieldsOneAlphaFieldPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("data->>'it' = :that", Where.byFields(List.of(Field.equal("it", "", ":that"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates one field | SQLite")
|
||||||
|
public void byFieldsOneFieldSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("data->>'it' = :that", Where.byFields(List.of(Field.equal("it", "", ":that"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates multiple fields w/ default match | PostgreSQL")
|
||||||
|
public void byFieldsMultipleDefaultPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three",
|
||||||
|
Where.byFields(List.of(
|
||||||
|
Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates multiple fields w/ default match | SQLite")
|
||||||
|
public void byFieldsMultipleDefaultSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three",
|
||||||
|
Where.byFields(List.of(
|
||||||
|
Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates multiple fields w/ ANY match | PostgreSQL")
|
||||||
|
public void byFieldsMultipleAnyPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three",
|
||||||
|
Where.byFields(List.of(
|
||||||
|
Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
||||||
|
FieldMatch.ANY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byFields generates multiple fields w/ ANY match | SQLite")
|
||||||
|
public void byFieldsMultipleAnySQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three",
|
||||||
|
Where.byFields(List.of(
|
||||||
|
Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
||||||
|
FieldMatch.ANY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates defaults for alphanumeric key | PostgreSQL")
|
||||||
|
public void byIdDefaultAlphaPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("data->>'id' = :id", Where.byId(":id", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates defaults for numeric key | PostgreSQL")
|
||||||
|
public void byIdDefaultNumericPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("(data->>'id')::numeric = :id", Where.byId(":id", 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates defaults | SQLite")
|
||||||
|
public void byIdDefaultSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("data->>'id' = :id", Where.byId(":id", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates named ID | PostgreSQL")
|
||||||
|
public void byIdDefaultNamedPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("data->>'id' = :key", Where.byId(":key"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("byId generates named ID | SQLite")
|
||||||
|
public void byIdDefaultNamedSQLite() throws DocumentException {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertEquals("data->>'id' = :key", Where.byId(":key"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("jsonContains generates defaults | PostgreSQL")
|
||||||
|
public void jsonContainsDefaultPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("data @> :criteria", Where.jsonContains());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("jsonContains generates named parameter | PostgreSQL")
|
||||||
|
public void jsonContainsNamedPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("data @> :it", Where.jsonContains(":it"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("jsonContains fails | SQLite")
|
||||||
|
public void jsonContainsFailsSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, Where::jsonContains);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("jsonPathMatches generates defaults | PostgreSQL")
|
||||||
|
public void jsonPathMatchDefaultPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("jsonb_path_exists(data, :path::jsonpath)", Where.jsonPathMatches());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("jsonPathMatches generates named parameter | PostgreSQL")
|
||||||
|
public void jsonPathMatchNamedPostgres() throws DocumentException {
|
||||||
|
ForceDialect.postgres();
|
||||||
|
assertEquals("jsonb_path_exists(data, :jp::jsonpath)", Where.jsonPathMatches(":jp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("jsonPathMatches fails | SQLite")
|
||||||
|
public void jsonPathFailsSQLite() {
|
||||||
|
ForceDialect.sqlite();
|
||||||
|
assertThrows(DocumentException.class, Where::jsonPathMatches);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,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 org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
|
import solutions.bitbadger.documents.support.ForceDialect
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotSame
|
import kotlin.test.assertNotSame
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
@ -19,7 +20,7 @@ class FieldTest {
|
|||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~~~ INSTANCE METHODS ~~~
|
// ~~~ INSTANCE METHODS ~~~
|
||||||
@ -120,178 +121,178 @@ class FieldTest {
|
|||||||
"Path not correct")
|
"Path not correct")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("toWhere generates for exists w/o qualifier (PostgreSQL)")
|
@DisplayName("toWhere generates for exists w/o qualifier | PostgreSQL")
|
||||||
fun toWhereExistsNoQualPostgres() {
|
fun toWhereExistsNoQualPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereExistsNoQualSQLite() {
|
fun toWhereExistsNoQualSQLite() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereNotExistsNoQualPostgres() {
|
fun toWhereNotExistsNoQualPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereNotExistsNoQualSQLite() {
|
fun toWhereNotExistsNoQualSQLite() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereBetweenNoQualNumericPostgres() {
|
fun toWhereBetweenNoQualNumericPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereBetweenNoQualAlphaPostgres() {
|
fun toWhereBetweenNoQualAlphaPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereBetweenNoQualSQLite() {
|
fun toWhereBetweenNoQualSQLite() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereBetweenQualNumericPostgres() {
|
fun toWhereBetweenQualNumericPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereBetweenQualAlphaPostgres() {
|
fun toWhereBetweenQualAlphaPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereBetweenQualSQLite() {
|
fun toWhereBetweenQualSQLite() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereAnyNumericPostgres() {
|
fun toWhereAnyNumericPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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", listOf(2, 4, 6), ":nbr").toWhere(), "Field WHERE clause not generated correctly")
|
Field.any("even", listOf(2, 4, 6), ":nbr").toWhere(), "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")
|
||||||
fun toWhereAnyAlphaPostgres() {
|
fun toWhereAnyAlphaPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||||
Field.any("test", listOf("Atlanta", "Chicago"), ":city").toWhere(),
|
Field.any("test", listOf("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")
|
||||||
fun toWhereAnySQLite() {
|
fun toWhereAnySQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||||
Field.any("test", listOf("Atlanta", "Chicago"), ":city").toWhere(),
|
Field.any("test", listOf("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")
|
||||||
fun toWhereInArrayPostgres() {
|
fun toWhereInArrayPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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", listOf(2, 4, 6, 8), ":it").toWhere(),
|
Field.inArray("even", "tbl", listOf(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")
|
||||||
fun toWhereInArraySQLite() {
|
fun toWhereInArraySQLite() {
|
||||||
Configuration.dialectValue = Dialect.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", listOf("Atlanta", "Chicago"), ":city").toWhere(),
|
Field.inArray("test", "tbl", listOf("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")
|
||||||
fun toWhereOtherNoQualPostgres() {
|
fun toWhereOtherNoQualPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereOtherNoQualSQLite() {
|
fun toWhereOtherNoQualSQLite() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereNoParamWithQualPostgres() {
|
fun toWhereNoParamWithQualPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereNoParamWithQualSQLite() {
|
fun toWhereNoParamWithQualSQLite() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereParamWithQualPostgres() {
|
fun toWhereParamWithQualPostgres() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
fun toWhereParamWithQualSQLite() {
|
fun toWhereParamWithQualSQLite() {
|
||||||
Configuration.dialectValue = Dialect.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")
|
||||||
|
@ -5,6 +5,7 @@ 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 kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,7 +19,7 @@ class WhereTest {
|
|||||||
*/
|
*/
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
Configuration.dialectValue = null
|
ForceDialect.none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -27,30 +28,30 @@ class WhereTest {
|
|||||||
assertEquals("", Where.byFields(listOf()))
|
assertEquals("", Where.byFields(listOf()))
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates one numeric field (PostgreSQL)")
|
@DisplayName("byFields generates one numeric field | PostgreSQL")
|
||||||
fun byFieldsOneFieldPostgres() {
|
fun byFieldsOneFieldPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("(data->>'it')::numeric = :that", Where.byFields(listOf(Field.equal("it", 9, ":that"))))
|
assertEquals("(data->>'it')::numeric = :that", Where.byFields(listOf(Field.equal("it", 9, ":that"))))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates one alphanumeric field (PostgreSQL)")
|
@DisplayName("byFields generates one alphanumeric field | PostgreSQL")
|
||||||
fun byFieldsOneAlphaFieldPostgres() {
|
fun byFieldsOneAlphaFieldPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that"))))
|
assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that"))))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates one field (SQLite)")
|
@DisplayName("byFields generates one field | SQLite")
|
||||||
fun byFieldsOneFieldSQLite() {
|
fun byFieldsOneFieldSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that"))))
|
assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that"))))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates multiple fields w/ default match (PostgreSQL)")
|
@DisplayName("byFields generates multiple fields w/ default match | PostgreSQL")
|
||||||
fun byFieldsMultipleDefaultPostgres() {
|
fun byFieldsMultipleDefaultPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three",
|
"data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three",
|
||||||
Where.byFields(
|
Where.byFields(
|
||||||
@ -60,9 +61,9 @@ class WhereTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates multiple fields w/ default match (SQLite)")
|
@DisplayName("byFields generates multiple fields w/ default match | SQLite")
|
||||||
fun byFieldsMultipleDefaultSQLite() {
|
fun byFieldsMultipleDefaultSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three",
|
"data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three",
|
||||||
Where.byFields(
|
Where.byFields(
|
||||||
@ -72,9 +73,9 @@ class WhereTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates multiple fields w/ ANY match (PostgreSQL)")
|
@DisplayName("byFields generates multiple fields w/ ANY match | PostgreSQL")
|
||||||
fun byFieldsMultipleAnyPostgres() {
|
fun byFieldsMultipleAnyPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three",
|
"data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three",
|
||||||
Where.byFields(
|
Where.byFields(
|
||||||
@ -85,9 +86,9 @@ class WhereTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates multiple fields w/ ANY match (SQLite)")
|
@DisplayName("byFields generates multiple fields w/ ANY match | SQLite")
|
||||||
fun byFieldsMultipleAnySQLite() {
|
fun byFieldsMultipleAnySQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three",
|
"data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three",
|
||||||
Where.byFields(
|
Where.byFields(
|
||||||
@ -98,79 +99,79 @@ class WhereTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates defaults for alphanumeric key (PostgreSQL)")
|
@DisplayName("byId generates defaults for alphanumeric key | PostgreSQL")
|
||||||
fun byIdDefaultAlphaPostgres() {
|
fun byIdDefaultAlphaPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("data->>'id' = :id", Where.byId(docId = ""))
|
assertEquals("data->>'id' = :id", Where.byId(docId = ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates defaults for numeric key (PostgreSQL)")
|
@DisplayName("byId generates defaults for numeric key | PostgreSQL")
|
||||||
fun byIdDefaultNumericPostgres() {
|
fun byIdDefaultNumericPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("(data->>'id')::numeric = :id", Where.byId(docId = 5))
|
assertEquals("(data->>'id')::numeric = :id", Where.byId(docId = 5))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates defaults (SQLite)")
|
@DisplayName("byId generates defaults | SQLite")
|
||||||
fun byIdDefaultSQLite() {
|
fun byIdDefaultSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals("data->>'id' = :id", Where.byId(docId = ""))
|
assertEquals("data->>'id' = :id", Where.byId(docId = ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates named ID (PostgreSQL)")
|
@DisplayName("byId generates named ID | PostgreSQL")
|
||||||
fun byIdDefaultNamedPostgres() {
|
fun byIdDefaultNamedPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("data->>'id' = :key", Where.byId<String>(":key"))
|
assertEquals("data->>'id' = :key", Where.byId<String>(":key"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates named ID (SQLite)")
|
@DisplayName("byId generates named ID | SQLite")
|
||||||
fun byIdDefaultNamedSQLite() {
|
fun byIdDefaultNamedSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertEquals("data->>'id' = :key", Where.byId<String>(":key"))
|
assertEquals("data->>'id' = :key", Where.byId<String>(":key"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("jsonContains generates defaults (PostgreSQL)")
|
@DisplayName("jsonContains generates defaults | PostgreSQL")
|
||||||
fun jsonContainsDefaultPostgres() {
|
fun jsonContainsDefaultPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("data @> :criteria", Where.jsonContains())
|
assertEquals("data @> :criteria", Where.jsonContains())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("jsonContains generates named parameter (PostgreSQL)")
|
@DisplayName("jsonContains generates named parameter | PostgreSQL")
|
||||||
fun jsonContainsNamedPostgres() {
|
fun jsonContainsNamedPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("data @> :it", Where.jsonContains(":it"))
|
assertEquals("data @> :it", Where.jsonContains(":it"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("jsonContains fails (SQLite)")
|
@DisplayName("jsonContains fails | SQLite")
|
||||||
fun jsonContainsFailsSQLite() {
|
fun jsonContainsFailsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { Where.jsonContains() }
|
assertThrows<DocumentException> { Where.jsonContains() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("jsonPathMatches generates defaults (PostgreSQL)")
|
@DisplayName("jsonPathMatches generates defaults | PostgreSQL")
|
||||||
fun jsonPathMatchDefaultPostgres() {
|
fun jsonPathMatchDefaultPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("jsonb_path_exists(data, :path::jsonpath)", Where.jsonPathMatches())
|
assertEquals("jsonb_path_exists(data, :path::jsonpath)", Where.jsonPathMatches())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("jsonPathMatches generates named parameter (PostgreSQL)")
|
@DisplayName("jsonPathMatches generates named parameter | PostgreSQL")
|
||||||
fun jsonPathMatchNamedPostgres() {
|
fun jsonPathMatchNamedPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
ForceDialect.postgres()
|
||||||
assertEquals("jsonb_path_exists(data, :jp::jsonpath)", Where.jsonPathMatches(":jp"))
|
assertEquals("jsonb_path_exists(data, :jp::jsonpath)", Where.jsonPathMatches(":jp"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("jsonPathMatches fails (SQLite)")
|
@DisplayName("jsonPathMatches fails | SQLite")
|
||||||
fun jsonPathFailsSQLite() {
|
fun jsonPathFailsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
ForceDialect.sqlite()
|
||||||
assertThrows<DocumentException> { Where.jsonPathMatches() }
|
assertThrows<DocumentException> { Where.jsonPathMatches() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user