./index.html ../index.html

Database Note

MyBase♪

きっぱり、個人でデータベースを扱う価値は無いと思ってました。
データベースという仕掛けは魅力的でも、いちいちデータベースサーバーソフトやSQLを取り扱う手間ばかり多く…サーバーをバックグラウンドで起動させたり終了させたり(普段使わないので常駐させる気はない)…大体ゲームデータ格納用にデータベース使いたいと思っても、いちいちAccessやInterBaseだかが必用なんて、やってられないじゃないですか!

MidasLib.dcuさえリンクしてしまえば、巨大*.exeにはなってしまうものの、サーバーもDLLも一切不要! Delphi6のMyBase機能は、メモリーの制限は受けてしまいますが、それも個人用途である限りPC搭載メモリーを超えるデータを使う必要性は感じられないし、個人ユースでは結構理想じゃないか…と、思ってみても、普段データベースなんていじらない僕にとっては、難しいとかの以前に、どうもとっつきが掴めない…気がしてたんです。

格闘してみて…うーむ、結構使えそうだ、ということが判明。
TDBGridさえ貼っておけば編集GUI作らなくていいし、こりゃ結構強力そうです、 ということで、自分が忘れないうちに使い方を書いておきます。

編集GUI作成

うんうん。これだけ使えれば編集機能としては普段使う分は完璧ですね。(本当か?)

コードからデータを読み取る

編集機能は「Data Controls」に任せるとして、コードからデータを読めなければ無意味です。

ClientDataSet1.First;
while not ClientDataSet1.Eof do
begin
  {項目を作った時にできるClientDataSetXXXのAsStringとかで読み取り}
  ClientDataSet.Next;
end;

全列挙さえできればなんでもありですね。非効率だけど。
FindKeyとかそれっぽいのはあるのですが…使い方は不明。 ヘルプみてもわけわからないし…。

TClientDataSetをTDataSetProvider経由で連結してみる実験

dbExpressでは、TClientDataSetをバッファとして、
サーバー←TSQLConnection←TSQLDataSet←TDataSetProvider←バッファ用TClientDataSet
という風に繋ぎますが、これを、
データ保持用TClientDataSet←TDataSetProvider←バッファ用TClientDataSet
という風に繋ごうというわけです。
メリット?編集カーソルを複数持てることかな…。

バッファ用TClientDataSetをAccessDataSet、データ保持用TClientDataSetをMainDataSetとすると、dbExpressと同じやり方で、AccessDataSetMainDataSet方向の反映は、AccessDataSet.Refreshで、AccessDataSetMainDataSet方向の変更通知(ついでにAccessDataSetの変更記録破棄)は、AccessDataSet.ApplyUpdates(-1)でいけるはず… と思ったら、謎の例外が発生するのですね。

ヘルプを調べまくった結果、間のTDataSetProviderのResolveToDataSetTrueにしないといけない事が判明。 要するにデフォルトではサーバーにSQLを送ろうとしていたわけ…。サーバーは当然ありませんから。

一通り実験しましたが、何といっても、SQLが出てこないのがいいですねー。
さーて、何に使おう。 やっぱり個人ユースでは用途が思いつかないのでありました。

dbExpressのドライバを静的リンクする

dbExpressのドライバ.dllは.exeに静的にリンクすることもできる…とマニュアルに書いています。
本当であれば、特にMyBaseなんか、追加配布物無しでデータベースが使えます。 そうでなくても依存.dllが一個減るって嬉しいですよ。

以下の対応がヘルプには書かれています。

データベースサーバー ドライバDLL 静的リンク用ユニット
INTERBASE dbexpint.dll dbexpint.dcu
ORACLE dbexpora.dll dbexpora.dcu
MYSQL dbexpmys.dll dbexpmys.dcu
DB2 dbexpdb2.dll dbexpdb2.dcu

しかし、Professional版では、InterBase用またはMySQL用しか見当たりませんでした。 Enterprise版なら全部付いているのかも。 (DB2とかMySQLなんて聞いたことすらないですけどね…)

とにかく、チュートリアル(ヘルプにあるCLXでInterbase接続のやつ)を終えた僕は、dbexpint.dcuを静的リンクしようとusesの最後にdbExpIntと書き加えたのです。

で、結果がこれ。
Internal Error

カラーカスタマイズは僕の趣味だからこの際関係ないとして、Update1の漏れか?とか、リンカのバグか?とか、色々考えてしまいました。

試行錯誤はすっ飛ばして結論を書きますと、こういうことでした。

MIDASの項目は何故かDelphi6のヘルプから消えていて、どうもMyBaseとDataSnapになってしまったらしいです。 それはいいんですけれど、記述が分散して、MidasLib.dcuに辿り着くのは至難の業と思います。 Delphi5のヘルプが無ければ、恐らく辿り着けませんでした…。 到達したい方は、「TClientDataSetの使い方」から、あっちこっち飛びまくっていると行けます。

ところで、上記DLLもBorland C++でコンパイルされているのはいいとして、Libディレクトリ以下にある*.libって一体? $L指令はOMFフォーマットの*.objファイルをリンクできるはずで、*.libはDelphiでは使えないはず…

Firebird embedded server♪

MyBaseに続いて、常駐させる必要が無いデーターベースとして、Firebird embedded server。 Interbaseから派生した、Interbase用のコンポーネントがそのまま使えるオープンソースデーターベースのFirebirdが、レジストリも何も使わないコピーだけで動く単なる.dllとして使えてしまいます。

Firebirdプロジェクトのファイル一覧ページから、Firebird-1.5.*.*_embed_win32.zipをダウンロード。

本体.exeを置く(予定の)ディレクトリに、以下のファイルをコピーします。

それだけで動く(らしい)です。 非常に簡単。 Delphi7\binにコピーしたら、設計時も動いてくれますでしょうか…?(未確認)

空のデーターベースファイルは、そのためだけにInterBaseとか普通のFirebirdを入れなくても、以下のコードで作成できます。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, IBDatabase;

type
  TForm1 = class(TForm)
    Button1: TButton;
    IBDatabase1: TIBDatabase;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  IBDatabase1.DatabaseName := ExtractFilePath(Application.ExeName) + 'test.gds';
  IBDatabase1.Params.Text :=
    'USER "SYSDBA"' + sLineBreak +
    'PASSWORD "masterkey"' + sLineBreak +
    'PAGE_SIZE 4096' + sLineBreak;
  IBDatabase1.CreateDatabase;
end;

end.

ファイルにデータを置く、SQLで操作するタイプのデーターベースですので、MyBaseよりも本格仕様ですね。 何年経っても相変わらず個人ユースでは用途は無いのですけれど。