Couchbase Lite開発: Kotlin拡張機能


## はじめに

Couchbase Lite Android 3.0.0-beta02では、Kotlinアプリ開発における慣用的なプログラミング作法のサポートが導入されています。

これによって、Kotlin開発者は、一般的なKotlinアプリケーション開発に用いられる実装パターンを用いてアプリを構築できるようになりました。Couchbase Kotlin SDKは、Couchbase Lite for Androidとシームレスに統合されており、Java APIと同等の機能を備えています。

Couchbaseをモバイルアプリケーションで利用する意義については、以下の記事をご参考ください。

https://qiita.com/yoshiyuki_kono/items/3abd5e32801060a449d2

## Kotlin拡張機能

## 概要

Kotlin開発者は、Couchbase Liteを利用したアプリケーション構築のために、Java APIとの完全な互換性に加えて、Kotlin拡張機能を利用できます。

Kotlin拡張機能パッケージには以下のサポートが含まれています。

- `ConfigurationFactory`
  - Kotlinの名前付きパラメーターを活用してデータベースやレプリケーターなどの各種プロパティ設定を行うことができます。
- `Flow`
  - コルーチンや[Flow](https://developer.android.com/kotlin/flow)などのKotlinの機能を使用して、主要なCouchbase Liteオブジェクトの変更を監視することができます。

### ConfigurationFactory
Couchbase Liteは、各種の設定オブジェクトを作成するためのファクトリークラスを提供します。

#### データベース
`DatabaseConfiguration`を作成するための`DatabaseConfigurationFactory`

##### 使用例

```KOTLIN
database = Database(
  "getting-started",
  DatabaseConfigurationFactory.create(context.filesDir.absolutePath)
  )
```

##### 定義例

```kotlin
val DatabaseConfigurationFactory: DatabaseConfiguration? = null

fun DatabaseConfiguration?.create(
    databasePath: String? = null,
    encryptionKey: EncryptionKey? = null
)
```

#### レプリケーション
`ReplicatorConfiguration`を作成するための`ReplicatorConfigurationFactory`

##### 使用例

```KOTLIN
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())
      )
  )
```

##### 定義例

```kotlin
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
)

```

#### 全文検索
`FullTextIndexConfiguration`を作成するための`FullTextIndexConfigurationFactory`。

##### 使用例

```KOTLIN
db.createIndex("fts_index",
      FullTextIndexConfigurationFactory.create(expressions = ["name","location"])
    )
```
##### 定義例

```kotlin
val FullTextIndexConfigurationFactory: FullTextIndexConfiguration? = null

fun FullTextIndexConfiguration?.create(expression: String? = null)

```

#### インデックス作成

`ValueIndexConfiguration`を作成するための`ValueIndexConfigurationFactory`。

##### 使用例

```KOTLIN
db.createIndex("name_and_location_index",
      ValueIndexConfigurationFactory.create(expressions = ["name","location"])
    )
```

##### 定義例

```kotlin
val ValueIndexConfigurationFactory: ValueIndexConfiguration? = null

fun ValueIndexConfiguration?.create(vararg expressions: String = emptyArray())
```

#### ログ
`LogFileConfiguration`を作成するための`LogFileConfigurationFactory`。

##### 使用例

```KOTLIN
Database.log.file.let {
  it.config = LogFileConfigurationFactory.create(
    context.cacheDir.absolutePath, 
    maxSize = 10240, 
    maxRotateCount = 5, 
    usePlainText = false
    ) 
    it.level = LogLevel.INFO 

  }
```

##### 定義例

```kotlin
val LogFileConfigurationFactory: LogFileConfiguration? = null

.LogFileConfiguration.create()

fun LogFileConfiguration?.create(
    directory: String? = null,
    maxSize: Long? = null,
    maxRotateCount: Int? = null,
    usePlainText: Boolean? = null
)
```

### Flow


#### データベース変更
データベース変更イベントを監視します。

##### 使用例

```KOTLIN
val updatedDocs = db.databaseChangeFlow()
    .map { it.documentIDs }
    .asLiveData()
```

##### 定義例

```kotlin
@ExperimentalCoroutinesApi
fun Database.databaseChangeFlow(executor: Executor? = null)

```

#### ドキュメント変更
ドキュメントの変更を監視します。

##### 使用例


```KOTLIN
val docModDate = db.documentChangeFlow("1001", null)
    .map { it.database.getDocument(it.documentID)?.getString("lastModified") }
    .asLiveData()
```

##### 定義例

```kotlin
@ExperimentalCoroutinesApi

fun Database.documentChangeFlow(documentId: String, executor: Executor? = null)

```

#### レプリケーター変更
レプリケータの変化を監視します。

##### 使用例

```KOTLIN
val replState = repl.replicatorChangesFlow()
    .map { it.status.activityLevel }
    .asLiveData()
```

##### 定義例

```kotlin
@ExperimentalCoroutinesApi
fun Replicator.replicatorChangesFlow(executor: Executor? = null)
```

#### ドキュメントレプリケーション
レプリケーション中のドキュメントの変更を監視します。

##### 使用例

```KOTLIN
val replicatedDocs = repl.documentReplicationFlow(testSerialExecutor)
    .map { update -> update.documents }
    .onEach { listView.setUpdated(it) }
    .collect()
```

##### 定義例

```kotlin
@ExperimentalCoroutinesApi
fun Replicator.documentReplicationFlow(executor: Executor? = null)

```

#### クエリ変更フロー
クエリ（の結果）の変更を監視します。

##### 使用例

```KOTLIN
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
}
```


##### 定義例

```kotlin
@ExperimentalCoroutinesApi
fun Query.queryChangeFlow(executor: Executor? = null)
```
## 最後に

Couchbase Liteについての記事を以下の投稿で整理していますので、ご関心に応じて、参照してみてください。

https://qiita.com/yoshiyuki_kono/items/6a5bbad1b02196a25417

Couchbase Liteは、Couchbase Serverとの自動双方向同期が可能です。

Couchbase Serverについては、日本語で読むことができるまとまった情報として、次の拙著を紹介させていただきます。

https://www.amazon.co.jp/-/en/%E6%B2%B3%E9%87%8E-%E6%B3%B0%E5%B9%B8/dp/429560030X/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1636588872&sr=1-1

## 関連情報

拡張APIドキュメントについては、以下のAPI Docを参照してください。

https://docs.couchbase.com/mobile/3.0.0-beta02/couchbase-lite-android-ktx/

本稿の内容の一次情報は下記です。

https://docs.couchbase.com/couchbase-lite/3.0/android/kotlin.html

Kotlin開発の一般的なパターンについては、以下を参照できます。

https://developer.android.com/kotlin/common-patterns