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)