今回の更新でsqliteのtableにカラム追加したので、その辺の話
対象のpull request
pull request見れば分かりますが、特に良い実装とかは無く愚直に実行しました。
対応内容
今回はのMigrationでは以下の通りに動作するように対応
- 既にアプリをインストール済みのユーザー→カラム追加のクエリを実行
- 新規でアプリをインストールしたユーザー→カラム追加済みのテーブルを作る
まず、Migration用のメソッド作成
import { SQLite } from "expo-sqlite"; import { success, error } from "./"; export const migrationV1040 = async ( tx: SQLite.Transaction, callback?: (error: any) => void ) => { const query = `alter table item_details add column place string;`; return tx.executeSql( query, [], (_: any, props: any) => success(props, callback), (_: any, err: any) => { error(err, callback); } ); }; export const migrationV1041 = async ( tx: SQLite.Transaction, callback?: (error: any) => void ) => { const query = `alter table item_details add column url string;`; return tx.executeSql( query, [], (_: any, props: any) => success(props, callback), (_: any, err: any) => { error(err, callback); } ); };
sqliteは、add columnを1クエリで複数投げられないので追加分実行
あとは起動時にアプリのバージョンと現在のDBのバージョンを比較して↑のメソッドを実行すればOK
まずは、新新規でアプリをインストールしたユーザーのバージョンを設定する。
import app from "../app.json"; 略) if (!data) { const uuid = Constants.installationId + uuidv1(); const user: User = { uuid }; db.transaction((tx: SQLite.Transaction) => { insertUser(tx, user, this.setUser); } ); AsyncStorage.setItem("userID", user.uuid); // 現在のバージョンを設定 AsyncStorage.setItem("APP_VERSION", app.expo.version); }
初期ユーザー作成の際に現在のexpoに設定いしているアプリバージョンを保存する
既にアプリをインストール済みのユーザーへの対応とした以下を実装
async componentDidMount() { let appVerion = await AsyncStorage.getItem("APP_VERSION"); if (!appVerion) { appVerion = "1.0.0"; } if (compareVersions.compare("1.0.4", appVerion, ">")) { // カラム追加のマイグレーション実行 const ok = await migrationV104(); if (ok) { // 現在のバージョンを設定 AsyncStorage.setItem("APP_VERSION", "1.0.4"); } } this.setState({ loading: false }); }
ちなみにバージョンの比較は↓のパッケージを使用しています github.com
ってことで自前で実装しました。 意外と実装が辛かったので、あとでパッケージ作ってもよいかもと思った。