@ObsoleteCoroutinesApi とは「様子見」?

Coroutine で Channel 辺りをウロウロと。

あれ?

This declaration is experimental and its usage should be marked with '@kotlinx.coroutines.ObsoleteCoroutinesApi' or '@UseExperimental(kotlinx.coroutines.ObsoleteCoroutinesApi::class)'

調べてみる。

From the point of usage `ObsoleteCoroutinesApi` is just like experimental. The different is in intent. When API is experimental it might change or might graduate as is. For obsolete API we already know that there are problems with designs that will force us to deprecated this API in the future when we have a better replacement.

Right now there is no replacement for channel operations, so you have no choice but continue using them. However, we plan to replace them with mechanism based on lazy/cold streams (#254) in the future, which will get you much better performance.

What is the recommended approach for @ObsoleteCoroutinesApi #632

Google翻訳で。

使用の観点からObsoleteCoroutinesApiは実験的なようです。 違いは意図しています。 APIが実験的なものである場合、それは変更されるか、またはそのまま卒業するかもしれません。 時代遅れのAPIについては、より良い代替品があるときに将来的にこのAPIを非推奨にするような設計上の問題があることはすでにわかっています。

今のところチャンネル操作に代わるものはないので、あなたには選択肢がないがそれらを使い続けることができる。 ただし、将来的にはレイジー/コールドストリーム(#254)に基づくメカニズムに置き換える予定です。これにより、パフォーマンスが大幅に向上します。

まとめ


@ExperimentalCoroutinesApi

→ 将来的には、変更される or そのまま。


@ObsoleteCoroutinesApi

→ 設計上の問題がある。

→ 今現在、代替えはない。

→ 将来的には非推奨。

アンダースコアがついてるのはそゆこと?


_events.consumeEach {

チャンネル周りは、今は「様子見」がいいのでしょうね。


SQLDelight の データベースバージョン

「分かれば簡単だけど、分かるまで難しい」

そんなこと多いですよね。

なにを悩んでいたのか。というやつ。

SQLDelight は、1.0 となり、今現在、ドキュメントやリファレンスが少なくてはまります。

おおまかに「しくみ」を捉えてからやってみること大事です。

 

1.テーブル作成

テーブルを作成したい場合。SQLで、


CREATE TABLE player (
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  number INTEGER NOT NULL,
  name TEXT NOT NULL,
  time TEXT DEFAULT (strftime('%s', 'now')),
  UNIQUE (number, name)
);

のようなものを書きますよね。

これは、Player.sq というファイルに書いて、所定の位置に置きます。

この位置はデフォルトでは、パッケージ名 com.example.testdelight の場合、


/app/src/main/sqldelight/com/example/testdelight/Player.sq

となります。

 

2.クエリー作成

プログラムコード上で利用したい「メソッド名」と、それに対するSQLを箇条書きにします。


selectAll:
SELECT *
FROM player;

insert:
INSERT INTO player(number, name)
VALUES (?, ?);

changes:
SELECT changes();

count:
SELECT COUNT(id)
FROM player;

これも、前述の Player.sq ファイルに追記します。

これで、テーブル周りの設定は終わりです。

 

3.スキーマのバージョン

ここが少し分かりづらかったのですが、

「201901281」を新バージョンにしたい場合、

「1を引いたもの」をファイル名として、

「201901280.sqm」

として置きます。

今回は、テーブル定義の変更はないので、中身なしの空ファイルです。

少し不思議な感じがしますが、書き出してみると分かってきます。

なお、このファイルを設定しなければ、適用されるバージョンは「1」となります。

 

4.ビルドして書き出す

ここでビルドすると、以下のようなファイルが書き出されます。

それぞれ以下のコードとなっています。

これらを使って、コードを書いていきます。

 

まとめ

既存の .db ファイルに対して、バージョン更新を行いたい場合のキモとなるのは、書き出される Database ファイル。


object Schema : SqlDriver.Schema {

     override val version: Int
         get() = 201901281 // 201801280 + 1

     // ...

     override fun migrate(
         driver: SqlDriver,
         oldVersion: Int,
         newVersion: Int
     ) {
         if (oldVersion <= 201901280 && newVersion > 201901280) { // same .sqm file name

           // from 201801280.sqm contents
           // ...

         }
     }
 }

.sqm のファイル名の数字が、

「新バージョンの数字」
「適用される既存.db のバージョンの数字」

を決める。

SQLDelight 1.0 使い方 #1
SQLDelight 1.0 使い方 #2
SQLiteのユーザバージョンを利用する - Basic
Pragma statements supported by SQLite




あみだくじを罫線で書く

実際に罫線で書いてみる。


┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃
┃┣┫┃┃┃┃┃┣┫┣┫┃┃┃┃┃┣┫┃
┣┫┣┫┃┃┃┃┣┫┣┫┣┫┃┣┫┃┣┫
┃┃┃┃┃┃┃┃┣┫┃┃┃┃┃┃┃┃┣┫
┣┫┣┫┣┫┣┫┣┫┣┫┣┫┣┫┣┫┣┫
┃┃┃┣┫┃┃┃┃┃┣┫┃┣┫┃┃┣┫┃
┃┃┃┃┣┫┃┃┃┣┫┃┃┃┃┃┣┫┃┃
┃┣┫┃┃┃┣┫┃┃┃┃┃┣┫┃┃┣┫┃
┣┫┣┫┃┃┣┫┃┃┃┣┫┣┫┃┃┃┃┃
┣┫┃┃┃┃┃┣┫┃┃┃┃┃┃┃┃┣┫┃

書いてみて分かるのは、

「┣┫」と「┃」

の二種類の文字列の組み合わせだけで構成されているということ。

Kotlinで。


val n = 20
val l = 10

repeat(l) {
  val ch = (0..n/2).shuffled().first()
  val ci = n - (ch * 2)
  val h = List(ch) { "┣┫" }
  val i = List(ci) { "┃" }
  val a = h.plus(i).shuffled()
  println(a.joinToString(""))
}

一つの「きまりごと」を発見するとコードは劇的に短くなる。

分岐がないコードはスッキリする。

Kotlin で FizzBuzz