Railsで、ActiveRecordは使わないけど database.ymlを使う
諸般の事情で ActiveRecordを使わず SQLでデータベースにアクセスする場合 DBIを使うことになると思うが、データベースの接続設定くらいは database.ymlを参照したい。
というわけで、下記のような Moduleを ApplicationControllerに Mix-inしてやることにした。
アクションメソッドの中からはこんな風に使う
DBI::DatabaseHandleについての詳しい情報が何故かネット上で見つけにくいので、ついでにメモしておく。
stmtは SQL文、bindvarsはバインド変数(可変長引数)。プレースホルダは ? 文字。
do( stmt, *bindvars )
SQLを実行し、処理された行数を返す。insertとかupdateに使う。
select_one( stmt, *bindvars )
SQLを実行し、結果セットの1行目を示す DBI::Rowを返す。結果が一行しか返らないことがわかっている select文向き。
select_all( stmt, *bindvars )
SQLを実行し、DBI::Rowの Arrayを返す。それほど多くない行数の結果を返す select文向き。
execute( stmt, *bindvars ) {|statement_handle| aBlock}
SQLを実行し、ハンドル(DBI::StatementHandle)を持ってコードブロックを実行する。多くの行を返す select文向き。
DBI::StatementHandleは each {|row| aBlock } で1行ずつrowをfetchしてコードブロックを実行。
参考文献: DBI Interface Specification Version 0.2.2 (Draft)
というわけで、下記のような Moduleを ApplicationControllerに Mix-inしてやることにした。
require 'yaml'
require 'dbi'
module WithDBI
@@dbconfig =
YAML::load(File.open("#{RAILS_ROOT}/config/database.yml"))[RAILS_ENV]
@@drivernames = {
"postgresql"=>"Pg",
"mysql"=>"Mysql",
"oci"=>"OCI8"
} # ActiveRecordのadapterと DBIのドライバ名を対応づけるマップ
def with_dbi
dbname = @@dbconfig["database"]
username = @@dbconfig["username"]
password = @@dbconfig["password"]
host = @@dbconfig["host"]
adapter = @@dbconfig["adapter"]
# encodingを処理する方法不明...多分DBIでは吸収されずDBMS依存
connstr = "DBI:" + @@drivernames[adapter] + ":" + dbname
if host != nil then
connstr += ":" + host
end
DBI.connect(connstr, username, password) {|dbh|
dbh['AutoCommit'] = false
dbh.transaction {|dbh|
yield dbh
}
}
end
end
アクションメソッドの中からはこんな風に使う
def list
with_dbi { |dbh| # DBI::DatabaseHandle
@results = dbh.select_all("select id,name from people")
# @resultsには DBI::Rowの Arrayが入る
}
end
DBI::DatabaseHandleについての詳しい情報が何故かネット上で見つけにくいので、ついでにメモしておく。
stmtは SQL文、bindvarsはバインド変数(可変長引数)。プレースホルダは ? 文字。
do( stmt, *bindvars )
SQLを実行し、処理された行数を返す。insertとかupdateに使う。
select_one( stmt, *bindvars )
SQLを実行し、結果セットの1行目を示す DBI::Rowを返す。結果が一行しか返らないことがわかっている select文向き。
select_all( stmt, *bindvars )
SQLを実行し、DBI::Rowの Arrayを返す。それほど多くない行数の結果を返す select文向き。
execute( stmt, *bindvars ) {|statement_handle| aBlock}
SQLを実行し、ハンドル(DBI::StatementHandle)を持ってコードブロックを実行する。多くの行を返す select文向き。
DBI::StatementHandleは each {|row| aBlock } で1行ずつrowをfetchしてコードブロックを実行。
参考文献: DBI Interface Specification Version 0.2.2 (Draft)
ラベル: Rails

0 件のコメント:
コメントを投稿
<< ホーム