Apache Module mod_dbd (ubuntu 12.4 apache install)
Apache Moduleからmod_dbdを使ってDBにアクセス、レコードの中身を表示してみる。
mod_dbdはapr(Apache Portable Runtime)を使ってデータベースを操作するもの。
http://httpd.apache.org/docs/2.4/mod/mod_dbd.html
http://apr.apache.org/
ubuntuにはmoduleを有効にするa2enmodと無効にするa2dismodがあるが
そもそもコンパイルに含まれていない関数を使ってる場合はmoduleのコンパイルは通っても
sudo /etc/init.d/apache2 start * Starting web server apache2 apache2: Syntax error on line 210 of /etc/apache2/apache2.conf: Syntax error on line 1 of /etc/apache2/mods-enabled/db.load: Cannot load /usr/lib/apache2/modules/mod_db.so into server: /usr/lib/apache2/modules/mod_db.so: undefined symbol: ap_dbd_acquire
undefined symbol: ap_dbd_acquireとなる。
apt-getとかデフォルトで入ってるapacheではたぶんこうなる。
apacheをソースコードからビルドする。
apr,apr-utilも最新のものにする。
ubuntu 12.4には/usr/include/apr-1.0/が入ってるが1.2以上じゃないとビルドこけるらしい。
環境
#sakura vps $ uname -a Linux www28181ue 3.2.0-36-generic #57-Ubuntu SMP Tue Jan 8 21:44:52 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=12.04 DISTRIB_CODENAME=precise DISTRIB_DESCRIPTION="Ubuntu 12.04.1 LTS"
$ sudo su - root % cd /usr/local/src/ % wget http://ftp.jaist.ac.jp/pub/apache//httpd/httpd-2.4.4.tar.gz % wget http://ftp.tsukuba.wide.ad.jp/software/apache//apr/apr-1.4.6.tar.gz % wget http://ftp.tsukuba.wide.ad.jp/software/apache//apr/apr-util-1.5.2.tar.gz % tar xvzf httpd-2.4.4.tar.gz % tar xvzf apr-1.4.6.tar.gz % tar xvzf apr-util-1.5.2.tar.gz % mv apr-1.4.6 httpd-2.4.4/srclib/apr % mv apr-util-1.5.2 httpd-2.4.4/srclib/apr-util % cd httpd-2.4.4/srclib/apr % ./configure --prefix=/usr/include/apr-httpd/ % make && make install % cd ../apr-util % ./configure --prefix=/usr/include/apr-util-httpd/ --with-apr=/usr/include/apr-httpd/ --% with-mysql=/usr/include/mysql % make && make install % cd ../../ % ./configure --prefix=/usr/include/apache22 \ % --with-mpm=worker \ % --with-apr=/usr/include/apr-httpd/ \ % --with-apr-util=/usr/include/apr-util-httpd/ \ % --enable-mods-shared=all \ % --enable-modules=all \ % --enable-proxy \ % --enable-cache \ % --enable-disk-cache \ % --enable-mem-cache \ % --enable-ssl % make && make install
起動。あとでpathを追加。
% /usr/include/apache22/bin/apachectl start
ちょいちょいlogs/error.log吐いたが、とりあえず動かしたいので
conf/httpd.confのslotmem_shmを有効にし、lynxを入れた。そういうログが出てた。
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
# apt-get install lynx
これで動くようになる。
あとは/usr/include/apache22/bin/apxsでモジュールのひな形を作る。apache再起動でmoduleが有効になる。
$ cd /my/apache_modules $ /usr/include/apache22/bin/apxs -g -n db $ sudo /usr/include/apache22/bin/apxs -i -a -c mod_db.c $ sudo /usr/include/apache22/bin/apachectl restart
mod_db.c ※変更点のみ記載
#include "apr_dbd.h" #include "mod_dbd.h" #include "apr_strings.h" static void execute(request_rec *r) { apr_status_t rv; apr_dbd_results_t *res; apr_dbd_row_t *row = NULL; char stmt[] = "select * from user"; int rows,cols; ap_dbd_t *dbd = ap_dbd_acquire(r); if (dbd == NULL) { ap_rputs("failed to connect db.", r); return; } int code = apr_dbd_select(dbd->driver, r->pool, dbd->handle, &res, stmt, 0); if (code != 0) { ap_rprintf(r, "failed. error_code:%d", code); return; } rows = apr_dbd_num_tuples(dbd->driver, res); cols = apr_dbd_num_cols(dbd->driver, res); ap_rprintf(r, "rows:%d, cols:%d<br>", rows, cols); for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1); rv != -1; rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) { if (rv != 0) { ap_rputs("finish.", r); return; } int i; for (i = 0; i < cols; i++) { char *val = apr_palloc(r->pool, sizeof(char)); val = apr_dbd_get_entry(dbd->driver, row, i); ap_rprintf(r, "%s ", val); } ap_rputs("<br>", r); } } /* The sample content handler */ static int db_handler(request_rec *r) { if (strcmp(r->handler, "db")) { return DECLINED; } r->content_type = "text/html"; if (!r->header_only) execute(r); return OK; }
httpd.confにDBの接続情報を追記、moduleとディレクトリの紐付けも
<Location /db> SetHandler db </Location> DBDriver mysql DBDParams user=delaemon,host=localhost,pass=shizuka,dbname=dekisugi DBDMin 5 DBDKeep 5 DBDMax 10 DBDExptime 60
mysqlは適当をインストールして、db,user,tableを作っておく。
http://your_host/db
でレコードの中身が画面に表示される。
apr_dbd_num_tuplesは
apr_dbd_select(dbd->driver, r->pool, dbd->handle, &res, stmt, 0);だと-1
apr_dbd_select(dbd->driver, r->pool, dbd->handle, &res, stmt, 1);だとレコード数が返る。
apr_dbd_selectは
成功の場合は0、もしくエラーコード(今回はmysqlのもの)が返される。
その他、apr_dbd_XXX使い方、返り値はソースコードか以下を参照
https://apr.apache.org/docs/apr/trunk/group___a_p_r___util___d_b_d.html
いろいろ調べてたらmod_sample.cを読むと学びがあるらしいので後で読む
http://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x/modules/experimental/mod_example.c