Kahua Release
- Release Note
- Download
- Current Version 1.0.7.3 (2008-05-08)
kahua-web Release
- kahua-webとは
- Release Note
- Download
- Current Version 0.3.1 (2007-06-12)
Security Advisory
Event Log
Documentation
For developers
Site info
Related Site
[module] kahua.persistence
このモジュールは、永続オブジェクトと、それを保存するオブジェクトデータ ベースを実現するクラスを提供します。
Persistent Object
[class] <kahua-persistent-meta>
永続オブジェクトを実現するためのメタクラスです。 このメタクラスを使って作成されたクラスのインスタンスが永続オブジェクトと なります。なお、下に述べる<kahua-persistent-base>を継承すれば 自動的にそのクラスのメタクラスに<kahua-persistent-meta>は含まれるので、 このメタクラスを明示的に使用する必要はありません。
このメタクラスを使って作成されたクラスでは、:allocationスロットオプションに :persistentという値を与えることが出来るようになります。 :persistentなallocationを持つスロットが永続化の際、保存の対象となります。
今のところ、永続化されるのは以下のオブジェクトです。
- boolean, number, string, symbol, keyword
- 永続化可能オブジェクトを要素に持つlist, vector
- 他の永続オブジェクトへの参照
また、この永続スロットには、:indexスロットオプションを与えることができ ます。:indexスロットオプションを与えたスロットは、後述の問い合わせ手続 きで、オブジェクトを特定するために使用することができます。与えられるオ プションは次の2種類です。
- :unique - 同一クラス内に、同じスロット値を持つオブジェクトは存在できません
- :any - 同一クラス内で、同じスロット値を持つオブジェクトが存在できます
インデックス値として使えるのは、
- boolean, number, string, symbol, keyword
- インデックス可能オブジェクトを要素に持つlist, vector
他の永続オブジェクトへの参照がインデックス値として使用できないのは、 現在の実装上の制限です。将来この制限は撤廃される予定です。
また、永続クラスには :source-id キーワードでソースIDを与えることが できます。これは永続クラスの世代管理に使われます。 詳しくはPersistenceGenerationを参照して下さい。
[class] <kahua-persistent-base>
永続オブジェクトを作成するクラスのベースクラスです。永続オブジェクトを 実現したいクラスはこのクラスを継承する必要があります。このクラスを継承 することで、メタクラスに<kahua-persistent-meta>が追加されます。
[method] key-of (obj <kahua-persistent-base>)
データベースのキーに使う文字列を返します。デフォルトメソッドではidが使 われます。クラスによっては、このメソッドを特化することでキーをカスタマ イズできます。但し、メソッドを特化するクラスはキーがユニークになること を保証しなければなりません。
注意: このメソッドは基本的にObsoleteです。歴史的理由から存 続しているに過ぎません。このメソッドを特化してキーをカスタマイズするよ り、インデックススロットを使用することを推奨します。key-ofの制約につい ては、PersistenceGenerationを参照して下さい。
[method] touch-kahua-instance! (obj <kahua-persistent-base>)
通常、永続オブジェクトは、プログラム中でslot-set!等により変更を受けた際 にマークされ、トランザクション終了時に変更がデータベースに書き戻されま す。
この手続きは、永続オブジェクトobjの内容を変えずにただマークだけを付 けて、変更がデータベースに書き戻されるようにします。
永続クラスの世代が上がった時に、永続インスタンスの世代もまとめて合わせ たい時などに使えます。
[method] remove-kahua-instance (obj <kahua-persistent-base>)
永続オブジェクトの削除済みフラグを立てます。これにより、不要になったオ ブジェクトを擬似的に削除することができます。削除したオブジェクトを他の 永続オブジェクトのスロットで参照していた場合、削除後にそのスロット値を 得ようとすると#fが返されます。
[procedure] kahua-serializable-object? obj
Schemeオブジェクトobjがシリアライズ可能か、すなわち永続オブジェクト のスロット値としてストア可能かどうかを返す述語です。
シリアライズ可能でないオブジェクトを永続オブジェクトにストアしようとす るとエラーとなります。そのエラーを未然に回避するのに使えます。
[procedure] kahua-indexable-object? obj
Schemeオブジェクトobjがインデックス値として使用可能かどうかを返す述 語です。
[class] <kahua-persistent-metainfo>
永続クラス、つまり<kahua-persistent-meta>メタクラスのインスタンスに関す る情報を管理するためのクラスです。このクラス自身、 <kahua-persistent-base>を継承しており、永続クラスになっています。各永続 クラスに対し、<kahua-persistent-metainfo>のインスタンスが作成され、クラ スの世代や世代間の変換規則等が保持されます。
永続データベースに関するメタ情報を扱うアプリケーションでない限り、通常 はこのクラスにアクセスする必要は無いでしょう。
Querying Persistent Objects
[procedure] find-kahua-class name
シンボルnameを名前に持つ永続クラスを返します。そのようなクラスが無 ければエラーとなります。
[method] kahua-persistent-id obj
永続オブジェクトのオブジェクトIDを整数として取得します。
[method] removed? obj
永続オブジェクトの削除済みフラグが立てられているかどうかを返す述語です。
[method] kahua-instance class id [maybe-include-removed-object?]
この手続きはデータベースがアクティブである時にしか呼べません。
classのインスタンスでオブジェクトIDがidである永続インスタンスを探し、 必要なら実体化して返します。該当するインスタンスが存在しない場合は #f を返します。maybe-include-removed-object? は省略可能引数で、#tを渡すと、 remove-kahua-instanceで削除されたオブジェクトも取得することができます。
[method] find-kahua-instance class key [maybe-include-removed-object?]
[method] find-kahua-instance class slot-name slot-value [maybe-include-removed-object?]
この手続きはデータベースがアクティブである時にしか呼べません。
最初の形式で呼び出すと、classのインスタンスでキー(文字列)とし てkeyを持つ永続インスタンスを探して返します。2番目の形式で呼び出す と、スロットslot-nameの値がslot-valueであるインスタンス をclassから探して返します。いずれの場合も、該当するインスタンスが無 い場合は#fを返します。maybe-include-removed-object? は省略可能引数で、 #tを渡すとremove-kahua-instanceで削除されたオブジェクトも取得することが できます。
[class] <kahua-collection>
永続オブジェクトの集合を扱うクラスです。<collection>を継承しているので、 gauche.collectionをuseしておけばmapやfoldが使えます。
[method] make-kahua-collection ((class <kahua-persistent-meta>) .opts)
この手続きはデータベースがアクティブである時にしか呼べません。
永続クラスclassの全てのインスタンスを<kahua-collection>に入れて返します。 optsはキーワード引数で、インスタンス抽出の条件を指定することができます。
- :index (slot-name . slot-value) - スロットslot-nameに値slot-valueを持つ インスタンスのみを抽出する。
- :keys (key0 ...) - キー値が key0 ... のいずれかであるインスタンスのみを抽出する。
- :predicate pred - (pred obj)が真値を返すインスタンスのみを抽出する。
- :include-removed-object? #t - 削除済みフラグの立っているインスタンスも含めて抽出する。
Object Database
[class] <kahua-db>
永続オブジェクトを格納するデータベースクラスは、このクラスを継承します。
[macro] with-db (db path) body ...
pathにあるデータベースをオープンし、データベースオブジェクト (<kahua-db>インスタンス)を変数dbに束縛した状態で、body ... を評 価します。body...が正常終了すれば、dbに加えられた変化をコミット し、dbをクローズします。bodyがエラーを投げた場合は変化をアボー トし、dbをクローズします。
bodyを実行中のダイナミックエクステントを指して、「データベースがア クティブである」と言います。Kahuaアプリケーションは、デフォルトデータベー スがアクティブな状態で実行されます。従って、ほとんどの場合、Kahuaアプリ ケーション内でこのマクロを明示的に呼ぶ必要はありません。Kahua ア プリケーションが使用するデフォルトデータベースは、kahua.confの default-database-nameや、app-serversの:default-database-nameオプション で指定することができます。
バックエンドのデータベースは、pathの構文により指定できます。デフォ ルトでは、ファイルシステムを使ったデータベースシステムが使われます。 kahua.conf (kahua.config参照)で指定されるdatabase-directory以下 にpathという名のディレクトリが作られ、その中に永続データが格納され ます。
path が "mysql:" または "postgresql:" で始まっている場合は、それぞ れMySQL, PostgreSQLをバックエンドにしたデータベースとなります。この 時、path は以下のような構文を満たさなければなりません。
mysql:user:password:options postgresql:user:password:options
user はDBのユーザ名、passwordはパスワード、そしてoptionsは DB接続時に与えるオプションです。password, options は無ければ省 略可能です。
kahua.persistenceは、外部データベースを使う際にはdbiモジュールと、指定 したデータベース接続に使用するDBDモジュールを自動的にloadします。システ ムにはあらかじめ必要なDBDモジュールがインストールされていなければなりま せん。デフォルトのファイルシステムデータベースを使う場合にはDBDは不要で す。
[procedure] kahua-db-sync db
データベースdbにこれまで加えられた変更をコミットします。コミットし た情報は、この後でエラーが発生してもロールバックされません。dbが省略さ れると、現在アクティブなデータベースが使われます。
通常、Kahuaアプリケーション内でこの手続きを明示的に呼ぶ必要はありません。
Metainformation
どのような永続クラスがデータベースに格納されているかの事前の知識無しに、 データベースに格納された永続クラスの情報を取り出すAPIがいくつか提供されます。
[procedure] kahua-persistent-classes-in-db
現在のデータベース内にある永続クラスのクラス名(シンボル)のリストを返します。
[procedure] kahua-persistent-class-generation class-name
現在のデータベースから、名前class-name(シンボル)で示される 永続クラスを探し、その最新の世代番号(整数)を返します。 指定のクラスが無い場合は#fが返ります。
[procedure] kahua-persistent-class-definition class-name [generation]
現在のデータベースから、名前class-name(シンボル)で示される 永続クラスの定義を取り出し、define-classフォームを作成して返します。 返されたフォームをevalすると、呼び出したプロセス内でその永続クラスが 使えるようになります。
複数の世代がデータベースに格納されている場合、デフォルトでは 最新の定義が得られますが、generation引数により世代を指定することもできます。
class-nameに対応する永続クラスが無い場合、また、 generationに対応する世代が無い場合は#fが返されます。
なお、この関数が返すフォームは、その永続クラスを作ったプロセスの持つ クラス定義と完全に一致するわけではないことに注意して下さい。 データベースには、クラスを永続化するために必要十分な情報しか 格納されていません。この関数が返すクラス定義は、元の定義にくらべて 次のような違いがあります。
- クラスの継承情報は失われます。返されるクラスは<kahua-persistent-base>を 直接継承します。
- 非永続スロットの情報は含まれません
- 永続スロットのスロットオプションは :allocation オプションを除いて 失われます。
- :source-id以外の初期化オプションは失われます。
- スロットの順序は保存されません。
このような違いがあっても、データベースのメタ情報を扱う アプリケーションにとっては、クラス定義情報は有用でしょう。