Skip to content

Commit

Permalink
Nullable record if recordName not found (#51)
Browse files Browse the repository at this point in the history
Co-authored-by: hfhbd <hfhbd@users.noreply.github.com>
  • Loading branch information
hfhbd and hfhbd authored May 16, 2021
1 parent f2fb88b commit f1b8867
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 24 deletions.
73 changes: 73 additions & 0 deletions cloudkitclient-core/api/cloudkitclient-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,47 @@ public final class app/softwork/cloudkitclient/Environment$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class app/softwork/cloudkitclient/Error : java/lang/Exception {
public static final field Companion Lapp/softwork/cloudkitclient/Error$Companion;
public fun <init> ()V
public synthetic fun <init> (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/String;
public final fun component4 ()Ljava/lang/Integer;
public final fun component5 ()Ljava/lang/String;
public final fun component6 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;)Lapp/softwork/cloudkitclient/Error;
public static synthetic fun copy$default (Lapp/softwork/cloudkitclient/Error;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lapp/softwork/cloudkitclient/Error;
public fun equals (Ljava/lang/Object;)Z
public final fun getReason ()Ljava/lang/String;
public final fun getRecordName ()Ljava/lang/String;
public final fun getRedirectURL ()Ljava/lang/String;
public final fun getRetryAfter ()Ljava/lang/Integer;
public final fun getServerErrorCode ()Ljava/lang/String;
public final fun getUuid ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class app/softwork/cloudkitclient/Error$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lapp/softwork/cloudkitclient/Error$$serializer;
public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor;
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lapp/softwork/cloudkitclient/Error;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lapp/softwork/cloudkitclient/Error;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class app/softwork/cloudkitclient/Error$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class app/softwork/cloudkitclient/Filter {
public static final field Companion Lapp/softwork/cloudkitclient/Filter$Companion;
public synthetic fun <init> (ILjava/lang/String;Lapp/softwork/cloudkitclient/Filter$Comparator;Lapp/softwork/cloudkitclient/values/Value;Ljava/lang/Double;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
Expand Down Expand Up @@ -432,6 +473,38 @@ public abstract interface class app/softwork/cloudkitclient/Record$Information {
public abstract fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class app/softwork/cloudkitclient/Response {
public static final field Companion Lapp/softwork/cloudkitclient/Response$Companion;
public synthetic fun <init> (ILjava/util/List;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
public fun <init> (Ljava/util/List;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/util/List;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/util/List;
public final fun component2 ()Ljava/lang/String;
public final fun copy (Ljava/util/List;Ljava/lang/String;)Lapp/softwork/cloudkitclient/Response;
public static synthetic fun copy$default (Lapp/softwork/cloudkitclient/Response;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Lapp/softwork/cloudkitclient/Response;
public fun equals (Ljava/lang/Object;)Z
public final fun getContinuationMarker ()Ljava/lang/String;
public final fun getRecords ()Ljava/util/List;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class app/softwork/cloudkitclient/Response$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun <init> (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)V
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lapp/softwork/cloudkitclient/Response;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lapp/softwork/cloudkitclient/Response;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class app/softwork/cloudkitclient/Response$Companion {
public final fun serializer (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
}

public final class app/softwork/cloudkitclient/Sort {
public static final field Companion Lapp/softwork/cloudkitclient/Sort$Companion;
public synthetic fun <init> (ILjava/lang/String;ZLapp/softwork/cloudkitclient/types/Location;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ public class CKClient(

public inner class Database internal constructor(internal val name: String) : Client.Database {
public override suspend fun <F : Fields, R : Record<F>> query(
recordInformation: Record.Information<F, R>,
recordInformation: Information<F, R>,
zoneID: ZoneID,
filter: Filter.Builder<F>.() -> Unit,
sort: Sort.Builder<F>.() -> Unit
sort: Sort.Builder<F>.() -> Unit,
filter: Filter.Builder<F>.() -> Unit
): List<R> = request("/records/query", Request.serializer()) {
Request(
zoneID = zoneID,
Expand All @@ -62,7 +62,7 @@ public class CKClient(

public override suspend fun <F : Fields, R : Record<F>> create(
record: R,
recordInformation: Record.Information<F, R>
recordInformation: Information<F, R>
): R =
request(
"/records/modify",
Expand All @@ -79,13 +79,20 @@ public class CKClient(
recordName: String,
recordInformation: Information<F, R>,
zoneID: ZoneID
): R = request("/records/lookup", Request.RecordLookup.serializer()) {
): R? = request("/records/lookup", Request.RecordLookup.serializer()) {
Request.RecordLookup(listOf(Request.RecordLookup.RecordName(recordName = recordName)), zoneID = zoneID)
}.toRegularResponse(recordInformation).first()
}.handleError(recordInformation).run {
when (this) {
is Holder.Success -> response.records.single()
is Holder.Failure -> {
if (error.serverErrorCode == "NOT_FOUND") null else throw error
}
}
}

public override suspend fun <F : Fields, R : Record<F>> update(
record: R,
recordInformation: Record.Information<F, R>
recordInformation: Information<F, R>
): R =
request(
"/records/modify",
Expand All @@ -100,7 +107,7 @@ public class CKClient(

public override suspend fun <F : Fields, R : Record<F>> delete(
record: R,
recordInformation: Record.Information<F, R>
recordInformation: Information<F, R>
) {
request(
"/records/modify",
Expand All @@ -116,7 +123,7 @@ public class CKClient(

override suspend fun <F : Fields, R : Record<F>> upload(
asset: ByteArray,
recordInformation: Record.Information<F, R>,
recordInformation: Information<F, R>,
field: KProperty1<F, Value.Asset?>,
recordName: String?,
zoneID: ZoneID
Expand Down Expand Up @@ -167,14 +174,42 @@ public class CKClient(
this.body = body
}

private fun <F : Fields, R : Record<F>> String.toRegularResponse(recordInformation: Record.Information<F, R>) =
let {
println(it)
json.decodeFromString(
private fun <F : Fields, R : Record<F>> String.toRegularResponse(recordInformation: Information<F, R>): List<R> {
val response = json.decodeFromString(
Response.serializer(
recordInformation.fieldsSerializer(),
recordInformation.serializer()
), this
)
return response.records
}


private fun <F : Fields, R : Record<F>> String.handleError(
recordInformation: Information<F, R>
): Holder<F, R> =
try {
val response = json.decodeFromString(
Response.serializer(
recordInformation.fieldsSerializer(),
recordInformation.serializer()
), it
), this
)
}.records
Holder.Success(response)
} catch (e: SerializationException) {
try {
val error = json.decodeFromString(Holder.Failure.ReadError.serializer(), this)
Holder.Failure(error.records.first())
} catch (error: SerializationException) {
throw error
}
}

private sealed class Holder<F : Fields, R : Record<F>> {
class Success<F : Fields, R : Record<F>>(val response: Response<F, R>) : Holder<F, R>()
class Failure<F : Fields, R : Record<F>>(val error: Error) : Holder<F, R>() {
@Serializable
data class ReadError(val records: List<Error>)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ public interface Client {
public suspend fun <F : Fields, R : Record<F>> query(
recordInformation: Information<F, R>,
zoneID: ZoneID = ZoneID.default,
filter: Filter.Builder<F>.() -> Unit = { },
sort: Builder<F>.() -> Unit = { }
sort: Builder<F>.() -> Unit = { },
filter: Filter.Builder<F>.() -> Unit = { }
): List<R>

public suspend fun <F : Fields, R : Record<F>> create(record: R, recordInformation: Information<F, R>): R
public suspend fun <F : Fields, R : Record<F>> read(
recordName: String,
recordInformation: Information<F, R>,
zoneID: ZoneID = ZoneID.default
): R
): R?

public suspend fun <F : Fields, R : Record<F>> update(record: R, recordInformation: Information<F, R>): R
public suspend fun <F : Fields, R : Record<F>> delete(record: R, recordInformation: Information<F, R>)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.softwork.cloudkitclient

import kotlinx.serialization.Serializable

@Serializable
public data class Error(
val recordName: String? = null,
val reason: String? = null,
val serverErrorCode: String? = null,
val retryAfter: Int? = null,
val uuid: String? = null,
val redirectURL: String? = null,
) : Exception()
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package app.softwork.cloudkitclient
import kotlinx.serialization.*

@Serializable
internal data class Response<F: Record.Fields, R: Record<F>>(
public data class Response<F: Record.Fields, R: Record<F>>(
val records: List<R>,
val continuationMarker: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public class Storage(
public fun <F : Record.Fields, R : Record<F>> get(
recordName: String,
recordInformation: Record.Information<F, R>
): R {
return storage[recordName]!! as R
): R? {
return storage[recordName]?.let { it as R }
}

public fun <F : Record.Fields, R : Record<F>> delete(record: R, recordInformation: Information<F, R>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public open class TestDatabase(
public override suspend fun <F: Record.Fields, R : Record<F>> query(
recordInformation: Information<F, R>,
zoneID: ZoneID,
filter: Filter.Builder<F>.() -> Unit,
sort: Sort.Builder<F>.() -> Unit
sort: Sort.Builder<F>.() -> Unit,
filter: Filter.Builder<F>.() -> Unit
): List<R> {
return zones[zoneID]!!.query(recordInformation, Filter.Builder<F>().apply(filter).build(), Sort.Builder<F>().apply(sort).build())
}
Expand All @@ -37,7 +37,7 @@ public open class TestDatabase(
recordName: String,
recordInformation: Information<F, R>,
zoneID: ZoneID
): R = zones[zoneID]!!.get(recordName, recordInformation)
): R? = zones[zoneID]!!.get(recordName, recordInformation)

override suspend fun <F: Record.Fields, R : Record<F>> update(record: R, recordInformation: Information<F, R>): R =
record.zone.update(record, recordInformation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,10 @@ class TodoClientTest {
client.publicDB.delete(todoDeletedAsset, TodoRecord)
}

@Test
fun notFound() = runTest(clients) { client ->
assertNull(client.publicDB.read("TestingNotFound", TodoRecord))
}

private val Client.timeout get() = if (this is TestClient) 0L else 2500L
}

0 comments on commit f1b8867

Please sign in to comment.