Initial Development #1
@ -254,7 +254,7 @@ object Query {
|
|||||||
* @param docId The ID of the document (optional, used for type checking)
|
* @param docId The ID of the document (optional, used for type checking)
|
||||||
* @return A query to determine document existence by ID
|
* @return A query to determine document existence by ID
|
||||||
*/
|
*/
|
||||||
fun <TKey> byId(tableName: String, docId: TKey?) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
exists(tableName, Where.byId(docId = docId))
|
exists(tableName, Where.byId(docId = docId))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,7 +265,7 @@ object Query {
|
|||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to determine document existence for the given fields
|
* @return A query to determine document existence for the given fields
|
||||||
*/
|
*/
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch?) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
exists(tableName, Where.byFields(fields, howMatched))
|
exists(tableName, Where.byFields(fields, howMatched))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,38 +63,50 @@ class QueryTest {
|
|||||||
@DisplayName("Where.byFields generates multiple fields w/ default match (PostgreSQL)")
|
@DisplayName("Where.byFields generates multiple fields w/ default match (PostgreSQL)")
|
||||||
fun whereByFieldsMultipleDefaultPostgres() {
|
fun whereByFieldsMultipleDefaultPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals("data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three",
|
assertEquals(
|
||||||
|
"data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three",
|
||||||
Query.Where.byFields(
|
Query.Where.byFields(
|
||||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))))
|
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Where.byFields generates multiple fields w/ default match (SQLite)")
|
@DisplayName("Where.byFields generates multiple fields w/ default match (SQLite)")
|
||||||
fun whereByFieldsMultipleDefaultSQLite() {
|
fun whereByFieldsMultipleDefaultSQLite() {
|
||||||
Configuration.connectionString = lite
|
Configuration.connectionString = lite
|
||||||
assertEquals("data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three",
|
assertEquals(
|
||||||
|
"data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three",
|
||||||
Query.Where.byFields(
|
Query.Where.byFields(
|
||||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))))
|
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Where.byFields generates multiple fields w/ ANY match (PostgreSQL)")
|
@DisplayName("Where.byFields generates multiple fields w/ ANY match (PostgreSQL)")
|
||||||
fun whereByFieldsMultipleAnyPostgres() {
|
fun whereByFieldsMultipleAnyPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals("data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three",
|
assertEquals(
|
||||||
|
"data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three",
|
||||||
Query.Where.byFields(
|
Query.Where.byFields(
|
||||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
||||||
FieldMatch.ANY))
|
FieldMatch.ANY
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Where.byFields generates multiple fields w/ ANY match (SQLite)")
|
@DisplayName("Where.byFields generates multiple fields w/ ANY match (SQLite)")
|
||||||
fun whereByFieldsMultipleAnySQLite() {
|
fun whereByFieldsMultipleAnySQLite() {
|
||||||
Configuration.connectionString = lite
|
Configuration.connectionString = lite
|
||||||
assertEquals("data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three",
|
assertEquals(
|
||||||
|
"data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three",
|
||||||
Query.Where.byFields(
|
Query.Where.byFields(
|
||||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
||||||
FieldMatch.ANY))
|
FieldMatch.ANY
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -201,34 +213,46 @@ class QueryTest {
|
|||||||
@DisplayName("byFields generates default field query (PostgreSQL)")
|
@DisplayName("byFields generates default field query (PostgreSQL)")
|
||||||
fun byFieldsMultipleDefaultPostgres() {
|
fun byFieldsMultipleDefaultPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals("this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
|
assertEquals(
|
||||||
Query.byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value"))))
|
"this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
|
||||||
|
Query.byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates default field query (SQLite)")
|
@DisplayName("byFields generates default field query (SQLite)")
|
||||||
fun byFieldsMultipleDefaultSQLite() {
|
fun byFieldsMultipleDefaultSQLite() {
|
||||||
Configuration.connectionString = lite
|
Configuration.connectionString = lite
|
||||||
assertEquals("this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
|
assertEquals(
|
||||||
Query.byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value"))))
|
"this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
|
||||||
|
Query.byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates ANY field query (PostgreSQL)")
|
@DisplayName("byFields generates ANY field query (PostgreSQL)")
|
||||||
fun byFieldsMultipleAnyPostgres() {
|
fun byFieldsMultipleAnyPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals("that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
|
assertEquals(
|
||||||
Query.byFields("that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
"that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
|
||||||
FieldMatch.ANY))
|
Query.byFields(
|
||||||
|
"that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
||||||
|
FieldMatch.ANY
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates ANY field query (SQLite)")
|
@DisplayName("byFields generates ANY field query (SQLite)")
|
||||||
fun byFieldsMultipleAnySQLite() {
|
fun byFieldsMultipleAnySQLite() {
|
||||||
Configuration.connectionString = lite
|
Configuration.connectionString = lite
|
||||||
assertEquals("that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
|
assertEquals(
|
||||||
Query.byFields("that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
"that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
|
||||||
FieldMatch.ANY))
|
Query.byFields(
|
||||||
|
"that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
||||||
|
FieldMatch.ANY
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~~~ Definition ~~~
|
// ~~~ Definition ~~~
|
||||||
@ -236,8 +260,10 @@ class QueryTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Definition.ensureTableFor generates correctly")
|
@DisplayName("Definition.ensureTableFor generates correctly")
|
||||||
fun ensureTableFor() =
|
fun ensureTableFor() =
|
||||||
assertEquals("CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
assertEquals(
|
||||||
Query.Definition.ensureTableFor("my.table", "JSONB"), "CREATE TABLE statement not constructed correctly")
|
"CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
||||||
|
Query.Definition.ensureTableFor("my.table", "JSONB"), "CREATE TABLE statement not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Definition.ensureTable generates correctly (PostgreSQL)")
|
@DisplayName("Definition.ensureTable generates correctly (PostgreSQL)")
|
||||||
@ -262,39 +288,50 @@ class QueryTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Definition.ensureKey generates correctly with schema")
|
@DisplayName("Definition.ensureKey generates correctly with schema")
|
||||||
fun ensureKeyWithSchema() =
|
fun ensureKeyWithSchema() =
|
||||||
assertEquals("CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data->>'id'))",
|
assertEquals(
|
||||||
|
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data->>'id'))",
|
||||||
Query.Definition.ensureKey("test.table", Dialect.POSTGRESQL),
|
Query.Definition.ensureKey("test.table", Dialect.POSTGRESQL),
|
||||||
"CREATE INDEX for key statement with schema not constructed correctly")
|
"CREATE INDEX for key statement with schema not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Definition.ensureKey generates correctly without schema")
|
@DisplayName("Definition.ensureKey generates correctly without schema")
|
||||||
fun ensureKeyWithoutSchema() =
|
fun ensureKeyWithoutSchema() =
|
||||||
assertEquals("CREATE UNIQUE INDEX IF NOT EXISTS idx_${tbl}_key ON $tbl ((data->>'id'))",
|
assertEquals(
|
||||||
|
"CREATE UNIQUE INDEX IF NOT EXISTS idx_${tbl}_key ON $tbl ((data->>'id'))",
|
||||||
Query.Definition.ensureKey(tbl, Dialect.SQLITE),
|
Query.Definition.ensureKey(tbl, Dialect.SQLITE),
|
||||||
"CREATE INDEX for key statement without schema not constructed correctly")
|
"CREATE INDEX for key statement without schema not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Definition.ensureIndexOn generates multiple fields and directions")
|
@DisplayName("Definition.ensureIndexOn generates multiple fields and directions")
|
||||||
fun ensureIndexOnMultipleFields() =
|
fun ensureIndexOnMultipleFields() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table ((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table ((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
||||||
Query.Definition.ensureIndexOn("test.table", "gibberish", listOf("taco", "guac DESC", "salsa ASC"),
|
Query.Definition.ensureIndexOn(
|
||||||
Dialect.POSTGRESQL),
|
"test.table", "gibberish", listOf("taco", "guac DESC", "salsa ASC"),
|
||||||
"CREATE INDEX for multiple field statement not constructed correctly")
|
Dialect.POSTGRESQL
|
||||||
|
),
|
||||||
|
"CREATE INDEX for multiple field statement not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Definition.ensureIndexOn generates nested PostgreSQL field")
|
@DisplayName("Definition.ensureIndexOn generates nested PostgreSQL field")
|
||||||
fun ensureIndexOnNestedPostgres() =
|
fun ensureIndexOnNestedPostgres() =
|
||||||
assertEquals("CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data#>>'{a,b,c}'))",
|
assertEquals(
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data#>>'{a,b,c}'))",
|
||||||
Query.Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.POSTGRESQL),
|
Query.Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.POSTGRESQL),
|
||||||
"CREATE INDEX for nested PostgreSQL field incorrect")
|
"CREATE INDEX for nested PostgreSQL field incorrect"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Definition.ensureIndexOn generates nested SQLite field")
|
@DisplayName("Definition.ensureIndexOn generates nested SQLite field")
|
||||||
fun ensureIndexOnNestedSQLite() =
|
fun ensureIndexOnNestedSQLite() =
|
||||||
assertEquals("CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data->'a'->'b'->>'c'))",
|
assertEquals(
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data->'a'->'b'->>'c'))",
|
||||||
Query.Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.SQLITE),
|
Query.Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.SQLITE),
|
||||||
"CREATE INDEX for nested SQLite field incorrect")
|
"CREATE INDEX for nested SQLite field incorrect"
|
||||||
|
)
|
||||||
|
|
||||||
// ~~~ root functions ~~~
|
// ~~~ root functions ~~~
|
||||||
|
|
||||||
@ -319,7 +356,8 @@ class QueryTest {
|
|||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (:data::jsonb || ('{\"id\":' " +
|
"INSERT INTO $tbl VALUES (:data::jsonb || ('{\"id\":' " +
|
||||||
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $tbl) || '}')::jsonb)",
|
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $tbl) || '}')::jsonb)",
|
||||||
Query.insert(tbl, AutoId.NUMBER))
|
Query.insert(tbl, AutoId.NUMBER)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -329,7 +367,8 @@ class QueryTest {
|
|||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (json_set(:data, '$.id', " +
|
"INSERT INTO $tbl VALUES (json_set(:data, '$.id', " +
|
||||||
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $tbl)))",
|
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $tbl)))",
|
||||||
Query.insert(tbl, AutoId.NUMBER))
|
Query.insert(tbl, AutoId.NUMBER)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -337,8 +376,10 @@ class QueryTest {
|
|||||||
fun insertAutoUUIDPostgres() {
|
fun insertAutoUUIDPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
val query = Query.insert(tbl, AutoId.UUID)
|
val query = Query.insert(tbl, AutoId.UUID)
|
||||||
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
assertTrue(
|
||||||
"Query start not correct (actual: $query)")
|
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
||||||
|
"Query start not correct (actual: $query)"
|
||||||
|
)
|
||||||
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,8 +388,10 @@ class QueryTest {
|
|||||||
fun insertAutoUUIDSQLite() {
|
fun insertAutoUUIDSQLite() {
|
||||||
Configuration.connectionString = lite
|
Configuration.connectionString = lite
|
||||||
val query = Query.insert(tbl, AutoId.UUID)
|
val query = Query.insert(tbl, AutoId.UUID)
|
||||||
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
assertTrue(
|
||||||
"Query start not correct (actual: $query)")
|
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
||||||
|
"Query start not correct (actual: $query)"
|
||||||
|
)
|
||||||
assertTrue(query.endsWith("'))"), "Query end not correct")
|
assertTrue(query.endsWith("'))"), "Query end not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,14 +400,18 @@ class QueryTest {
|
|||||||
fun insertAutoRandomPostgres() {
|
fun insertAutoRandomPostgres() {
|
||||||
try {
|
try {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
Configuration.idStringLength = 8
|
Configuration.idStringLength = 8
|
||||||
val query = Query.insert(tbl, AutoId.RANDOM_STRING)
|
val query = Query.insert(tbl, AutoId.RANDOM_STRING)
|
||||||
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
assertTrue(
|
||||||
"Query start not correct (actual: $query)")
|
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
||||||
|
"Query start not correct (actual: $query)"
|
||||||
|
)
|
||||||
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
||||||
assertEquals(8,
|
assertEquals(
|
||||||
|
8,
|
||||||
query.replace("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\"", "").replace("\"}')", "").length,
|
query.replace("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\"", "").replace("\"}')", "").length,
|
||||||
"Random string length incorrect")
|
"Random string length incorrect"
|
||||||
|
)
|
||||||
} finally {
|
} finally {
|
||||||
Configuration.idStringLength = 16
|
Configuration.idStringLength = 16
|
||||||
}
|
}
|
||||||
@ -375,12 +422,16 @@ class QueryTest {
|
|||||||
fun insertAutoRandomSQLite() {
|
fun insertAutoRandomSQLite() {
|
||||||
Configuration.connectionString = lite
|
Configuration.connectionString = lite
|
||||||
val query = Query.insert(tbl, AutoId.RANDOM_STRING)
|
val query = Query.insert(tbl, AutoId.RANDOM_STRING)
|
||||||
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
assertTrue(
|
||||||
"Query start not correct (actual: $query)")
|
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
||||||
|
"Query start not correct (actual: $query)"
|
||||||
|
)
|
||||||
assertTrue(query.endsWith("'))"), "Query end not correct")
|
assertTrue(query.endsWith("'))"), "Query end not correct")
|
||||||
assertEquals(Configuration.idStringLength,
|
assertEquals(
|
||||||
|
Configuration.idStringLength,
|
||||||
query.replace("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '", "").replace("'))", "").length,
|
query.replace("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '", "").replace("'))", "").length,
|
||||||
"Random string length incorrect")
|
"Random string length incorrect"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -395,7 +446,8 @@ class QueryTest {
|
|||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
"INSERT INTO $tbl VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
||||||
Query.save(tbl), "INSERT ON CONFLICT UPDATE statement not constructed correctly")
|
Query.save(tbl), "INSERT ON CONFLICT UPDATE statement not constructed correctly"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -407,26 +459,32 @@ class QueryTest {
|
|||||||
@DisplayName("Count.byFields generates correctly (PostgreSQL)")
|
@DisplayName("Count.byFields generates correctly (PostgreSQL)")
|
||||||
fun countByFieldsPostgres() {
|
fun countByFieldsPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals("SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
assertEquals(
|
||||||
|
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
||||||
Query.Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
Query.Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
||||||
"Count query not constructed correctly")
|
"Count query not constructed correctly"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Count.byFields generates correctly (PostgreSQL)")
|
@DisplayName("Count.byFields generates correctly (PostgreSQL)")
|
||||||
fun countByFieldsSQLite() {
|
fun countByFieldsSQLite() {
|
||||||
Configuration.connectionString = lite
|
Configuration.connectionString = lite
|
||||||
assertEquals("SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
assertEquals(
|
||||||
|
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
||||||
Query.Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
Query.Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
||||||
"Count query not constructed correctly")
|
"Count query not constructed correctly"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Count.byContains generates correctly (PostgreSQL)")
|
@DisplayName("Count.byContains generates correctly (PostgreSQL)")
|
||||||
fun countByContainsPostgres() {
|
fun countByContainsPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals("SELECT COUNT(*) AS it FROM $tbl WHERE data @> :criteria", Query.Count.byContains(tbl),
|
assertEquals(
|
||||||
"Count query not constructed correctly")
|
"SELECT COUNT(*) AS it FROM $tbl WHERE data @> :criteria", Query.Count.byContains(tbl),
|
||||||
|
"Count query not constructed correctly"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -440,8 +498,10 @@ class QueryTest {
|
|||||||
@DisplayName("Count.byJsonPath generates correctly (PostgreSQL)")
|
@DisplayName("Count.byJsonPath generates correctly (PostgreSQL)")
|
||||||
fun countByJsonPathPostgres() {
|
fun countByJsonPathPostgres() {
|
||||||
Configuration.connectionString = pg
|
Configuration.connectionString = pg
|
||||||
assertEquals("SELECT COUNT(*) AS it FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)",
|
assertEquals(
|
||||||
Query.Count.byJsonPath(tbl), "Count query not constructed correctly")
|
"SELECT COUNT(*) AS it FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
|
Query.Count.byJsonPath(tbl), "Count query not constructed correctly"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -451,11 +511,81 @@ class QueryTest {
|
|||||||
assertThrows<DocumentException> { Query.Count.byJsonPath(tbl) }
|
assertThrows<DocumentException> { Query.Count.byJsonPath(tbl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// @DisplayName("exists generates correctly")
|
@DisplayName("Exists.byId generates correctly (PostgreSQL)")
|
||||||
// fun exists() =
|
fun existsByIdPostgres() {
|
||||||
// assertEquals("SELECT EXISTS (SELECT 1 FROM $tbl WHERE turkey) AS it", Query.exists(tbl, "turkey"),
|
Configuration.connectionString = pg
|
||||||
// "Exists query not constructed correctly")
|
assertEquals(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
||||||
|
Query.Exists.byId<String>(tbl), "Exists query not constructed correctly"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Exists.byId generates correctly (SQLite)")
|
||||||
|
fun existsByIdSQLite() {
|
||||||
|
Configuration.connectionString = lite
|
||||||
|
assertEquals(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
||||||
|
Query.Exists.byId<String>(tbl), "Exists query not constructed correctly"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Exists.byFields generates correctly (PostgreSQL)")
|
||||||
|
fun existsByFieldsPostgres() {
|
||||||
|
Configuration.connectionString = pg
|
||||||
|
assertEquals(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE (data->>'it')::numeric = :test) AS it",
|
||||||
|
Query.Exists.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
||||||
|
"Exists query not constructed correctly"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Exists.byFields generates correctly (SQLite)")
|
||||||
|
fun existsByFieldsSQLite() {
|
||||||
|
Configuration.connectionString = lite
|
||||||
|
assertEquals(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'it' = :test) AS it",
|
||||||
|
Query.Exists.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
||||||
|
"Exists query not constructed correctly"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Exists.byContains generates correctly (PostgreSQL)")
|
||||||
|
fun existsByContainsPostgres() {
|
||||||
|
Configuration.connectionString = pg
|
||||||
|
assertEquals(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data @> :criteria) AS it", Query.Exists.byContains(tbl),
|
||||||
|
"Exists query not constructed correctly"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Exists.byContains fails (SQLite)")
|
||||||
|
fun existsByContainsSQLite() {
|
||||||
|
Configuration.connectionString = lite
|
||||||
|
assertThrows<DocumentException> { Query.Exists.byContains(tbl) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Exists.byJsonPath generates correctly (PostgreSQL)")
|
||||||
|
fun existsByJsonPathPostgres() {
|
||||||
|
Configuration.connectionString = pg
|
||||||
|
assertEquals(
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
||||||
|
Query.Exists.byJsonPath(tbl), "Exists query not constructed correctly"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Exists.byJsonPath fails (SQLite)")
|
||||||
|
fun existsByJsonPathSQLite() {
|
||||||
|
Configuration.connectionString = lite
|
||||||
|
assertThrows<DocumentException> { Query.Exists.byJsonPath(tbl) }
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Find.all generates correctly")
|
@DisplayName("Find.all generates correctly")
|
||||||
@ -482,56 +612,74 @@ class QueryTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates single, no direction for PostgreSQL")
|
@DisplayName("orderBy generates single, no direction for PostgreSQL")
|
||||||
fun orderBySinglePostgres() =
|
fun orderBySinglePostgres() =
|
||||||
assertEquals(" ORDER BY data->>'TestField'",
|
assertEquals(
|
||||||
Query.orderBy(listOf(Field.named("TestField")), Dialect.POSTGRESQL), "ORDER BY not constructed correctly")
|
" ORDER BY data->>'TestField'",
|
||||||
|
Query.orderBy(listOf(Field.named("TestField")), Dialect.POSTGRESQL), "ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates single, no direction for SQLite")
|
@DisplayName("orderBy generates single, no direction for SQLite")
|
||||||
fun orderBySingleSQLite() =
|
fun orderBySingleSQLite() =
|
||||||
assertEquals(" ORDER BY data->>'TestField'", Query.orderBy(listOf(Field.named("TestField")), Dialect.SQLITE),
|
assertEquals(
|
||||||
"ORDER BY not constructed correctly")
|
" ORDER BY data->>'TestField'", Query.orderBy(listOf(Field.named("TestField")), Dialect.SQLITE),
|
||||||
|
"ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates multiple with direction for PostgreSQL")
|
@DisplayName("orderBy generates multiple with direction for PostgreSQL")
|
||||||
fun orderByMultiplePostgres() =
|
fun orderByMultiplePostgres() =
|
||||||
assertEquals(" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
|
assertEquals(
|
||||||
|
" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||||
Query.orderBy(
|
Query.orderBy(
|
||||||
listOf(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
listOf(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
||||||
Dialect.POSTGRESQL),
|
Dialect.POSTGRESQL
|
||||||
"ORDER BY not constructed correctly")
|
),
|
||||||
|
"ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates multiple with direction for SQLite")
|
@DisplayName("orderBy generates multiple with direction for SQLite")
|
||||||
fun orderByMultipleSQLite() =
|
fun orderByMultipleSQLite() =
|
||||||
assertEquals(" ORDER BY data->'Nested'->'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
|
assertEquals(
|
||||||
|
" ORDER BY data->'Nested'->'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||||
Query.orderBy(
|
Query.orderBy(
|
||||||
listOf(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
listOf(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
||||||
Dialect.SQLITE),
|
Dialect.SQLITE
|
||||||
"ORDER BY not constructed correctly")
|
),
|
||||||
|
"ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates numeric ordering PostgreSQL")
|
@DisplayName("orderBy generates numeric ordering PostgreSQL")
|
||||||
fun orderByNumericPostgres() =
|
fun orderByNumericPostgres() =
|
||||||
assertEquals(" ORDER BY (data->>'Test')::numeric",
|
assertEquals(
|
||||||
Query.orderBy(listOf(Field.named("n:Test")), Dialect.POSTGRESQL), "ORDER BY not constructed correctly")
|
" ORDER BY (data->>'Test')::numeric",
|
||||||
|
Query.orderBy(listOf(Field.named("n:Test")), Dialect.POSTGRESQL), "ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates numeric ordering for SQLite")
|
@DisplayName("orderBy generates numeric ordering for SQLite")
|
||||||
fun orderByNumericSQLite() =
|
fun orderByNumericSQLite() =
|
||||||
assertEquals(" ORDER BY data->>'Test'", Query.orderBy(listOf(Field.named("n:Test")), Dialect.SQLITE),
|
assertEquals(
|
||||||
"ORDER BY not constructed correctly")
|
" ORDER BY data->>'Test'", Query.orderBy(listOf(Field.named("n:Test")), Dialect.SQLITE),
|
||||||
|
"ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates case-insensitive ordering for PostgreSQL")
|
@DisplayName("orderBy generates case-insensitive ordering for PostgreSQL")
|
||||||
fun orderByCIPostgres() =
|
fun orderByCIPostgres() =
|
||||||
assertEquals(" ORDER BY LOWER(data#>>'{Test,Field}') DESC NULLS FIRST",
|
assertEquals(
|
||||||
|
" ORDER BY LOWER(data#>>'{Test,Field}') DESC NULLS FIRST",
|
||||||
Query.orderBy(listOf(Field.named("i:Test.Field DESC NULLS FIRST")), Dialect.POSTGRESQL),
|
Query.orderBy(listOf(Field.named("i:Test.Field DESC NULLS FIRST")), Dialect.POSTGRESQL),
|
||||||
"ORDER BY not constructed correctly")
|
"ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("orderBy generates case-insensitive ordering for SQLite")
|
@DisplayName("orderBy generates case-insensitive ordering for SQLite")
|
||||||
fun orderByCISQLite() =
|
fun orderByCISQLite() =
|
||||||
assertEquals(" ORDER BY data->'Test'->>'Field' COLLATE NOCASE ASC NULLS LAST",
|
assertEquals(
|
||||||
|
" ORDER BY data->'Test'->>'Field' COLLATE NOCASE ASC NULLS LAST",
|
||||||
Query.orderBy(listOf(Field.named("i:Test.Field ASC NULLS LAST")), Dialect.SQLITE),
|
Query.orderBy(listOf(Field.named("i:Test.Field ASC NULLS LAST")), Dialect.SQLITE),
|
||||||
"ORDER BY not constructed correctly")
|
"ORDER BY not constructed correctly"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user