2003年11月13日号

━━━━━━━━━━━━━━━━━━━━━ 2003.11.13 Vol.866 ━━━━━
 ■□■□■
 ■□■□■ 日刊「WEBのツボ!」
 □■□■□              http://www.soho-union.com/
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                             配信部数 xxxx部
「システムはオブジェクト指向 Ruby & Flash」(#008)   
                                                          福井修@Fsys

【○】本日のお題 【 実践編 】LoadVars連携での DB検索     ━━━━━━
 
11月も半ばで、落ち葉を見ると秋を感じます。本連載も8回目になり今回を入
れてあと3回です。

前回注1)【 実践編 】「LoadVars連携でのログイン認証」というテーマでWeb画
面からの入力で、サーバサイドのDBデータと照合し、画面遷移せずに部分更新
で応答が得られ、使い勝手が良いという例を示しました。

本日は、LoadVars連携での DB検索 というテーマでサーバサイド Ruby での
DB連携の説明を続けます。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ コンテンツはDBに
────────────────────────────────────
 MVCモデルでViewにFlashを採用しリッチクライアントを実現するのと両輪で、
MODELには、Rubyでの処理がエレガントですという話しをしてきました。注2)

Webでの情報の取り扱いで、表舞台の表示画面でリッチさを実装するにしても、
コンテンツを供給する舞台裏を支える仕掛けが、プアーであったり、扱いにくい
ものであっては、調和を欠きうまくゆきません。舞台裏もリッチに仕掛けたいと
ころです。

データを保持するのに、様々な方式があります。組織では様々な事情があります。

1.紙ベース
   まだまだ 紙やファックスが情報庫という現実は、あります。
   
2.テキストファイル
   旧来のオフコンシステムなどでは、まだまだ現役です。
   またPCの世界でも、異なるアプリケーションを受け渡す際には、CSVファイル
   などまだまだ大きな比重をもっています。
   Webの掲示板、グループウェアでもテキストベースのものも沢山あります。

3.アプリケーションの保存ファイル
   ExcelやWord などに、沢山データが保持されていることでしょう。
   年賀状ソフトの保存ファイルにも住所などが詰まっていますよね。

4.小規模データベース
   Access の .mdbファイルは、アプリケーションの保存ファイルとしての位置
   づけの側面もありますが、まあ業務データをそれなりに整理整頓して収納・
   利用する用途にも使われています。
   Accessは、個人的に使うオートバイのイメージです。沢山は乗れません。
   FileMakerもこの範疇です。熱いユーザがいらっしゃいます。

5.中大規模データベース
   用途や予算の規模、好みで、選択肢はいろいろあります。
  
   オラクル Oracle7/8/8i/9/
                  もう 10g の時代が訪れるようですが、実業務システム構築
                  の現場では新規導入でも Oracle9 の前の 8i をいまだに現
                  役で使っているケースもありですな。
                  大規模システムでは、お世話になっていました。
                  私には、ダンプカーのイメージがあります。
                  RubyOracleを使うには久保さんのライブラリがあります。
                  注6)

   マイクロソフト SQLServer/MSDE
                  SQLServer2000が長く続いています。次期バージョン(Yukon)
                  は、なかなか出ませんがどうなのでしょうね。
                  実は、私は仕事で使っています。

   IBM DB2 UDB
                  昔、汎用機で、使わせてもらいました。
                  私には、重機のイメージがあります。
                  私は、Rubyで使ったことはありませんがもちろん使えます。
                  注7)

   MySQL 3../4..  Windowsで簡単に使えるオープンソース(GPLライセンス)プロ
                  ダクツなので、人気があります。
                  私には、軽トラックのイメージがあります。
                  RubyMySQLは、すいすいです。注8)

   PostgreSQL 7.3.4/もうすぐ7.4   オープンソースプロダクツの雄でしょう。
                  私は、愛用させてもらっています。
                  まあ 普通乗用車、トラックのイメージです。
                  大規模向けもあります。注9)

Webサイト(イントラサイトでも)のデータストアには、テキストファイルもあ
りですが、デジタルコンテンツの量や型が、DBになじむのであればDBの出番
です。

押入に、ばらばらに荷物をつっこんでも、ある一定量を超えたら整理不能になり
ます。そのときは、棚やカートンを使って仕切って整理整頓する必要が出てくる
のと同じです。

DBも規模に応じて適材適所で使いましょう。コンビニへの買い物は、バイク
でも良いでしょうが、50人乗せるならバスが要ります。

「 システムとは、DBを使いこなすしかけである。 」 と言っておきます。

ワープロ表計算のファイルをハンドリングするだけでは、まだシステム以前で
DBを使って情報の一元管理に乗り出すあたりで「システム」になってくる感じ
ですね。

システムでは、業務をモデル化し、計算機内のプログラムで、データの処理を行
います。その記述が、複雑になるのか、簡潔明解になるのかで、開発コスト、管
理コストに差がでます。オブジェクト指向の道具をじょうずに使いこなすのが有
利ですが、そこは慣れないと難しい面もあります。ここは、使いやすい道具を選
ぶのが大事です。これは使ってみて、評価するのが一番です。

私は、C++を使って、Perlを使って、PHPを使って、Javaを使って、Rubyを使って、
その結果 Ruby がベストでした。

DBのハンドリングは、重要なポイントです。DB検索では、動的に複数レコー
ドを取り扱う訳ですが、そのような場面で、Rubyイテレータ機構は、実に強力
です。

また業務システムでは異常処理でのきめ細かい対応も不可欠ですが、言語仕様と
して「例外」を扱えると、コードは、ずいぶんすっきりし、見通しが良くなりま
す。RubyJavaでは「例外」が言語仕様に実装されています。 注4) 
実装されていなかったPHPでもPHP5 から例外処理ができるようになります。注5)

言語仕様の優劣は、結局品質に現れます。

日経バイト2002年10月号、11月号に、まつもとゆきひろ氏の「プログラミング言
語論」が連載されています。プログラミング言語の系統などが解説されていて、
勉強になります。人間の脳力には、制限があり、マシンの性能は、飛躍的にアッ
プしている訳で、人間に負担をかけるのでなく、人間にとって習得しやすく、使
いやすい(使って楽しい)言語が、新しい世代の言語であるとの指摘には共感し
ます。
                  
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ Ruby のDB連携 実装解説
────────────────────────────────────
サーバサイドでRubyのDB連携については、第6回【 実践編 】「サーバサイドで 
Ruby&PostgreSQL 連携」注3)で、少し説明しました。そこでは準備レベルの話し
でかなり費やしてしまいRubyでのDB連携の説明がほとんど出来ませんでしたの
で、今回そこを重点的に説明します。

前回の 郵便番号入力のリクエストでFlash ActionScript LoadVarsオブジェクト
のsendAndLoadメソッドを実行して呼び出されるRubyプログラム selPostal.rb
は、次のようになります。第6回の分から一部変更しています。

〜〜〜〜〜 ここから 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
#!/usr/local/bin/ruby -T -Ke
#-----------------------------------------------------------------------
=begin
=  selPostal.rb
郵便番号検索
=end
#-----------------------------------------------------------------------
# @version A00 2003/10/14 福井@Fsys (c)2003
# $Id: selPostal.rhtml,v 1.2 2003/11/12 06:59:22 fukui Exp $
#-----------------------------------------------------------------------
# 実行場所get
BaseDir = File.dirname(File.expand_path(__FILE__)).untaint
# Pathのうち最後を除く
basePath = File.dirname(BaseDir)
# ライブラリ検索用PATH追加
$LOAD_PATH.unshift basePath + '/lib'

# ライブラリ読み込み
require 'cgi'
require 'nkf'
require 'pgCon'

# cgiデータget
cgi = CGI.new

zipno   = cgi['zipno'][0].to_s

# 初期化
results = nil
out     = nil

# DB接続
db = DBConnection.new
db.connect

begin
  # 郵便番号から検索
  unless zipno.empty?
    results = db.query("select post_id,ken,si,tyou from postlist " \
                       "where  post_id ~ '#{zipno}' order by post_id ;")
    end
  end
  if results and results.size > 0
    results.each{ |record|
      post_id,ken,si,tyou = record
      out = ''
      out << post_id[0,3]
      out << '-'
      out << post_id[3,4]
      out << ' '
      out << ken
      out << ' '
      out << si
      out << ' '
      out << tyou if tyou
    }
  else
    out = "みつかりません(;_;)"
  end
rescue
  out = "DB検索でエラー"
end

# データの出力
print "Content-type: text/plain\n\n"
print "addr=#{NKF.nkf('-sZ',out)}"

〜〜〜〜〜 ここまで 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

ポイントとなるのは、まず次のSQL文の実行文です。
    results = db.query("select post_id,ken,si,tyou from postlist " \
                       "where  post_id ~ '#{zipno}' order by post_id ;")

   db は、DB接続のオブジェクトです。インスタンス生成し、コネクション
   を張っておきます。
   その dbオブジェクトに、queryメソッドを発行します。引数には、SQL文を
   渡します。Rubyでは、文字列を スペース\ で行をまたいでつなぐことが
   できます。また"(ダブルクォーテーション)で囲まれた文字列のなかで
   #{式} という表現で、式展開(実行結果の文字列を動的に得る)できます。

そして結果は、複数レコードの配列で、返るので、それをイテレータで、順次処
理する文です。
    results.each{ |record|
      post_id,ken,si,tyou = record
      out = ''
      out << post_id[0,3]
      out << '-'
      out << post_id[3,4]
      out << ' '
      out << ken
      out << ' '
      out << si
      out << ' '
      out << tyou if tyou
      log.puts out
    }

  resultsは、複数レコードが配列で返されるオブジェクトを指します。
  そのオブジェクトに対し、eachメソッドで{ }のブロックを繰り返し処理させ
  ます。
  { } 内で |変数| を指定すると、繰り返し毎にその変数に、逐次値(=オブジ
  ェクトが入ります。この場合は、1レコードの配列。(1レコード内には、
  複数のデータ項目があります。)
  
        post_id,ken,si,tyou = record

  の文では、多重代入と言いますが、右辺の配列の要素を、左辺のカンマで区切
  った変数に順番に代入してくれます。

      out << post_id[0,3]
      out << '-'
      out << post_id[3,4]

  郵便番号の上3桁とハイフンと下4桁を合成しています。
  もちろん 同様な処理は、様々な言語で、実装できます。

  私は Rubyの簡潔で豊富なメソッドを使うようになってからは、他の言語を使
  いたくなくなりました^^。
 

次回は【 応用編 】Ruby&Flash&PostgreSQL での 郵便番号検索 のテーマで、
さらに進んだ事例を紹介します。



━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
※ 注釈、資料、参考情報
────────────────────────────────────
注1) 「システムはオブジェクト指向 Ruby & Flash」(#007)
     http://www.melma.com/mag/02/m00020302/a00000651.html
注2) 「システムはオブジェクト指向 Ruby & Flash」(#005)
     http://www.melma.com/mag/02/m00020302/a00000631.html
注3) 「システムはオブジェクト指向 Ruby & Flash」(#006)
     http://www.melma.com/mag/02/m00020302/a00000641.html
注4) Ruby 例外
     http://www.namaraii.com/rubytips/?%CE%E3%B3%B0
     Javaの道:例外(はじめての例外)
     http://www2s.biglobe.ne.jp/~yuuki_ki/java_exception1.htm
注5) PHP5.0.0βを試してみる - 例外処理
     http://www.pat.hi-ho.ne.jp/dimension/php5/php5_exception.shtml
注6) Ruby/OCI8 (Oracle Call Interface)
     http://www.jiubao.org/ruby-oci8/index.ja.old.html
注7) Ruby/DBI 
     http://ruby-dbi.sourceforge.net/
注8) Rubyで作るデータベースCGI
     http://www.atmarkit.co.jp/flinux/rensai/mysql07/mysql07a.html
     MySQL - Ruby インタフェース
     http://www.tmtm.org/ja/mysql/ruby/
     大御所とみたまさひろ氏は、関西オープンソース+フリーウェア2003に
     来阪されていて RubyOFF会でご一緒しましたがなんと大学の後輩でした^^
注9) SRA、PowerGres の大規模システム向けパッケージを発表
     http://japan.internet.com/linuxtoday/20030808/3.html
     
【プロフィール】
福井 修 ( FUKUI Osamu )o-fukuiアットpo.iijnet.or.jp
福井システムリサーチ http://fsys.net/  主幹。システム構築歴27年。
システム構築エキスパート
日本リヌクス協会、神戸商工会議所情報処理学会 会員
関西ソーホ・デジタルコンテンツ事業協同組合デジタルハリウッド神戸校 Java講師