人気ブログランキングへ

2009年12月27日

WebアプリでSQLiteを使ってみる (Perl)

SQLiteは、"most widely deployed SQL database engine in the world" だそうである (SQLite のホームページより)。
しかも、設定不要でサーバーの設置の必要もなく、トランザクションにも対応している。
こんな重宝なものを使わずに放っておくのはもったいない。
そんなわけで、(今さらながら) SQLite を使ってみた。

今回使用した環境は、
・SQLite
・Perl (および、DBI, DBD:SQLite)
・OS は Fedora 10
たいていのレンタルサーバーであれば、(OSはさておき) こういう環境が用意されているのではないだろうか。

以下は、簡単なアドレス帳の Web アプリの作例。

(1) ドキュメント

SQLite のホームページでドキュメントが整備されている。
以下のレファレンスがあれば、だいたい事足りそうだ。
http://sqlite.org/lang.html
これを眺めてみると、意外なほど機能が充実していることが分かる。

(2) sqlite3 コマンドでデータベースファイルを作成

sqlite3 は、コマンドラインから SQLite データベースファイルを操作するためのコマンドである。

SQLite では、個々のデータベースファイルが MySQL や PostgreSQL の「データベース」に相当する。
たとえば、コマンドラインから
$ sqlite3 addrbook.db
を実行すると、addrbook.db というデータベースファイルが作られ、SQLite のプロンプトが表示される。
sqlite>
この SQLite プロンプトに SQL 文を入力すれば、指定したファイル (上記の場合は addrbook.db) にデータが書き込まれていく。

なお、
sqlite> .help
と入力すると SQLite コマンド一覧が表示されるので、だいたいの機能の見当がつく。
(.databases というコマンドがあり、データベース一覧を表示できる。ということは、1 ファイルで複数のデータベースを保持できるのだろうか? 今のところ、真相不明)

さて、必要なテーブルを sqlite3 で作っておこう。
sqlite> CREATE TABLE personal ( name, addr, tel, email );
sqlite> .quit
これで、データベースファイル addrbook.db の準備は完了である。

(3) Webアプリからの操作

では、Web アプリから Perl / DBD::SQLite 経由でデータベースファイルにアクセスしてみよう。

まずは、サンプルコード。
※SQLインジェクションなどの対策はまったくしていないのでご注意。
#!/usr/bin/perl
use strict;
use CGI qw(param);
use DBI;
# データベースへの接続
my $dbname = 'addrbook.db';
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", '', '') or do {
print_err('データベースに接続できない');
exit 0;
};
if (param()) {
my $name = param('name');
$name =~ s/'/''/g;
$name =~ s/\\/\\\\/g;
my $addr = param('addr');
$addr =~ s/'/''/g;
$addr =~ s/\\/\\\\/g;
my $tel = param('tel');
$tel =~ s/'/''/g;
$tel =~ s/\\/\\\\/g;
my $email = param('email');
$email =~ s/'/''/g;
$email =~ s/\\/\\\\/g;
my $sql = "INSERT INTO personal ( name, addr, tel, email ) "
. "VALUES ( '$name', '$addr', '$tel', '$email' )";
$dbh->do($sql) or do {
print_err("SQL実行失敗:<br>$sql", __LINE__);
exit 0;
};
}
my $sql = 'SELECT name, addr, tel, email FROM personal';
my $sth = $dbh->prepare($sql) or do {
print_err("SQL準備失敗 ($sql)", __LINE__);
exit 0;
};
my $rc = $sth->execute or do {
print_err("SQL実行失敗 ($sql)", __LINE__);
exit 0;
};
print <<EOS;
Content-Type: text/html;charset=utf-8
<html>
<head>
<title>アドレス帳</title>
</head>
<body>
<form action="addrbook.cgi">
名前: <input type="text" name="name"><br>
住所: <input type="text" name="addr"><br>
電話: <input type="text" name="tel"><br>
メール: <input type="text" name="email"><br>
<input type="submit" value="追加">
</form>
<table border="1">
<tr>
<th>名前</th>
<th>住所</th>
<th>電話</th>
<th>メール</th>
</tr>
EOS
while (my $ref_row = $sth->fetchrow_hashref) {
print " <tr>\n";
print " <td>", $ref_row->{'name'}, "</td>\n";
print " <td>", $ref_row->{'addr'}, "</td>\n";
print " <td>", $ref_row->{'tel'}, "</td>\n";
print " <td>", $ref_row->{'email'}, "</td>\n";
print " </tr>\n";
}
print <<EOS;
</table>
</body>
</html>
EOS
$dbh->disconnect;
sub print_err
{
my $msg = shift @_;
my $line = $#_ >= 0 ? shift : undef;
print <<EOS;
Content-Type: text/html;charset=utf-8
<html>
<head>
<title>エラー</title>
</head>
<body>
<h1>エラー</h1>
EOS
if ($line) {
print "l.$line<br/>";
}
print <<EOS;
<div>$msg</div>
</body>
</html>
EOS
}
1;
これを、UTF-8 エンコーディングで addrbook.cgi というファイル名でしかるべき場所に、addrbook.db とともに保存すればよい。
(addrbook.db は、Apache から読み書きができるようにパーミションを変更しておく必要がある)

addrbook.cgi をブラウザで開くと、上半分がアドレスの追加フォーム、下半分がアドレス一覧になるはずだ。

上のコードでは、DBI->connect でデータベースファイルに接続し、do で INSERT し、prepare & execute で SELECT を実行し、fetchrow_hashref で SELECT 結果を読み出している。
posted by K/I at 07:45 | 東京 ☀ | Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。