2008-02-13

近況

体調不全で一回休み. 週末のんだくれて喉をやられてしまった. 酔っぱらいよくない... 禁煙のビール屋があってもいいと思うんだけどなあ.

そのビール屋で組み込み屋さんの友達と宴会をしているときに, sqlite いいよねという話になった. web での sqlite は rails や php と一緒に人気が出た気がする. 組み込み用途でも人気. たとえばゲーム屋さんでは zlib と lua の次くらいに使われてるという風説がある. (真偽不詳.) ライセンスが緩いのもいい. 私もなんとなくファンで, たまにウェブサイトの文書を眺めたり 触ってみたりしている.

今日も wiki を眺めていたら, いつのまにか FTS のバージョンは 3 になり, 仮想テーブルに続いて 仮想ファイルシステム なんてのも 実装されていた. コード以外の話題では Mozilla と Symbian が sponsor になった様子. なかなか熱心に開発されているし, 企業が金を出すくらいの実用性がある. sqlite に精通して組み込みデータベースエンジニアになる, なんてのは 組み込み屋さんとしてはアリじゃないか. このあいだはそんな話をしていた.

その友達は, 組み込み屋さんとして sqlite に二つの懸念を持っていた. ひとつはストレージの消費容量を入力するデータから計算できるかということ. もう一つは atomic write のための fsync で 刺さるのが困ること. いかにも組込みっぽい懸念ではある.

ストレージサイズは, 調べればわかる...と思う. ちょっと面倒そうだけど, 予想不可能というかんじはない. fsync での block は, 改造が必要かと思ったら先の VFS で解決するようだ. (VFS というと大袈裟だけど, 要するにファイル周辺の移植層ね.) そのものずばりな test_async.c なるサンプルがあった. やりくちは単純. ファイル IO の要求をキューイングして遅延する. そういえば sponsor になっている symbian の OS は基本的に API が非同期だと聞く. VFS は sponsoring の成果なのかもしれない. でも, かわりに btree のトラバースが心配になってきた. 読み出しは遅延して隠すことができないからブロックせざるを得ない. 困った. 中断をあわらすエラーもなさそう. symbian ではどうやって解決してるんだろうね. まさか setjmp じゃ... ゲーム機ならスレッド使っておわりなんだけど. (test_async.c では解決していない.)

Fossil

sqlite にはいくつかのブランチがあり, それらのブランチは sqlite 作者謹製の Fossil という SCM で管理されている. 分散 SCM らしい. ページの宣伝によれば, ウェブ UI を内蔵し, Trac 風の BTS や Wiki を標準で供えている. CGI でも動く. レポジトリが単一のファイルに収まっており管理しやすい. それに実行ファイルひとつで動くからインストールも簡単...実行ファイル?

まさかと思いスナップショットをダウンロード. 不安は的中した. C言語で書かれている. マジかよ. しかもプリプロセッサとして実装されたコード埋め込みのテンプレートエンジンを 使って HTML などを整形してる. こりゃいじる気にならないなあ... コードベースには Amalgamation された sqlite が含まれる. 単一ファイルレポジトリの正体は sqlite のデータベースというわけ.

コードはこんなかんじ.

/*
** WEBPAGE: home    // このコメントも解釈されるっぽい.
** WEBPAGE: index
** WEBPAGE: not_found
*/
void home_page(void){
  char *zPageName = db_get("project-name",0);
  if( zPageName ){
    login_check_credentials();
    ...
    wiki_page();
    return;
  }
  style_header("Home");
  @ <p>This is a stub home-page for the project.
  @ To fill in this page, first go to
  @ <a href="%s(g.zBaseURL)/setup_config">setup/config</a>
  @ and establish a "Project Name".  Then create a
  @ wiki page with that name.  The content of that wiki page
  @ will be displayed in place of this message.
  style_footer();
}

はー...

せっかくなので動かしてみよう. 手順 に従い スナップショットをダウンロード, 展開, ビルドする. ビルドはただ make するだけ. (要 zlib.) fossil というバイナリができるから, 適当に path を通す.

使ってみる.

$ mkdir hello
$ cd hello
$ fossil new hello
$ ls
hello

この hello ファイルがレポジトリ. こんなかんじになっている:

$ sqlite3 hello
SQLite version 3.4.2
Enter ".help" for instructions
sqlite> .tables
blob         event        phantom      reportfmt    tagxref      user
config       filename     plink        shun         unclustered
delta        mlink        rcvfrom      tag          unsent

コマンド体系は mercurial や svk と同じ路線 のようす.

$ fossil help
Usage: fossil help COMMAND.
Available COMMANDs:
add          close        gdiff        new          revert       timeline
branch       commit       help         open         rm           undo
cgi          deconstruct  http         pull         server       update
changes      del          info         push         settings     user
checkout     descendents  leaves       rebuild      status
clean        diff         ls           reconstruct  sync
clone        extra        merge        redo         tag
This is fossil version [1ce0ac53ef] 2008-02-12 00:31:48

...でも, ちょっと面倒. まず open で working copy をつくるらしい.

$ fossil open hello
$ ls
_FOSSIL_ hello
$ sqlite3 _FOSSIL_
SQLite version 3.4.2
Enter ".help" for instructions
sqlite> .tables
vfile   vmerge  vvar

追加, チェックインは他と同じようなかんじ.

$ echo Hello > hello.txt
$ fossil add hello.txt
$ fossil commit # エディタ起動. 色々聞かれるけど yes で乗り切る.

HTTP server もついてくる.

$ fossil server hello # 8080 で内蔵の httpd が起動する

ブラウザで wiki などを見るほか, 分散らしく clone もできる.

$ fossil clone http://localhost:8080/ foo

さっきの hello ファイルが foo という名前でコピーされる.

$ ls
foo hello

このへんで飽きた.

sqlite を使った小さなアプリケーションの例として眺める分には面白いけれど, 普通に使うなら mecurial の方がいいや... それにしても C 言語でこんなのを書いちゃうとは, sqlite 作者の D. Richard Hipp はタフだなーと尊敬しました. 会社休んでる場合じゃないね.