Add remove fields functions

This commit is contained in:
2025-03-01 20:50:55 -05:00
parent d0375d14fc
commit aae7dfe11d
13 changed files with 465 additions and 24 deletions

View File

@@ -23,13 +23,10 @@ data class ArrayDocument(val id: String, val values: List<String>) {
}
@Serializable
data class JsonDocument(val id: String, val value: String, val numValue: Int, val sub: SubDocument?) {
data class JsonDocument(val id: String, val value: String = "", val numValue: Int = 0, val sub: SubDocument? = null) {
companion object {
/** An empty JsonDocument */
val emptyDoc = JsonDocument("", "", 0, null)
/** Documents to use for testing */
val testDocuments = listOf(
private val testDocuments = listOf(
JsonDocument("one", "FIRST!", 0, null),
JsonDocument("two", "another", 10, SubDocument("green", "blue")),
JsonDocument("three", "", 4, null),

View File

@@ -56,7 +56,7 @@ object Document {
Configuration.autoIdStrategy = AutoId.UUID
assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table")
db.conn.insert(TEST_TABLE, JsonDocument.emptyDoc)
db.conn.insert(TEST_TABLE, JsonDocument(""))
val after = db.conn.findAll<JsonDocument>(TEST_TABLE)
assertEquals(1, after.size, "There should have been 1 document returned")
@@ -71,10 +71,10 @@ object Document {
Configuration.autoIdStrategy = AutoId.RANDOM_STRING
assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table")
db.conn.insert(TEST_TABLE, JsonDocument.emptyDoc)
db.conn.insert(TEST_TABLE, JsonDocument(""))
Configuration.idStringLength = 21
db.conn.insert(TEST_TABLE, JsonDocument.emptyDoc)
db.conn.insert(TEST_TABLE, JsonDocument(""))
val after = db.conn.findAll<JsonDocument>(TEST_TABLE)
assertEquals(2, after.size, "There should have been 2 documents returned")

View File

@@ -7,7 +7,7 @@ import kotlin.test.assertNotNull
import kotlin.test.assertTrue
/**
* Integration tests for the `Find` object
* Integration tests for the `Patch` object
*/
object Patch {

View File

@@ -0,0 +1,106 @@
package solutions.bitbadger.documents.common
import solutions.bitbadger.documents.*
import kotlin.test.*
/**
* Integration tests for the `RemoveFields` object
*/
object RemoveFields {
fun byIdMatchFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
db.conn.removeFieldsById(TEST_TABLE, "two", listOf("sub", "value"))
val doc = db.conn.findById<String, JsonDocument>(TEST_TABLE, "two")
assertNotNull(doc, "There should have been a document returned")
assertEquals("", doc.value, "The value should have been empty")
assertNull(doc.sub, "The sub-document should have been removed")
}
fun byIdMatchNoFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("a_field_that_does_not_exist"))) }
db.conn.removeFieldsById(TEST_TABLE, "one", listOf("a_field_that_does_not_exist")) // no exception = pass
}
fun byIdNoMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertFalse { db.conn.existsById(TEST_TABLE, "fifty") }
db.conn.removeFieldsById(TEST_TABLE, "fifty", listOf("sub")) // no exception = pass
}
fun byFieldsMatchFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
val fields = listOf(Field.equal("numValue", 17))
db.conn.removeFieldsByFields(TEST_TABLE, fields, listOf("sub"))
val doc = db.conn.findFirstByFields<JsonDocument>(TEST_TABLE, fields)
assertNotNull(doc, "The document should have been returned")
assertEquals("four", doc.id, "An incorrect document was returned")
assertNull(doc.sub, "The sub-document should have been removed")
}
fun byFieldsMatchNoFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("nada"))) }
db.conn.removeFieldsByFields(TEST_TABLE, listOf(Field.equal("numValue", 17)), listOf("nada")) // no exn = pass
}
fun byFieldsNoMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
val fields = listOf(Field.notEqual("missing", "nope"))
assertFalse { db.conn.existsByFields(TEST_TABLE, fields) }
db.conn.removeFieldsByFields(TEST_TABLE, fields, listOf("value")) // no exception = pass
}
fun byContainsMatchFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
val criteria = mapOf("sub" to mapOf("foo" to "green"))
db.conn.removeFieldsByContains(TEST_TABLE, criteria, listOf("value"))
val docs = db.conn.findByContains<JsonDocument, Map<String, Map<String, String>>>(TEST_TABLE, criteria)
assertEquals(2, docs.size, "There should have been 2 documents returned")
docs.forEach {
assertTrue(listOf("two", "four").contains(it.id), "An incorrect document was returned (${it.id})")
assertEquals("", it.value, "The value should have been empty")
}
}
fun byContainsMatchNoFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("invalid_field"))) }
db.conn.removeFieldsByContains(TEST_TABLE, mapOf("sub" to mapOf("foo" to "green")), listOf("invalid_field"))
// no exception = pass
}
fun byContainsNoMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
val contains = mapOf("value" to "substantial")
assertFalse { db.conn.existsByContains(TEST_TABLE, contains) }
db.conn.removeFieldsByContains(TEST_TABLE, contains, listOf("numValue"))
}
fun byJsonPathMatchFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
val path = "$.value ? (@ == \"purple\")"
db.conn.removeFieldsByJsonPath(TEST_TABLE, path, listOf("sub"))
val docs = db.conn.findByJsonPath<JsonDocument>(TEST_TABLE, path)
assertEquals(2, docs.size, "There should have been 2 documents returned")
docs.forEach {
assertTrue(listOf("four", "five").contains(it.id), "An incorrect document was returned (${it.id})")
assertNull(it.sub, "The sub-document should have been removed")
}
}
fun byJsonPathMatchNoFields(db: ThrowawayDatabase) {
JsonDocument.load(db)
assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("submarine"))) }
db.conn.removeFieldsByJsonPath(TEST_TABLE, "$.value ? (@ == \"purple\")", listOf("submarine")) // no exn = pass
}
fun byJsonPathNoMatch(db: ThrowawayDatabase) {
JsonDocument.load(db)
val path = "$.value ? (@ == \"mauve\")"
assertFalse { db.conn.existsByJsonPath(TEST_TABLE, path) }
db.conn.removeFieldsByJsonPath(TEST_TABLE, path, listOf("value")) // no exception = pass
}
}

View File

@@ -0,0 +1,72 @@
package solutions.bitbadger.documents.postgresql
import org.junit.jupiter.api.DisplayName
import solutions.bitbadger.documents.common.RemoveFields
import kotlin.test.Test
/**
* PostgreSQL integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
*/
@DisplayName("PostgreSQL - RemoveFields")
class RemoveFieldsIT {
@Test
@DisplayName("byId removes fields from an existing document")
fun byIdMatchFields() =
PgDB().use(RemoveFields::byIdMatchFields)
@Test
@DisplayName("byId succeeds when fields do not exist on an existing document")
fun byIdMatchNoFields() =
PgDB().use(RemoveFields::byIdMatchNoFields)
@Test
@DisplayName("byId succeeds when no document exists")
fun byIdNoMatch() =
PgDB().use(RemoveFields::byIdNoMatch)
@Test
@DisplayName("byFields removes fields from matching documents")
fun byFieldsMatchFields() =
PgDB().use(RemoveFields::byFieldsMatchFields)
@Test
@DisplayName("byFields succeeds when fields do not exist on matching documents")
fun byFieldsMatchNoFields() =
PgDB().use(RemoveFields::byFieldsMatchNoFields)
@Test
@DisplayName("byFields succeeds when no matching documents exist")
fun byFieldsNoMatch() =
PgDB().use(RemoveFields::byFieldsNoMatch)
@Test
@DisplayName("byContains removes fields from matching documents")
fun byContainsMatchFields() =
PgDB().use(RemoveFields::byContainsMatchFields)
@Test
@DisplayName("byContains succeeds when fields do not exist on matching documents")
fun byContainsMatchNoFields() =
PgDB().use(RemoveFields::byContainsMatchNoFields)
@Test
@DisplayName("byContains succeeds when no matching documents exist")
fun byContainsNoMatch() =
PgDB().use(RemoveFields::byContainsNoMatch)
@Test
@DisplayName("byJsonPath removes fields from matching documents")
fun byJsonPathMatchFields() =
PgDB().use(RemoveFields::byJsonPathMatchFields)
@Test
@DisplayName("byJsonPath succeeds when fields do not exist on matching documents")
fun byJsonPathMatchNoFields() =
PgDB().use(RemoveFields::byJsonPathMatchNoFields)
@Test
@DisplayName("byJsonPath succeeds when no matching documents exist")
fun byJsonPathNoMatch() =
PgDB().use(RemoveFields::byJsonPathNoMatch)
}

View File

@@ -0,0 +1,56 @@
package solutions.bitbadger.documents.sqlite
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.assertThrows
import solutions.bitbadger.documents.DocumentException
import solutions.bitbadger.documents.common.RemoveFields
import kotlin.test.Test
/**
* SQLite integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
*/
@DisplayName("SQLite - RemoveFields")
class RemoveFieldsIT {
@Test
@DisplayName("byId removes fields from an existing document")
fun byIdMatchFields() =
SQLiteDB().use(RemoveFields::byIdMatchFields)
@Test
@DisplayName("byId succeeds when fields do not exist on an existing document")
fun byIdMatchNoFields() =
SQLiteDB().use(RemoveFields::byIdMatchNoFields)
@Test
@DisplayName("byId succeeds when no document exists")
fun byIdNoMatch() =
SQLiteDB().use(RemoveFields::byIdNoMatch)
@Test
@DisplayName("byFields removes fields from matching documents")
fun byFieldsMatchFields() =
SQLiteDB().use(RemoveFields::byFieldsMatchFields)
@Test
@DisplayName("byFields succeeds when fields do not exist on matching documents")
fun byFieldsMatchNoFields() =
SQLiteDB().use(RemoveFields::byFieldsMatchNoFields)
@Test
@DisplayName("byFields succeeds when no matching documents exist")
fun byFieldsNoMatch() =
SQLiteDB().use(RemoveFields::byFieldsNoMatch)
@Test
@DisplayName("byContains fails")
fun byContainsFails() {
assertThrows<DocumentException> { SQLiteDB().use(RemoveFields::byContainsMatchFields) }
}
@Test
@DisplayName("byJsonPath fails")
fun byJsonPathFails() {
assertThrows<DocumentException> { SQLiteDB().use(RemoveFields::byJsonPathMatchFields) }
}
}