<!--
   $FML: db_modules.sgml,v 1.2 2004/10/06 09:07:38 fukachan Exp $
-->

<!--
    XXX-TODO: データベース関連モジュール も書き直した方が…
-->


<chapter id="db.module">
	<title>
	データベース関連モジュール
	</title>


<sect1 id="db.module.ovewview">
	<title>
	概要もしくは理想像
	</title>

<para>
ＭＬドライバはメールのさまざまな要素をデータとして保存する必要がありま
す。しかしながら、同じ要素でも、永続的に持つべき場合と、一定時間経過後
に捨てて良い扱いの場合とがあります。
</para>

<para>
前者の例はスレッドのデータです。一方、後者の例はフィルタシステムの持っ
ている message-id cache などです。スレッドデータベースも同じく 
message-id のデータを持っていますし、記事の分については重複しています。
ですが、２つの有効期間は異なるため別々に取り扱う必要があります。
</para>

<para>
とはいえ実際問題スレッド関係とそれ以外に集約できそうなので、
各モジュールの理想的な関係は次のようになるのでしょう。
<screen>
モジュールＡ ---|ア|----- スレッド DB
モジュールＢ ---|ダ|
モジュールＣ ---|プ|
モジュールＤ ---|タ|----- キャッシュ (有効期限つき)
</screen>
このスレッド DB は 
<link linkend="threadtrack.db">
Mail::Message::DB
</link>
のようなものとし、各種アダプタ層が頑張って欲しい。
また、キャッシュの方ですが、現在では Tie::JournaledDir もしくは 
FML::Cache::Ring のいづれかが使われることとなっています。
</para>

<para>
なお、メンバーリストなどの永続性の必要なデータに対するデータベースはき
ちんと DBMS (データベース管理システム)を使うべきです。ここで述べている
データベースは fml8 が動作する上で内部的に使っているデータベースです。
</para>

</sect1>


<sect1 id="db.module.persistent">
	<title>
	永続的なデータの保持
	</title>

<para>
永続的にデータを保持する方法はいくつかあります。いい加減なものから大真
面目なものまでいろいろです。大真面目に考えると、LRU などの機能を持った
モジュールを利用して作るのかもしれませんが、やや大げさで、いまひとつしっ
くりこない気がします。つまり、そこまで真面目に virtual memory のような
実装をしなくてもよいのでは？という気がします。それに、もし切実に必要な
ら、なんらかの
<link linkend="dbms">
DBMS
</link>
	<footnote>
	<para>
	DBMS = DataBase Management System
	</para>
	</footnote>
を使うべきでしょう。
</para>

<para>
ここでは fml8 内部で使っているモジュールの話をします。
</para>

<para>
&fml8; では、データの expire の仕方に応じて２つのデータ保持クラスを用
意しています。それは「サイズを気にせず、時間を区切って expire するのか？」
もしくは「使用する領域のサイズをある程度気にするか？」の２種類です。
</para>

</sect1>


<sect1 id="db.module.Tie.JournaledFile">
	<title>
	Tie::JournaledFile クラス
	</title>

<para>
これは、一つのファイルに append していくタイプです。
この機能は
	<ulink url="../../en/modules/Tie/JournaledFile.txt">
	Tie::JournaledFile
	</ulink>
クラスが提供します。
</para>


<para>
このクラスは、データを追加もするし参照もしたい場合に用いられますが、
追加のオペレーションしか行なえません。
つまり LFS (Log Structured File System) のような振舞いです。
</para>


<para>
参照する際は最後に追加したデータが取り出されます。
つまり、値は追加された値を last match で取り出しています。
</para>


<para>
逆に、必要な場合には、過去のログを追跡していくことができます。
</para>


<para>
このクラスは、サイズを度外視して一定期間のあいだ記録しておきたいデータ
に対して使います。例えば、登録時の confirmation のキャッシュや
message-id キャッシュです。これらは expire を時間で制御したいからです。
このクラスは引数でファイル名を与えることになっているので、ファイル名に
日付付のファイルを選ぶと良いでしょう。
</para>


<para>
なお、普通の tie() とは違う
<screen>
key => [
	ろぐ1	 (どっかのふぁいるのどっかの行),
	ろぐ2	 (どっかのふぁいるのどっかの行),
	ろぐ3	 (どっかのふぁいるのどっかの行),
]
</screen>
型のデータとりだしをしたい場合があります。
この形のデータ取り出しは
get_all_values_as_hash_ref()
メソッドを使えば可能です。
</para>


<warning>
<para>
なお検索時の挙動のfirst match と last match は切替えることができます。
どちらの戦略で探すのか、クラスオブジェクトを生成する際に明示的に指定す
ることが推奨されます。デフォルトは last match です(最後に書き込んだデー
タが返される振舞いが自然です)。
</para>
</warning>

</sect1>


<sect1 id="db.module.FML.Cache.Ring">
	<title>
	FML::Cache::Ring クラス
	</title>

<para>
この
	<ulink url="../../en/modules/File/CacheDir.txt">
	FML::Cache::Ring
	</ulink>
クラスは、主にサイズに上限を設けたいタイプのデータを蓄える場合に用
います。expire の時間については気にしません。
サイズで有無を言わさず切ってしまいます。
</para>


<para>
デバッグ等に用いるデータはこれで十分と考えます。
普段は使わないデバッグのために、サイズを食われるのも嫌ですから。
</para>


<para>
このクラスは、あるディレクトリ(例: db/)の有限の複数のファイル群の中に
データを蓄えます。
例えば db/ に 1 〜 100 の名前のファイルがつくられ、
順番に使われてきます。
これらのファイルはぐるぐる回って使われ、上書きされます。
</para>


<warning>
<para>
旧 RingBuffer は FML::Cache::Ring に統合されました。
また、FML::Cache::Ring は File::CacheDir から作られました。
</para>
</warning>

</sect1>


</chapter>
