ファイルDBシステム

DBが使えない場合にファイルをDB代わりに使うことが多い。
というかするしかない。
ただ、その場合、カラムが複数あったりすると結構面倒。
まぁやり様はいろいろかな。

検索とかつけると結構大変だね。

そこで、ファイルDBシステムを作った。
以前私の管理するブログでも公開していたのだが、それに+αしてある。
? 検索機能の追加。
? 排他制御のサポート

さて、
http://pluswing.net/download/FileTable.zip
をダウンロードし、解凍すると、
以下の4ファイルがある。
CriticalSection.class.php
FileTable.class.php
Columns.class.php
ColumnTable.class.php

CriticalSection.class.php排他制御クラス。 排他制御はフォルダの存在確認によって行っている。 詳しくは排他制御のところで触れよう。
FileTable.class.phpはファイルDBのベースとなるクラスだ。 こいつがファイルを読み込み、基本的な処理を行っている。
Columns.class.phpはカラム管理クラスだ。 これが1行をあらわす。 ちょっと命名が悪かったかな。
ColumnTable.class.phpはFileTableとColumnを内部に持つFacade的なクラスだ。 ユーザはこれを使用することになる。

まず、簡単な使いかたから説明しよう。
ColumnTableには以下のメソッドがある。

function ColumnTable($fileName, $separator, $columnNames)
コンストラクタ。 ファイルパス、セパレータ、カラム名配列を指定する。
たとえば、カラムが3つある場合、
$table = new ColumnTable("ファイルパス", ",", array("column1", "column2", "column3"));
大体分かるだろうか? セパレータはカラムの仕切りになる文字列なので、
データ中に絶対にない文字列にすれば何でも良い。複数文字でも構わないので、たとえば"!#$%&"とか。複雑にしておけば問題は出ないだろう。

全データの取得は以下を呼び出す。
function getAll()
戻り値はColumnsクラスの配列となるので注意が必要だ。
ColumnsクラスはSetterとGetterが分かればまぁ大丈夫だろう。
ということでここでは詳しく書かないが、取得は以下のように記述する。
$datas = $table->getAll();
$datas[0]->get("column1"); これで1行目の1カラム目が取れる。

1行のみの取得は以下で行える。 行指定だ。
function get($line)

次は更新。
function update($line, $columns)
行を指定し、get()もしくはgetAll()で取得したColumnsクラスを指定する。
これで更新される。
$datas[0].set("column1", "100");
$table->update(0, $datas[0]);
これでcolumn1が100に更新される。

次に行の削除だ。
function remove($line)
を使う。 行を指定すればその行が削除される。 これは簡単。

次に追加だ。 その前に1メソッド説明しておこう。
function createColumn()
これでデータが空のcolumnsクラスを取得できる。
$column = $table->createColumn();
$column->set("column1", "100");
$column->set("column2", "200");

追加メソッドはこれだ。
function add($columns)
上の$columnを指定してやれば、最終行に1行追加される。
$table->add($column);


検索と削除(ちょっと高度)だ。
function delete($deleteColumn)
function find($findColumn)
引数はどちらも一緒だ。
createColumn()で取得した後、検索(削除)対象となるデータを設定すれば良い。 設定した項目は完全一致していることが前提となる。
最初に見つかったものを削除するため、同一キーがある場合、複数行の削除にはならない。
findは最初に見つかった行を返す。 見つからなかった場合、NOT_FOND定数を返す。

$column = $table->createColumn();
$column->set("column1", "100");
$findIndex = $table->find($column);
これでcolumn1が100の最初の行を取得できる。

もう少し! 保存だ。
function save()
追加、更新、削除はsaveメソッド呼び出しでファイルに反映される。
トランザクション処理のためと、ファイルアクセス数を減らすためにこういう作りにした。
add()とかでファイルに反映されない場合はsaveを呼び出しているか確認して欲しい。
また、saveを実行すると、再読み込みが発生する。
削除をした場合、削除行以下の行番号が変更になるため、注意が必要だろう。

最後 排他処理だ。
function lock()
function free()

lock()で排他処理を開始し、freeで排他を解放する。
free内でsaveが呼び出されるので、排他処理を行っている場合はsaveを明示的に呼び出す必要はない。
基本的にwebシステムであれば読み込み以外はこれを使う事になるだろう。

また、排他制御ディレクトリ有無確認によって行っている。
ディレクトリ名はコンストラクタで指定したファイル名の後ろ4文字(拡張子分)を削除したものとなる。 覚書程度だが、注意して欲しい。

長々と書いたがこんなところだ。
最近公開したBBSにはこれを使用している。
速度面で問題が出そうだが、使い勝手は良いと思っている。