debianでMySQL with sennaのパッケージを作ってみる

debian lennyをインストールしてみました。debianは過去に一度触ったことがあってそれ以来です。まだsargeも出ていなかった頃だったと思います。
FreeBSDとなんとなく似てる所もあるのですが、最小構成でインストールするとほんとにスッキリしてていいですね。

それで早速いろいろインストールしていたのですが、sennaバインディングしたMySQLをインストールしようとして、ちょっと手間取りました。ソースから入れてしまえば早いのかもしれないですが・・・。

sennaはソースからインストールしたのですが、どうもsennaMySQLパッケージを作ると、依存関係とかで引っかかってしまいました。

dpkg-shlibdeps: failure: no dependency information found for /usr/local/lib/libsenna.so.0 (used by debian/mysql-client-5.0/usr/bin/mysqltest_embedded).
dh_shlibdeps: command returned error code 512
make: *** [binary-arch] エラー 1

分からなかったので、sennaのパッケージも作ってみます。
ここを参考にしました。
|| Not Found ||

## dh_makeというパッケージを作るコマンドを入れる
# aptitude install dh-make
$ tar zxvf senna-1.1.4.tar.gz
$ cd senna-1.1.4
## -fでソースパッケージ指定
$ dh_make -f ../senna-1.1.4.tar.gz
## パッケージの種類(single binaryを選択)
> Type of package: single binary, multiple binary, library, kernel module or cdbs?
> [s/m/l/k/b] s
## 次に作成されたdebianディレクトリの中にある、
## debina/rulesを編集します。
## 今回はmecabを使わないので、configureの値に追記しました。
$ vim debian/rules
> ./configure $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs" --with-mecab=no
## パッケージを作成
$ dpkg-buildpackage -rfakeroot
## 成功すればdebファイルが出来るので、そのままインストール
# dpkg -i ../senna_1.1.4-1_i386.deb

次にここを参考にして、MySQLのパッケージを作ってみます。記事の内容がちょっと古いようで、今のバインディングパッチではautotoolsなどは不要で一気にconfigureを実行できるようです。

$ mkdir ~/mysql-server-5.0
$ cd ~/mysql-server-5.0
$ apt-get source mysql-server-5.0
# apt-get build-dep mysql-server-5.0

これでカレントディレクトリ内にソースパッケージが展開されます。
次にdpatchを作ります。その前にsennaのバインディングパッチをダウンロードします。
ここからパッチを落とした
ダウンロード – Tritonn – SourceForge.JP

$ cd mysql-dfsg-5.0-5.0.51a
$ dpatch-edit-patch patch 99_senna 95_SECURITY_CVE-2009-2446.dpatch
## ここでパッチ作成用のシェルに自動的に入ります
## キャンセルする時は、exit 230と打たないと反映されてしまうので注意
## 先ほど落としたパッチを当てる
$ patch -p1 < ~/msyql-server-5.0/tritonn-1.0.10-mysql-5.0.51a.diff
$ find . -name '*.rej'
$ find . -name '*.orig' -exec rm {} \;
$ exit

これでdpatchが作成されます。作成したdpatchの情報を書き込みます。

$ echo "99_senna.dpatch" >> debian/patches/00list
## configureに--with-sennaを追加する
$ vim debian/rules
> --without-ndb-docs \
> --with-senna'

参考サイトのまま実行すると、次にdebuildをするわけですが、以下のようなエラーが出てしまいます。

$ debuild -rfakeroot -us -uc
## こんなエラーが出て途中で止まってしまう
configure.in:2981: required file `debian/Makefile.in' not found
configure.in:2981: required file `debian/defs.mk.in' not found
configure.in:2981: required file `debian/control.in' not found
make[1]: *** [Makefile.in] エラー 1
make[1]: ディレクトリ `/home/hogehoge/mysql-server-5.0/mysql-dfsg-5.0-5.0.51a' から出ます
make: *** [build-stamp] エラー 2
dpkg-buildpackage: failure: debian/rules build gave error exit status 2
debuild: fatal error at line 1319:
dpkg-buildpackage -rfakeroot -D -us -uc failed

dpatchを作る際に、configure.inを戻すと書いてあったのですが、これを戻さないでおくとエラーが出る事なくできました。

## これを実行しない
$ cp ~/mysql-server-5.0/mysql-dfsg-5.0-5.0.51a/configure.in .

次にビルドは通ったのですが、どうしてもテストが通りませんでした・・・。とりあえず、テストをしないようにして回避しました。

$ DEB_BUILD_OPTIONS=nocheck debuild -rfakeroot -us -uc

このままでは、libsennaの依存でエラーになりましたので、debian/shlibs.localファイルに以下のように書き込みます。

libsenna        0       senna (>= 1.1.4)

同じようにdebuildしますが、失敗してから再度実行するとエラーになってしまったので、最初からやり直しました。
成功すると以下のようなファイルができます。

libmysqlclient15-dev_5.0.51a-24+lenny2_i386.deb
libmysqlclient15off_5.0.51a-24+lenny2_i386.deb
mysql-client-5.0_5.0.51a-24+lenny2_i386.deb
mysql-client_5.0.51a-24+lenny2_all.deb
mysql-common_5.0.51a-24+lenny2_all.deb
mysql-server-5.0_5.0.51a-24+lenny2_i386.deb
mysql-server_5.0.51a-24+lenny2_all.deb

かなりたいへんでした・・・ソースから入れたほうが楽だったかも。

SQLiteの日付にハマる

この前初めてSQLiteを使ってみたのですが思わぬところでハマってしまいました。

SQLiteではよくある話のようで日付処理に関する問題です。
型の概念がほとんどないらしく、数値と文字列の二つで管理されている?ようです。テーブルを見てみるとDATE型とか表示されるので一見、型があるように思うのですが・・・。

当然日付に関しても数値か文字列でしか管理されないというわけです。
なので、挿入する際に数値か文字列のどちからで統一しておかないと、めんどうなことになりそうです。
日付文字列に関してのフォーマットもあまり柔軟ではないようです。

例えば関数に渡すとき

# YYYY-MM-DD HH:MM:SS これならOK
1999-02-01 23:01:01
# YYYY-M-D H:M:S これだとだめ
1999-2-1 23:1:1

julianday関数で数値化して格納するか、文字列のフォーマットを統一して格納するという感じでしょうか・・・?
文字列のフォーマットを統一する際は、アブリ側でやることになるのでしょうか?PHPならば、mktime、sprintf、strftime、strtotime関数などが使えそうです。RubyならDateクラスなどに同様のメソッドがあるみたい?です。

参考
shiromaru しろまる: SQliteで日付の演算ができるみたいだ
rakuto.net – rakuto Resources and Information. This website is for sale!

はじめてのSQLite

はじめてSQLiteさわってみました。

さくらのワンコイン共有サーバ使っているのですがMySQLのDBは一つしか作れないのですね・・・。
不安定で遅い!というイメージだったので敬遠していたところがあったのですがMySQLより速い?らしい。よく考えたら軽い実装なのだから当たり前なのかな?

サーバの設定ではデフォで使えるようになっていた(PHP)ので、さっそくDBを作ってみよう!と思ったのだけど、よく考えたら安いプランでシェルが使えなかった。WebベースのSQLiteManagerというのを入れてみました。phpmyadminみたいなものみたいです。

無事にDBを作ってテーブルを流し込みました。型とか大丈夫なのかな?と心配でしたが、すんなりいって一安心。SQLiteは型の概念がほとんどないらしい。

ここまではよかったのですが、ここからちょっと引っかかりました。
PHPで昔作ったものでADODBというライブラリを使っていたのですが、DSNをSQLiteに書き換えても上手く動きません。

sqlite:///home/hogehoge/sqlite/hoge.db
SQL logic error or missing database

こんなエラーが出ました。パーミッション?SQL?と色々いじってみたのですが解決せず・・・。でもよく考えるとSQLiteManagerでは動いていた気がしました。ADODBのソースを見てみる事に・・・。

どうも独自に内部でDSNを処理しているらしく、parse_url関数の部分でエラーになってるっぽいです。ホスト名の指定がないせいで、正しいURLと解釈されないのが原因でした。絶対パスで指定するのが間違ってるのかな・・・?

sqlite://localhost/home/hogehoge/sqlite/hoge.db

こんな感じに直してみたらまだエラー。さらにソースを覗いてみると

if (empty($argHostname) && $argDatabasename) $argHostname = $argDatabasename;

どうもホスト名が空じゃないとだめらしい・・・。これは無理かなと思い、別の方法を考えることに。

$con =& NewADOConnection('sqlite');
$con->Connect('/home/hogehoge/sqlite/hoge.db');

これで動きました!これが一番簡単みたい。でもどうしてもDSNで指定したいと思い、ソースを眺めてたらこんな記述がありました。

if (($at2 = strpos($origdsn,'@/')) !== FALSE) {
// special handling of oracle, which might not have host
$fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn);
}

どうやら@を使えばホスト名を指定しなくてもOKらしいです。結局これで解決しました。

# ちなみに@の後に/を二つ書かないと一つ目は消されるみたい
sqlite://@//home/hogehoge/sqlite/hoge.db

そんなこんなで小一時間かかりました。
そういえば、NOW()なんてのも動かないんですね・・・。