データベースと連動させよう!

 

CGIを使うようになってくると、どうしても必要なのがデータの保存です。
従来のPerlを使ったCGIでは、これらは全てファイルの読み書きにより行っていました。
しかし、この方法には手間がかかります。
幸い現代には、フリーで使えるデータベースが数多く存在します。
これを利用しない手は無いでしょう。

データベース・ライブラリのインストール

Rubyからデータベースを使うには、拡張ライブラリをインストールする必要があります。
ここではMySQLが既にインストールされているものとして話を進めます。
始めに、MySQLをRubyから使えるようにするライブラリをダウンロードしましょう。
Ruby公式ページのアーカイブから「MySQL/Ruby」をDLします。
後は他アプリの時と同様にインストール作業を行います。
うまくいかない場合は、付属の「README.ja」を読めば対処法が書いてあるはずです。
そこに書いてあるテストがうまく行けばOKです。先に進みましょう。

※注意
なお、MySQLは基本的にトランザクションを持たない高速データベースです。
もしあなたが「比較的頻繁にDB更新を行う」コンテンツを「安全に」作る必要がある場合は
トランザクションをサポートしたPostgreSQL(もちろんフリー)の使用をお薦めします。
ただしこちらはDB初期化処理などを含め、少し難易度が高いかもしれません。

アクセスカウンターを作る

あまりに簡単な例で申し訳ないですが、これが出来れば後はそんなに心配いりません。
何事も基本が大事です。
と、その前に。使用するデータベースとテーブルを先に作っておきましょう。
今回は、MySQLに始めから存在するtestデータベースを使用します。
ここにcounterテーブルを作るためのSQL文は以下の通りです。

CREATE TABLE counter (count INTEGER);
INSERT INTO counter (count) VALUES (0);

簡単ですね。テーブルを作成し、初期化レコードを1件挿入しています。
それでは早速、eRubyでプログラムを作りましょう。

<html>
<body>

<%
require 'mysql'
sql = Mysql.new("localhost", "mysqluser", "mysqlpasswd", "test")
res = sql.query('select count from counter')
cnt = res.fetch_row[0].to_i
cnt += 1
sql.query "update counter set count=#{cnt}"
puts cnt
%>

</body>
</html>

実にシンプルですね。では、解説です。

・データベースとの接続
何はなくとも、データベースと接続しなければ始まりません。
sql = Mysql.new(ホスト名, ユーザー名, パスワード, データベース名)
他にもいくつか接続方法はありますが、
上に書いたのが最もよく使われるであろうやり方です。
各パラメータは、お使いの環境に応じて変えてみて下さい。
以下、データベース関連のアクセスは全て変数sqlを通して行います。
あ、そうそう。先頭のrequireも忘れずに。
MySQL/Rubyのインストールが正しく行われていないと
このrequire文のところでエラーが発生します。

・SQLの発行
データベースと接続したら、早速SQL文を発行してみましょう。
res = sql.query(SQL文)
これで、結果が変数resに代入されます。
ここでは検索結果は1件だけと予めわかっているのでfetch_rowを使って結果を取得しています。
[0]というのはフィールドの最初の要素であることを表します。
例えば、「select a,b,c ...」の結果ならばfetch_row[0]がaを、fetch_row[1]がbを表します。
フィールド名で指定したい場合は、fetch_hashを使います。
res.fetch_hash['count']のように直接フィールド名を書けるので通常はこちらの方がよく使われるかもしれません。

・数値への変換
一つ注意があります。データベースから受け取った値は
「たとえフィールド型が数値型でも全て文字列型で返される」ということです。
よって、このままでは演算が出来ません。まず、数値型に変換する必要があります。
幸い、変換処理は非常に簡単です。to_iメソッドを適用すれば、文字列→数値への変換が行われます。

・文字列中の式展開
文字列中に変数の値を埋め込みたい場合、#{変数名}という形を使います。
上の例でいえば"update ..."の部分がそうです。
なお、式展開を使わない形で置き換えると
"update counter set count=" + cnt
となります。
この二つの方法はどちらが良いとも言えません。好みに応じて使い分ければ良いでしょう。

プログラムの流れは簡単ですね。
テーブルから1レコードを読み取り、値に1を足して元のレコードを置き換えています。
最後に、画面にカウント値を表示します。
リロードする度に表示される数字が増えていれば成功です。