PackedTable<&T::id> は高レベル API の中心になる型付きテーブル API です。C++ aggregate を primary key ごとに 1 つのエンコード済み値として保存し、row-id mapping や secondary index などのテーブル metadata も管理します。
テーブルを定義する
Section titled “テーブルを定義する”struct User { uint64_t id; std::string name; uint32_t age;};
AKKARADB_ENTITY(User, id, name, age);
auto users = db->table<&User::id>("users");AKKARADB_ENTITY は RefTraits<User> と query field の両方を登録します。query だけが必要で Ref<T> 対応が不要な型では AKKARADB_QUERYABLE を使います。
主要メソッド
Section titled “主要メソッド”| メソッド | 挙動 |
|---|---|
put(entity) | エンティティの主キーで挿入または置換します。 |
get(pk) | std::optional<Entity> を返します。 |
getInto(pk, out) | 呼び出し側が持つ格納先へ復号します。 |
exists(pk) | 現在行の存在を確認します。 |
remove(pk) | 行、row-id metadata、index entries を削除します。 |
upsert(pk, fn) | 読み込み、または default construct した上で primary key を設定し、callback 後に書き込みます。 |
updatePrimaryKey(oldPk, entity) | 行 ID を保ったまま新しい主キーへ移動します。 |
count() | table namespace 内の行数を数えます。 |
scanAll() は table namespace 全体を scan します。scan(startPk, endPk) は half-open な primary-key range を scan します。
auto rows = users.scan(100ULL, 200ULL);while (rows.hasNext()) { auto entry = rows.next();}返る Entry には id と value が含まれます。
インデックス
Section titled “インデックス”インデックスは、そのインデックスで見つけたい行を書き込む前に登録します。
auto byEmail = users.index<&User::email>();indexed<&Field>() は通常のフィールドインデックスを連結して登録するヘルパーです。prefixIndexed<&Field>() は startsWith() と単純な接頭辞 like() のクエリ計画に使う、別の文字列接頭辞インデックスを登録します。
主キーの更新
Section titled “主キーの更新”put() は同じ primary key の値を置き換える API です。identity 自体を移動する場合は updatePrimaryKey() を使います。
users.updatePrimaryKey(1, User{10, "Alice Cooper", 31});移動先 primary key は存在してはいけません。安定した row id は保たれるため、Ref<T> は引き続き解決できます。
数値 primary key は順序を保つ byte order でエンコードされるため、range scan は自然な数値順になります。
インデックスの管理
Section titled “インデックスの管理”prefix index は string-like field 専用で、findBy<&Field>() には使われません。findBy<&Field>(value) は最初に見つかったエンティティを返し、通常の field index が未登録なら例外を投げます。
index entries は insert、replacement、remove、primary-key update で更新されます。既存行には自動 backfill されません。
onUpdate<&Field>() は既存行が置き換えられ、そのフィールドが変化したときに実行されます。
users.onUpdate<&User::age>( [](const auto& oldAge, const auto& newAge, const User& oldUser, User& nextUser) { nextUser.name = oldUser.name; });フックは置換後のエンティティがエンコードされる前に動きます。テーブルの書き込み経路で実行されるため、決定的で局所的な処理に留めるのが安全です。
変更不可フィールド
Section titled “変更不可フィールド”Immutable<T> は、読み込み後または保存後に変更したくないフィールドを守ります。
struct Account { uint64_t id; akkaradb::Immutable<std::string> handle;};sealed immutable field を replacement 時に変更しようとすると例外を投げます。primary-key field には Immutable<T> を使えません。