コンテンツにスキップ

PackedTable

PackedTable<&T::id> は高レベル API の中心になる型付きテーブル API です。C++ aggregate を primary key ごとに 1 つのエンコード済み値として保存し、row-id mapping や secondary index などのテーブル metadata も管理します。

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_ENTITYRefTraits<User> と query field の両方を登録します。query だけが必要で Ref<T> 対応が不要な型では AKKARADB_QUERYABLE を使います。

メソッド挙動
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 には idvalue が含まれます。

インデックスは、そのインデックスで見つけたい行を書き込む前に登録します。

auto byEmail = users.index<&User::email>();
auto alice = byEmail.find("alice@example.test");

indexed<&Field>() は通常のフィールドインデックスを連結して登録するヘルパーです。prefixIndexed<&Field>()startsWith() と単純な接頭辞 like() のクエリ計画に使う、別の文字列接頭辞インデックスを登録します。

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 は自然な数値順になります。

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;
}
);

フックは置換後のエンティティがエンコードされる前に動きます。テーブルの書き込み経路で実行されるため、決定的で局所的な処理に留めるのが安全です。

Immutable<T> は、読み込み後または保存後に変更したくないフィールドを守ります。

struct Account {
uint64_t id;
akkaradb::Immutable<std::string> handle;
};

sealed immutable field を replacement 時に変更しようとすると例外を投げます。primary-key field には Immutable<T> を使えません。