Dexie

javascript 用の InexedDB のラッパーライプラリ

導入

yarn add dexie

Hello World

基本的にCURDの操作は非同期(Promise)で行う。

import Dexie from "dexie";

// データベース作成
const db = new Dexie("app_database");

// テーブル作成
db.version(1).stores({
  // ここにはPKとインデックスカラムの定義を書く。
  // ※すべての列名を書かなくても良いけど、`where()`で指定したい列はここに書く。
  // ++: オートインクリメントのPK
  // & : ユニーク列
  // ->: 外部キー ex) userId -> users.id
  users: "++id,name,age"
});

const table = db.users

// テーブル内容全取得:戻り値はPromise
const fildAll = (id: string) =>
  table
    .where('trackId')
    .equals(trackId)
    .toArray()

// 条件を指定して取得:戻り値はPromise
const fildByName = (name: string) =>
  table
    .where('name')
    .equals(name)
    .toArray()

// 主キーを指定して1件取得:戻り値はPromise
table.get(1)

// 1件追加
// ※PKをオートインクリメント(++)にしている場合、PKは省略可
table.add({name: "hoge", age: 10})
// 追加(キーを第2引数で指定)
table.add({name: "hoge", age: 10}, 1)

// 1件追加・更新(なければ追加、あれば更新)
const count = table.put({ name: "Nicolas", shoeSize: 8 });
console.log(count); // -> "1"


//
// 同じ主キーを持つオブジェクトが既にある場合は失敗
// 成功の場合は挿入されたオブジェクトのIDが返る
//

// 更新
await table.update(1, { name: "hoge" });
// これも同じ
await db.where(":id").equals(1).modify({ name: "hoge"})

// 全削除
table.clear()

TypeScript

Dexieのサブクラスを作ると型補完が効くようになる。

myAppDatabase.ts

import Dexie from "dexie";

export class MyAppDatabase extends Dexie {
  users: Dexie.Table<IUser, number>;
  foods: Dexie.Table<IFood, number>;

  constructor() {
    super("MyAppDatabase");

    this.version(1).stores({
      // -> で外部キー
      users: "++id, name, age, foodId -> foods.id",
      foods: "++id, name"

    });
    this.users = this.table("users");
  }
}

export interface IUser {
  id?: number; // Primary key. Optional (autoincremented)
  name: string;
  age: number;
  foodId: number;
}

export interface IFood {
  id?: number;
  name: string;
}

Ref: Dexie.js - how to join tables?

main.ts

import { MyAppDatabase } from './myAppDatabase';

const db = new MyAppDatabase()
await db.users.put({ name: "aNicolas", age: 6 });

DBの変更監視

  • Table.hook
  • Database.on

https://dexie.org/docs/Table/Table.hook('creating')

Table.hook()の例

db.users.hook('creating', (key, obj, transaction) => {
  // key: エンティティのキー
  // obj: 追加されたエンティティ
  // transaction: イベント時に追加の処理をする場合に使えるトランザクション
  console.log('created', key, obj, transaction)
})

db.users.hook('updating', (mod, key, obj, transaction) => {
  // mod: 更新されるプロパティと更新後の値がkey:valueになっているオブジェクト。プロパティ削除の場合はundefined。
  // key: エンティティのキー
  // obj: 更新対象エンティティ(更新前の状態の値)
  // transaction: イベント時に追加の処理をする場合に使えるトランザクション
  console.log('updated', key, obj, transaction)
})

db.users.hook('deleting', function(key, obj, transaction) {
  // key: エンティティのキー
  // obj: 削除されるエンティティ
  // transaction: イベント時に追加の処理をする場合に使えるトランザクション
  console.log('deleted', key, obj, transaction)
})