Initial Development #1
@ -14,6 +14,24 @@ class Field<T>(
|
|||||||
val parameterName: String? = null,
|
val parameterName: String? = null,
|
||||||
val qualifier: String? = null) {
|
val qualifier: String? = null) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the parameter name for the field
|
||||||
|
*
|
||||||
|
* @param paramName The parameter name to use for this field
|
||||||
|
* @return A new `Field` with the parameter name specified
|
||||||
|
*/
|
||||||
|
fun withParameterName(paramName: String): Field<T> =
|
||||||
|
Field(name, comparison, paramName, qualifier)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a qualifier (alias) for the document table
|
||||||
|
*
|
||||||
|
* @param alias The table alias for this field
|
||||||
|
* @return A new `Field` with the table qualifier specified
|
||||||
|
*/
|
||||||
|
fun withQualifier(alias: String): Field<T> =
|
||||||
|
Field(name, comparison, parameterName, alias)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path for this field
|
* Get the path for this field
|
||||||
*
|
*
|
||||||
@ -32,7 +50,7 @@ class Field<T>(
|
|||||||
* @param value The value for the comparison
|
* @param value The value for the comparison
|
||||||
* @return A `Field` with the given comparison
|
* @return A `Field` with the given comparison
|
||||||
*/
|
*/
|
||||||
fun <T> Equal(name: String, value: T): Field<T> =
|
fun <T> equal(name: String, value: T): Field<T> =
|
||||||
Field<T>(name, Comparison(Op.EQUAL, value))
|
Field<T>(name, Comparison(Op.EQUAL, value))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +60,7 @@ class Field<T>(
|
|||||||
* @param value The value for the comparison
|
* @param value The value for the comparison
|
||||||
* @return A `Field` with the given comparison
|
* @return A `Field` with the given comparison
|
||||||
*/
|
*/
|
||||||
fun <T> Greater(name: String, value: T): Field<T> =
|
fun <T> greater(name: String, value: T): Field<T> =
|
||||||
Field(name, Comparison(Op.GREATER, value))
|
Field(name, Comparison(Op.GREATER, value))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +70,7 @@ class Field<T>(
|
|||||||
* @param value The value for the comparison
|
* @param value The value for the comparison
|
||||||
* @return A `Field` with the given comparison
|
* @return A `Field` with the given comparison
|
||||||
*/
|
*/
|
||||||
fun <T> GreaterOrEqual(name: String, value: T): Field<T> =
|
fun <T> greaterOrEqual(name: String, value: T): Field<T> =
|
||||||
Field(name, Comparison(Op.GREATER_OR_EQUAL, value))
|
Field(name, Comparison(Op.GREATER_OR_EQUAL, value))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +80,7 @@ class Field<T>(
|
|||||||
* @param value The value for the comparison
|
* @param value The value for the comparison
|
||||||
* @return A `Field` with the given comparison
|
* @return A `Field` with the given comparison
|
||||||
*/
|
*/
|
||||||
fun <T> Less(name: String, value: T): Field<T> =
|
fun <T> less(name: String, value: T): Field<T> =
|
||||||
Field(name, Comparison(Op.LESS, value))
|
Field(name, Comparison(Op.LESS, value))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +90,7 @@ class Field<T>(
|
|||||||
* @param value The value for the comparison
|
* @param value The value for the comparison
|
||||||
* @return A `Field` with the given comparison
|
* @return A `Field` with the given comparison
|
||||||
*/
|
*/
|
||||||
fun <T> LessOrEqual(name: String, value: T): Field<T> =
|
fun <T> lessOrEqual(name: String, value: T): Field<T> =
|
||||||
Field(name, Comparison(Op.LESS_OR_EQUAL, value))
|
Field(name, Comparison(Op.LESS_OR_EQUAL, value))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +100,7 @@ class Field<T>(
|
|||||||
* @param value The value for the comparison
|
* @param value The value for the comparison
|
||||||
* @return A `Field` with the given comparison
|
* @return A `Field` with the given comparison
|
||||||
*/
|
*/
|
||||||
fun <T> NotEqual(name: String, value: T): Field<T> =
|
fun <T> notEqual(name: String, value: T): Field<T> =
|
||||||
Field(name, Comparison(Op.NOT_EQUAL, value))
|
Field(name, Comparison(Op.NOT_EQUAL, value))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,22 +111,37 @@ class Field<T>(
|
|||||||
* @param maxValue The upper value for the comparison
|
* @param maxValue The upper value for the comparison
|
||||||
* @return A `Field` with the given comparison
|
* @return A `Field` with the given comparison
|
||||||
*/
|
*/
|
||||||
fun <T> Between(name: String, minValue: T, maxValue: T): Field<Pair<T, T>> =
|
fun <T> between(name: String, minValue: T, maxValue: T): Field<Pair<T, T>> =
|
||||||
Field(name, Comparison(Op.BETWEEN, Pair(minValue, maxValue)))
|
Field(name, Comparison(Op.BETWEEN, Pair(minValue, maxValue)))
|
||||||
|
|
||||||
fun <T> In(name: String, values: List<T>): Field<List<T>> =
|
/**
|
||||||
|
* Create a field where any values match (SQL `IN`)
|
||||||
|
*
|
||||||
|
* @param name The name of the field to be compared
|
||||||
|
* @param values The values for the comparison
|
||||||
|
* @return A `Field` with the given comparison
|
||||||
|
*/
|
||||||
|
fun <T> any(name: String, values: List<T>): Field<List<T>> =
|
||||||
Field(name, Comparison(Op.IN, values))
|
Field(name, Comparison(Op.IN, values))
|
||||||
|
|
||||||
fun <T> InArray(name: String, tableName: String, values: List<T>): Field<Pair<String, List<T>>> =
|
/**
|
||||||
|
* Create a field where values should exist in a document's array
|
||||||
|
*
|
||||||
|
* @param name The name of the field to be compared
|
||||||
|
* @param tableName The name of the document table
|
||||||
|
* @param values The values for the comparison
|
||||||
|
* @return A `Field` with the given comparison
|
||||||
|
*/
|
||||||
|
fun <T> inArray(name: String, tableName: String, values: List<T>): Field<Pair<String, List<T>>> =
|
||||||
Field(name, Comparison(Op.IN_ARRAY, Pair(tableName, values)))
|
Field(name, Comparison(Op.IN_ARRAY, Pair(tableName, values)))
|
||||||
|
|
||||||
fun Exists(name: String): Field<String> =
|
fun exists(name: String): Field<String> =
|
||||||
Field(name, Comparison(Op.EXISTS, ""))
|
Field(name, Comparison(Op.EXISTS, ""))
|
||||||
|
|
||||||
fun NotExists(name: String): Field<String> =
|
fun notExists(name: String): Field<String> =
|
||||||
Field(name, Comparison(Op.NOT_EXISTS, ""))
|
Field(name, Comparison(Op.NOT_EXISTS, ""))
|
||||||
|
|
||||||
fun Named(name: String): Field<String> =
|
fun named(name: String): Field<String> =
|
||||||
Field(name, Comparison(Op.EQUAL, ""))
|
Field(name, Comparison(Op.EQUAL, ""))
|
||||||
|
|
||||||
fun nameToPath(name: String, dialect: Dialect, format: FieldFormat): String {
|
fun nameToPath(name: String, dialect: Dialect, format: FieldFormat): String {
|
||||||
@ -118,7 +151,7 @@ class Field<T>(
|
|||||||
if (dialect == Dialect.POSTGRESQL) {
|
if (dialect == Dialect.POSTGRESQL) {
|
||||||
path.append("#>", extra, "'{", name.replace('.', ','), "}'")
|
path.append("#>", extra, "'{", name.replace('.', ','), "}'")
|
||||||
} else {
|
} else {
|
||||||
val names = mutableListOf(name.split('.'))
|
val names = name.split('.').toMutableList()
|
||||||
val last = names.removeLast()
|
val last = names.removeLast()
|
||||||
names.forEach { path.append("->'", it, "'") }
|
names.forEach { path.append("->'", it, "'") }
|
||||||
path.append("->", extra, "'", last, "'")
|
path.append("->", extra, "'", last, "'")
|
||||||
|
@ -3,7 +3,7 @@ package solutions.bitbadger.documents.common
|
|||||||
/**
|
/**
|
||||||
* How fields should be matched in by-field queries
|
* How fields should be matched in by-field queries
|
||||||
*/
|
*/
|
||||||
enum class FieldMatch(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`) */
|
||||||
|
@ -143,19 +143,19 @@ object Query {
|
|||||||
val (field, direction) =
|
val (field, direction) =
|
||||||
if (it.name.indexOf(' ') > -1) {
|
if (it.name.indexOf(' ') > -1) {
|
||||||
val parts = it.name.split(' ')
|
val parts = it.name.split(' ')
|
||||||
Pair(Field.Named(parts[0]), " " + parts.drop(1).joinToString(" "))
|
Pair(Field.named(parts[0]), " " + parts.drop(1).joinToString(" "))
|
||||||
} else {
|
} else {
|
||||||
Pair<Field<*>, String?>(it, null)
|
Pair<Field<*>, String?>(it, null)
|
||||||
}
|
}
|
||||||
val path =
|
val path =
|
||||||
if (field.name.startsWith("n:")) {
|
if (field.name.startsWith("n:")) {
|
||||||
val fld = Field.Named(field.name.substring(2))
|
val fld = Field.named(field.name.substring(2))
|
||||||
when (dialect) {
|
when (dialect) {
|
||||||
Dialect.POSTGRESQL -> "(${fld.path(dialect)})::numeric"
|
Dialect.POSTGRESQL -> "(${fld.path(dialect)})::numeric"
|
||||||
Dialect.SQLITE -> fld.path(dialect)
|
Dialect.SQLITE -> fld.path(dialect)
|
||||||
}
|
}
|
||||||
} else if (field.name.startsWith("i:")) {
|
} else if (field.name.startsWith("i:")) {
|
||||||
val p = Field.Named(field.name.substring(2)).path(dialect)
|
val p = Field.named(field.name.substring(2)).path(dialect)
|
||||||
when (dialect) {
|
when (dialect) {
|
||||||
Dialect.POSTGRESQL -> "LOWER($p)"
|
Dialect.POSTGRESQL -> "LOWER($p)"
|
||||||
Dialect.SQLITE -> "$p COLLATE NOCASE"
|
Dialect.SQLITE -> "$p COLLATE NOCASE"
|
||||||
|
20
src/common/src/test/kotlin/FieldMatchTest.kt
Normal file
20
src/common/src/test/kotlin/FieldMatchTest.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package solutions.bitbadger.documents.common
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class FieldMatchTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("ANY uses proper SQL")
|
||||||
|
fun any() {
|
||||||
|
assertEquals("OR", FieldMatch.ANY.sql, "ANY should use OR")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("ALL uses proper SQL")
|
||||||
|
fun all() {
|
||||||
|
assertEquals("AND", FieldMatch.ALL.sql, "ALL should use AND")
|
||||||
|
}
|
||||||
|
}
|
@ -8,13 +8,270 @@ import kotlin.test.assertNull
|
|||||||
class FieldTest {
|
class FieldTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Equal constructs a field")
|
@DisplayName("equal constructs a field")
|
||||||
fun equalCtor() {
|
fun equalCtor() {
|
||||||
val field = Field.Equal("Test", 14)
|
val field = Field.equal("Test", 14)
|
||||||
assertEquals("Test", field.name, "Field name not filled correctly")
|
assertEquals("Test", field.name, "Field name not filled correctly")
|
||||||
assertEquals(Op.EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
assertEquals(Op.EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
assertEquals(14, field.comparison.value, "Field comparison value not filled correctly")
|
assertEquals(14, field.comparison.value, "Field comparison value not filled correctly")
|
||||||
assertNull(field.parameterName, "The parameter name should have been null")
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
assertNull(field.qualifier, "The qualifier should have been null")
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("greater constructs a field")
|
||||||
|
fun greaterCtor() {
|
||||||
|
val field = Field.greater("Great", "night")
|
||||||
|
assertEquals("Great", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.GREATER, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("night", field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("greaterOrEqual constructs a field")
|
||||||
|
fun greaterOrEqualCtor() {
|
||||||
|
val field = Field.greaterOrEqual("Nice", 88L)
|
||||||
|
assertEquals("Nice", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.GREATER_OR_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals(88L, field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("less constructs a field")
|
||||||
|
fun lessCtor() {
|
||||||
|
val field = Field.less("Lesser", "seven")
|
||||||
|
assertEquals("Lesser", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.LESS, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("seven", field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("lessOrEqual constructs a field")
|
||||||
|
fun lessOrEqualCtor() {
|
||||||
|
val field = Field.lessOrEqual("Nobody", "KNOWS")
|
||||||
|
assertEquals("Nobody", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.LESS_OR_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("KNOWS", field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("notEqual constructs a field")
|
||||||
|
fun notEqualCtor() {
|
||||||
|
val field = Field.notEqual("Park", "here")
|
||||||
|
assertEquals("Park", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.NOT_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("here", field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("between constructs a field")
|
||||||
|
fun betweenCtor() {
|
||||||
|
val field = Field.between("Age", 18, 49)
|
||||||
|
assertEquals("Age", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.BETWEEN, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals(18, field.comparison.value.first, "Field comparison min value not filled correctly")
|
||||||
|
assertEquals(49, field.comparison.value.second, "Field comparison max value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("any constructs a field")
|
||||||
|
fun inCtor() {
|
||||||
|
val field = Field.any("Here", listOf(8, 16, 32))
|
||||||
|
assertEquals("Here", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.IN, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals(listOf(8, 16, 32), field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("inArray constructs a field")
|
||||||
|
fun inArrayCtor() {
|
||||||
|
val field = Field.inArray("ArrayField", "table", listOf("z"))
|
||||||
|
assertEquals("ArrayField", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.IN_ARRAY, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("table", field.comparison.value.first, "Field comparison table not filled correctly")
|
||||||
|
assertEquals(listOf("z"), field.comparison.value.second, "Field comparison values not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("exists constructs a field")
|
||||||
|
fun existsCtor() {
|
||||||
|
val field = Field.exists("Groovy")
|
||||||
|
assertEquals("Groovy", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.EXISTS, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("", field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("notExists constructs a field")
|
||||||
|
fun notExistsCtor() {
|
||||||
|
val field = Field.notExists("Groovy")
|
||||||
|
assertEquals("Groovy", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.NOT_EXISTS, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("", field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("named constructs a field")
|
||||||
|
fun namedCtor() {
|
||||||
|
val field = Field.named("Tacos")
|
||||||
|
assertEquals("Tacos", field.name, "Field name not filled correctly")
|
||||||
|
assertEquals(Op.EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||||
|
assertEquals("", field.comparison.value, "Field comparison value not filled correctly")
|
||||||
|
assertNull(field.parameterName, "The parameter name should have been null")
|
||||||
|
assertNull(field.qualifier, "The qualifier should have been null")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a simple PostgreSQL SQL name")
|
||||||
|
fun nameToPathPostgresSimpleSQL() {
|
||||||
|
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a simple SQLite SQL name")
|
||||||
|
fun nameToPathSQLiteSimpleSQL() {
|
||||||
|
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.SQL),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a nested PostgreSQL SQL name")
|
||||||
|
fun nameToPathPostgresNestedSQL() {
|
||||||
|
assertEquals("data#>>'{A,Long,Path,to,the,Property}'",
|
||||||
|
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a nested SQLite SQL name")
|
||||||
|
fun nameToPathSQLiteNestedSQL() {
|
||||||
|
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->>'Property'",
|
||||||
|
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.SQL),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a simple PostgreSQL JSON name")
|
||||||
|
fun nameToPathPostgresSimpleJSON() {
|
||||||
|
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a simple SQLite JSON name")
|
||||||
|
fun nameToPathSQLiteSimpleJSON() {
|
||||||
|
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.JSON),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a nested PostgreSQL JSON name")
|
||||||
|
fun nameToPathPostgresNestedJSON() {
|
||||||
|
assertEquals("data#>'{A,Long,Path,to,the,Property}'",
|
||||||
|
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("nameToPath creates a nested SQLite JSON name")
|
||||||
|
fun nameToPathSQLiteNestedJSON() {
|
||||||
|
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->'Property'",
|
||||||
|
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.JSON),
|
||||||
|
"Path not constructed correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("withParameterName adjusts the parameter name")
|
||||||
|
fun withParameterName() {
|
||||||
|
assertEquals(":name", Field.equal("Bob", "Tom").withParameterName(":name").parameterName,
|
||||||
|
"Parameter name not filled correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("withQualifier adjust the table qualifier")
|
||||||
|
fun withQualifier() {
|
||||||
|
assertEquals("joe", Field.equal("Bill", "Matt").withQualifier("joe").qualifier,
|
||||||
|
"Qualifier not filled correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for simple unqualified PostgreSQL field")
|
||||||
|
fun pathPostgresSimpleUnqualified() {
|
||||||
|
assertEquals("data->>'SomethingCool'",
|
||||||
|
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for simple qualified PostgreSQL field")
|
||||||
|
fun pathPostgresSimpleQualified() {
|
||||||
|
assertEquals("this.data->>'SomethingElse'",
|
||||||
|
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||||
|
"Path not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for nested unqualified PostgreSQL field")
|
||||||
|
fun pathPostgresNestedUnqualified() {
|
||||||
|
assertEquals("data#>>'{My,Nested,Field}'",
|
||||||
|
Field.equal("My.Nested.Field", "howdy").path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for nested qualified PostgreSQL field")
|
||||||
|
fun pathPostgresNestedQualified() {
|
||||||
|
assertEquals("bird.data#>>'{Nest,Away}'",
|
||||||
|
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||||
|
"Path not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for simple unqualified SQLite field")
|
||||||
|
fun pathSQLiteSimpleUnqualified() {
|
||||||
|
assertEquals("data->>'SomethingCool'",
|
||||||
|
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for simple qualified SQLite field")
|
||||||
|
fun pathSQLiteSimpleQualified() {
|
||||||
|
assertEquals("this.data->>'SomethingElse'",
|
||||||
|
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||||
|
"Path not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for nested unqualified SQLite field")
|
||||||
|
fun pathSQLiteNestedUnqualified() {
|
||||||
|
assertEquals("data->'My'->'Nested'->>'Field'",
|
||||||
|
Field.equal("My.Nested.Field", "howdy").path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("path generates for nested qualified SQLite field")
|
||||||
|
fun pathSQLiteNestedQualified() {
|
||||||
|
assertEquals("bird.data->'Nest'->>'Away'",
|
||||||
|
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||||
|
"Path not correct")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
26
src/common/src/test/kotlin/ParameterNameTest.kt
Normal file
26
src/common/src/test/kotlin/ParameterNameTest.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package solutions.bitbadger.documents.common
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class ParameterNameTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("derive works when given existing names")
|
||||||
|
fun withExisting() {
|
||||||
|
val names = ParameterName()
|
||||||
|
assertEquals(":taco", names.derive(":taco"), "Name should have been :taco")
|
||||||
|
assertEquals(":field0", names.derive(null), "Counter should not have advanced for named field")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("derive works when given all anonymous fields")
|
||||||
|
fun allAnonymous() {
|
||||||
|
val names = ParameterName()
|
||||||
|
assertEquals(":field0", names.derive(null), "Anonymous field name should have been returned")
|
||||||
|
assertEquals(":field1", names.derive(null), "Counter should have advanced from previous call")
|
||||||
|
assertEquals(":field2", names.derive(null), "Counter should have advanced from previous call")
|
||||||
|
assertEquals(":field3", names.derive(null), "Counter should have advanced from previous call")
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user