🐕
SQLDelight で upsert する
SQLDelight は データベース操作を楽にしてくれるライブラリです。
CashApp ( Square 社 ) が開発しており、KMM を利用したプロジェクトでも導入できるのが利点だと思います。
今年 ( 2022年 ) の DroidKaigi でも採用されていました。
Upsert がしたい
Room では Upsert の機能が提供されています。
同様の動作を SQLDelight で実現したいです。
先に結論
こんな感じで記載するとうまく動作します。
HogeTable.sq
upsert {
UPDATE hogeTable
SET param1 = :param1,
param2 = :param2,
param3 = :param3
WHERE id = :id;
INSERT OR IGNORE INTO hogeTable (
id,
param1,
param2,
param3
) VALUES (
:id,
:param1,
:param2,
:param3
);
}
Grouping Statements を利用する
公式のドキュメントでしっかりとユースケースとして記載されていました。
Grouping Statements
という機能を利用すれば実現できそうです。
INSERT 文で 疑問符 ( qmark スタイル) を使用していた場合は注意が必要
もともとこんな感じの INSERT
文を利用していたので、これを流用しようとしました。
HogeTable.sq
insert:
INSERT OR IGNORE INTO hogeTable (
id,
param1,
param2,
param3
) VALUES ?;
流用して記載したものがこちら。
INSERT
文で qmark スタイルを利用しています。
HogeTable.sq
upsert {
UPDATE hogeTable
SET param1 = :param1,
param2 = :param2,
param3 = :param3
WHERE id = :id;
INSERT OR IGNORE INTO hogeTable (
id,
param1,
param2,
param3
) VALUES ?;
}
すると、こんなエラーが…。
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':core:database:generateCommonMainDatabaseInterface'.
> A failure occurred while executing com.squareup.sqldelight.gradle.SqlDelightTask$GenerateInterfaces
> Failed to compile SqlDelightStmtClojureStmtListImpl(STMT_CLOJURE_STMT_LIST): [] :
UPDATE hogeTable
SET param1 = :param1,
param2 = :param2,
param3 = :param3
WHERE id = :id;
INSERT OR IGNORE INTO hogeTable (
id,
param1,
param2,
param3
) VALUES ?;
ぬぬ、よくわからん…。
おかしいところはなさそうだったのですが、公式が named スタイルで記載してあるなと思い、書き直してみました。
HogeTable.sq
upsert {
UPDATE hogeTable
SET param1 = :param1,
param2 = :param2,
param3 = :param3
WHERE id = :id;
INSERT OR IGNORE INTO hogeTable (
id,
param1,
param2,
param3
) VALUES (
:id,
:param1,
:param2,
:param3
);
}
これでビルドが通り、無事 Kotlin ファイルが生成されていることを確認できました 🎉
Discussion