Skip to content

Commit

Permalink
Improve xList overloads to check types better forcing list methods (#…
Browse files Browse the repository at this point in the history
…15)

* Improved the api to to force using list overloads where it can't detect the collection
Removed some xList overloads to use type detection instead.

* fix rebae
  • Loading branch information
chrisjenx authored Feb 4, 2025
1 parent 2826bfb commit 927b799
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 16 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ org.gradle.daemon=true
org.gradle.parallel=true
# Maven
GROUP=com.mercury.sqkon
VERSION_NAME=1.0.0-alpha06
VERSION_NAME=1.0.0-alpha07
POM_NAME=Sqkon
POM_INCEPTION_YEAR=2024
POM_URL=https://github.com/MercuryTechnologies/sqkon/
Expand Down
35 changes: 21 additions & 14 deletions library/src/commonMain/kotlin/com/mercury/sqkon/db/JsonPath.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ class JsonPathBuilder<R : Any>

// Handles collection property type and extracts the element type vs the list type
@PublishedApi
internal inline fun <reified R1 : R, reified V : Any?> withList(
@JvmName("withList")
internal inline fun <reified R1 : R, reified V : Any?> with(
property: KProperty1<R, Collection<V>>,
serialName: String? = null,
block: JsonPathNode<R, V>.() -> Unit = {}
Expand Down Expand Up @@ -135,20 +136,20 @@ class JsonPathBuilder<R : Any>

// Builder Methods to start building paths

inline fun <reified R : Any, reified V> KProperty1<R, V>.builder(
inline fun <reified R : Any, reified V : Any?> KProperty1<R, V>.builder(
serialName: String? = null,
block: JsonPathNode<R, V>.() -> Unit = {}
): JsonPathBuilder<R> {
return JsonPathBuilder<R>().with<R, V>(property = this, serialName = serialName, block = block)
}

inline fun <reified R : Any, reified V> KProperty1<R, Collection<V>>.builderFromList(
inline fun <reified R : Any, reified V : Any?> KProperty1<R, Collection<V>>.builderFromList(
block: JsonPathNode<out R, V>.() -> Unit = {}
): JsonPathBuilder<R> {
return JsonPathBuilder<R>().withList<R, V>(property = this, block = block)
return JsonPathBuilder<R>().with<R, V>(property = this, block = block)
}

inline fun <reified R : Any, reified V : Any?, reified V1 : V, reified V2 : Any?> KProperty1<R, V>.then(
inline fun <reified R : Any, reified V : Any?, reified V1 : V, reified V2> KProperty1<R, V>.then(
property: KProperty1<V1, V2>,
fromSerialName: String? = null,
thenSerialName: String? = null,
Expand All @@ -160,50 +161,55 @@ inline fun <reified R : Any, reified V : Any?, reified V1 : V, reified V2 : Any?
}
}

inline fun <reified R : Any, reified V, reified V1 : V, reified V2> KProperty1<R, Collection<V>>.thenFromList(
@JvmName("thenFromList")
inline fun <reified R : Any, reified V, reified V1 : V, reified V2> KProperty1<R, Collection<V>>.then(
property: KProperty1<V1, V2>,
fromSerialName: String? = null,
thenSerialName: String? = null,
block: JsonPathNode<V1, V2>.() -> Unit = {}
): JsonPathBuilder<R> {
return JsonPathBuilder<R>()
.withList<R, V>(property = this, fromSerialName) {
.with<R, V>(property = this, fromSerialName) {
then<V1, V2>(property = property, serialName = thenSerialName, block = block)
}
}


inline fun <reified R : Any, reified V, reified V2> KProperty1<R, V>.thenList(
@JvmName("thenList")
inline fun <reified R : Any, reified V, reified V2> KProperty1<R, V>.then(
property: KProperty1<out V, Collection<V2>>,
block: JsonPathNode<out V, V2>.() -> Unit = {}
): JsonPathBuilder<R> {
return JsonPathBuilder<R>().with<R, V>(property = this) {
thenList(property = property, block = block)
then(property = property, block = block)
}
}

inline fun <reified R : Any, reified R1 : R, reified V> KClass<R>.with(
property: KProperty1<R1, V>,
serialName: String? = null,
block: JsonPathNode<R, V>.() -> Unit = {}
): JsonPathBuilder<R> {
return JsonPathBuilder<R>().with<R1, V>(
baseType = typeOf<R>(), property = property, block = block
)
baseType = typeOf<R>(), property = property, block = block, serialName = serialName,
)
}

// Handles collection property type
@Suppress("UnusedReceiverParameter")
inline fun <reified R : Any, reified V : Any?> KClass<R>.withList(
property: KProperty1<R, Collection<V>>,
serialName: String? = null,
block: JsonPathNode<R, V>.() -> Unit = {}
): JsonPathBuilder<R> {
return JsonPathBuilder<R>().withList<R, V>(property = property, block = block)
return JsonPathBuilder<R>()
.with<R, V>(property = property, block = block, serialName = serialName)
}

/**
* Represents a path in a JSON object, using limited reflection and descriptors to build the path.
*
* Start building using [with] or [withList]
* Start building using [with].
*/
class JsonPathNode<R : Any?, V : Any?>
@PublishedApi
Expand Down Expand Up @@ -241,7 +247,8 @@ internal constructor(
*
* This returns the Collection element type, so you can chain into the next property.
*/
inline fun <reified V2 : Any?> thenList(
@JvmName("thenList")
inline fun <reified V2 : Any?> then(
property: KProperty1<out V, Collection<V2>>,
serialName: String? = null,
block: JsonPathNode<out V, V2>.() -> Unit = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ data class TestObject(
data class TestObjectChild(
val createdAt: Instant = Clock.System.now(),
val updatedAt: Instant = Clock.System.now(),
val subList: List<String> = listOf("1", "2", "3"),
)

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,16 @@ class JsonPathBuilderTest {
assertEquals(expected = "\$.list[%].createdAt", actual = builder.buildPath())
}

@Test
fun build_with_then_list() {
val builder = TestObject::child.then(TestObjectChild::subList)
assertEquals(expected = "\$.child.subList[%]", actual = builder.buildPath())
}


@Test
fun build_with_list_then() {
val builder = TestObject::list.thenFromList(TestObjectChild::createdAt)
val builder = TestObject::list.then(TestObjectChild::createdAt)
assertEquals(expected = "\$.list[%].createdAt", actual = builder.buildPath())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,5 +516,20 @@ class KeyValueStorageTest {
}
}

@Test
fun select_inList() = runTest{
val expectedO = TestObject()
testObjectStorage.insert(expectedO.id, expectedO)

val expectedList = expectedO.list.map { it.createdAt.toString() }

val actual = testObjectStorage.select(
where = TestObject::list.then(TestObjectChild::createdAt) inList expectedList
).first()

assertEquals(expectedO, actual.first())
assertEquals(expectedO.list, actual.first().list)
}


}

0 comments on commit 927b799

Please sign in to comment.