Kotlin

    +

    Description — Couchbase Lite for Android — Kotlin support
    Related Content — Databases | Documents | Indexing |

    Introduction

    Couchbase Lite Android 3.0.0 introduces full idiomatic support for Kotlin apps, out-of-the-box.

    Kotlin developers can now build apps using common Kotlin Patterns, that integrate seamlessly with Couchbase Lite for Android and have full feature parity with the Java API; including some convenient Kotlin Extensions to get you started.

    Key features include:

    • Nullability annotations

    • Named parameters

    • Kotlin Flows, for asynchronous event notifications

    Java support and functionality continues for Android.

    Kotlin Extensions

    In addition to having full co-compatible access to the existing Java API, Kotlin developers can also access a number of Kotlin Extensions.

    The Kotlin Extensions package includes:

    • Configuration Factories for the configuration of important Couchbase Lite objects such as Databases, Replicators and Listeners.

    • Change Flows that monitor key Couchbase Lite objects fpr change using Kotlin features such as, Co-routines and Flows.

    See: Kotlin Extensions for extension API docs

    Configuration Factories

    Couchbase Lite provides a set of ConfigurationFactories and CommonConfigurationFactories, these allow use of named parameters to specify property settings.

    Database

    Use DatabaseConfigurationFactory to create a DatabaseConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    database = Database(
      "getting-started",
      DatabaseConfigurationFactory.create(context.filesDir.absolutePath)
      )
    val DatabaseConfigurationFactory: DatabaseConfiguration? = null
    
    fun DatabaseConfiguration?.create(
        databasePath: String? = null,
        encryptionKey: EncryptionKey? = null
    )

    Replication

    Use ReplicatorConfigurationFactory to create a ReplicatorConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    val replicator =
      Replicator(
        ReplicatorConfigurationFactory.create(
          database = database,
          target = URLEndpoint(URI("ws://localhost:4984/getting-started-db")),
          type = ReplicatorType.PUSH_AND_PULL,
          authenticator = BasicAuthenticator("sync-gateway", "password".toCharArray())
          )
      )
    val ReplicatorConfigurationFactory: ReplicatorConfiguration? = null
    
    fun ReplicatorConfiguration?.create(
        database: Database? = null,
        target: Endpoint? = null,
        type: ReplicatorType? = null,
        continuous: Boolean? = null,
        authenticator: Authenticator? = null,
        headers: Map<String, String>? = null,
        pinnedServerCertificate: ByteArray? = null,
        channels: List<String>? = null,
        documentIDs: List<String>? = null,
        pushFilter: ReplicationFilter? = null,
        pullFilter: ReplicationFilter? = null,
        conflictResolver: ConflictResolver? = null,
        maxAttempts: Int? = null,
        maxAttemptWaitTime: Int? = null,
        heartbeat: Int? = null,
        enableAutoPurge: Boolean? = null,
        acceptOnlySelfSignedServerCertificate: Boolean? = null
    )
    
    val MessageEndpointListenerConfigurationFactory: MessageEndpointListenerConfiguration? = null
    
    fun MessageEndpointListenerConfiguration?.create(
        database: Database? = null,
        protocolType: ProtocolType? = null
    )

    Use FullTextIndexConfigurationFactory to create a FullTextIndexConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    db.createIndex("fts_index",
          FullTextIndexConfigurationFactory.create(expressions = ["name","location"])
        )
    val FullTextIndexConfigurationFactory: FullTextIndexConfiguration? = null
    
    fun FullTextIndexConfiguration?.create(expression: String? = null)

    Indexing

    Use ValueIndexConfigurationFactory to create a ValueIndexConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    db.createIndex("name_and_location_index",
          ValueIndexConfigurationFactory.create(expressions = ["name","location"])
        )
    val ValueIndexConfigurationFactory: ValueIndexConfiguration? = null
    
    fun ValueIndexConfiguration?.create(vararg expressions: String = emptyArray())

    Logs

    Use LogFileConfigurationFactory to create a LogFileConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    Database.log.file.let {
      it.config = LogFileConfigurationFactory.create(
        context.cacheDir.absolutePath, (1)
        maxSize = 10240, (2)
        maxRotateCount = 5, (3)
        usePlainText = false
        ) (4)
        it.level = LogLevel.INFO (5)
    
      }
    val LogFileConfigurationFactory: LogFileConfiguration? = null
    
    .LogFileConfiguration.create()
    
    fun LogFileConfiguration?.create(
        directory: String? = null,
        maxSize: Long? = null,
        maxRotateCount: Int? = null,
        usePlainText: Boolean? = null
    )

    Flows

    These wrappers use Flowables to monitor for changes.

    Database Change Flow

    Use the databaseChangeFlow(Database,Executor) to monitor database change events.

    • In Use

    • Definition

    val updatedDocs = db.databaseChangeFlow()
        .map { it.documentIDs }
        .asLiveData()
    @ExperimentalCoroutinesApi
    fun Database.databaseChangeFlow(executor: Executor? = null)

    Document Change Flow

    Use documentChangeFlow(Database,String,Executor) to monitor changes to a document.

    • In Use

    • Definition

    val docModDate = db.documentChangeFlow("1001", null)
        .map { it.database.getDocument(it.documentID)?.getString("lastModified") }
        .asLiveData()
    @ExperimentalCoroutinesApi
    
    fun Database.documentChangeFlow(documentId: String, executor: Executor? = null)

    Replicator Change Flow

    Use replicatorChangeFlow(Replicator,Executor) to monitor replicator changes.

    • In Use

    • Definition

    val replState = repl.replicatorChangesFlow()
        .map { it.status.activityLevel }
        .asLiveData()
    @ExperimentalCoroutinesApi
    fun Replicator.replicatorChangesFlow(executor: Executor? = null)

    Document Replicator Change Flow

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

    • In Use

    • Definition

    val replicatedDocs = repl.documentReplicationFlow(testSerialExecutor)
        .map { update -> update.documents }
        .onEach { listView.setUpdated(it) }
        .collect()
    @ExperimentalCoroutinesApi
    fun Replicator.documentReplicationFlow(executor: Executor? = null)

    Query Change Flow

    Use queryChangeFlow(Query,Executor) to monitor document changes during replication.

    • In Use

    • Definition

    var liveQuery: LiveData<List<Any>?>? = null
    
    @ExperimentalCoroutinesApi
    fun watchQuery(query: Query): LiveData<List<Any>?> {
        val queryFlow = query.queryChangeFlow()
            .map {
                val err = it.error
                if (err != null) {
                    throw err
                }
                it.results?.allResults()?.flatMap { it.toList() }
            }
            .asLiveData()
        liveQuery = queryFlow
        return queryFlow
    }
    @ExperimentalCoroutinesApi
    fun Query.queryChangeFlow(executor: Executor? = null)