Skip to content

Kotlin Extensions

Couchbase Lite — Kotlin support

Introduction

In addition to implementing the full Couchbase Lite Java SDK API, Kotbase also provides some additional APIs available in the Couchbase Lite Android KTX SDK, which includes a number of Kotlin-specific extensions.

This includes:

Note

The configuration factory APIs from the Couchbase Lite Android KTX SDK have been deprecated in Kotbase in favor of using constructors directly, which support Kotlin named arguments themselves, or properties can be accessed using the apply scope function. These APIs will be removed in a future release.

Additionally, while not available in the Java SDK, as Java doesn't support operator overloading, Kotbase adds support for Fragment subscript APIs, similar to Couchbase Lite Swift, Objective-C, and .NET.

Change Flows

These wrappers use Flows to monitor for changes.

Collection Change Flow

Use the Collection.collectionChangeFlow() to monitor collection change events.

scope.launch {
    collection.collectionChangeFlow()
        .map { it.documentIDs }
        .collect { docIds: List<String> ->
            // handle changes
        }
}
fun Collection.collectionChangeFlow(
    coroutineContext: CoroutineContext? = null
): Flow<CollectionChange>

Document Change Flow

Use Collection.documentChangeFlow() to monitor changes to a document.

scope.launch {
    collection.documentChangeFlow("1001")
        .map { it.collection.getDocument(it.documentID)?.getString("lastModified") }
        .collect { lastModified: String? ->
            // handle document changes
        }
}
fun Collection.documentChangeFlow(
    documentId: String, 
    coroutineContext: CoroutineContext? = null
): Flow<DocumentChange>

Replicator Change Flow

Use Replicator.replicatorChangeFlow() to monitor replicator changes.

scope.launch {
    repl.replicatorChangesFlow()
        .map { it.status.activityLevel }
        .collect { activityLevel: ReplicatorActivityLevel ->
            // handle replicator changes
        }
}
fun Replicator.replicatorChangesFlow(
    coroutineContext: CoroutineContext? = null
): Flow<ReplicatorChange>

Document Replicator Change Flow

Use Replicator.documentReplicationFlow() to monitor document changes during replication.

scope.launch {
    repl.documentReplicationFlow()
        .map { it.documents }
        .collect { docs: List<ReplicatedDocument> ->
            // handle replicated documents
        }
}
fun Replicator.documentReplicationFlow(
    coroutineContext: CoroutineContext? = null
): Flow<DocumentReplication>

Query Change Flow

Use Query.queryChangeFlow() to monitor changes to a query.

scope.launch {
    query.queryChangeFlow()
        .mapNotNull { change ->
            val err = change.error
            if (err != null) {
                throw err
            }
            change.results?.allResults()
        }
        .collect { results: List<Result> ->
            // handle query results
        }
}
fun Query.queryChangeFlow(
    coroutineContext: CoroutineContext? = null
): Flow<QueryChange>

Fragment Subscripts

Kotbase uses Kotlin's indexed access operator to implement Couchbase Lite's Fragment subscript APIs for Database, Collection, Document, Array, Dictionary, and Result, for concise, type-safe, and null-safe access to arbitrary values in a nested JSON object. MutableDocument, MutableArray, and MutableDictionary also support the MutableFragment APIs for mutating values.

Supported types can get Fragment or MutableFragment objects by either index or key. Fragment objects represent an arbitrary entry in a key path, themselves supporting subscript access to nested values.

Finally, the typed optional value at the end of a key path can be accessed or set with the Fragment properties, e.g. array, dictionary, string, int, date, etc.

Subscript API examples

val db = Database("db")
val coll = db.defaultCollection
val doc = coll["doc-id"]       // DocumentFragment
doc.exists                     // true or false
doc.document                   // "doc-id" Document from Database
doc["array"].array             // Array value from "array" key
doc["array"][0].string         // String value from first Array item
doc["dict"].dictionary         // Dictionary value from "dict" key
doc["dict"]["num"].int         // Int value from Dictionary "num" key
coll["milk"]["exp"].date       // Instant value from "exp" key from "milk" Document
val newDoc = MutableDocument("new-id")
newDoc["name"].value = "Sally" // set "name" value