トップ «前の日記(2009年07月10日) 最新 次の日記(2009年07月14日)» 編集

Masa's blog

検索キーワード:

2009年07月11日 ruby(1.8.x)儂(わし)的解釈によるメモ(DBI + MySQL編) [長年日記]

_ ruby(1.8.x)儂(わし)的解釈によるメモ(DBI + MySQL編)

rubyからDBMS(MySQL)にDBI経由で接続してみる。例によって用語、用法等は思い込みである部分が見受けられると思うが、御容赦願う。

準備

dbi-0.4.1.tar.gzを取得する(http://rubyforge.org/frs/?group_id=234)。

# tar xvzf dbi-0.4.1.tar.gz
# cd dbi-0.4.1/
# gem install dbi
# gem install dbd-mysql

もし上記でdbiがうまくインストール出来なかった場合は、

# ruby setup.rb config
# ruby setup.rb setup
# ruby setup.rb install

を試してみるとよいかも...。

サンプルプログラム

#! /usr/bin/ruby
#
require 'rubygems'
require 'dbi'
#
# データベースへの接続
#
dbh = DBI.connect('DBI:Mysql:dbitestdb', 'm-ito', 'USER-PASSWORD')
puts("データベース(dbitestdb)に接続しました。")
#
# 文字コードの設定(MySQL依存)
#
dbh.do('SET NAMES ujis')
puts("日本語文字コードをujisに設定しました(MySQL依存設定)。")
#
# 自動コミットの停止
#
##dbh.do('SET AutoCommit = 0')
dbh['AutoCommit'] = false
puts("自動コミット停止しました(トランザクションの開始)。")
#
# トランザクション(1)
#
dbh.transaction {|dbh|
#
# テーブルの削除
#
	begin
		sql = <<SQL
			drop table member
SQL
		dbh.do(sql)
		puts "テーブルの削除に成功しました。"
	rescue => e
		puts "テーブルの削除に失敗しました(#{e.to_s})。"
	end
#
# テーブルの作成(engine = innodbによるストレージエンジンの
#                指定はMySQL依存機能)
#
	begin
		sql = <<SQL
			create table member (
				id INT PRIMARY KEY,
				name VARCHAR(50),
				job VARCHAR(50)
			) engine = innodb
SQL
		dbh.do(sql)
		puts "テーブルの作成に成功しました。"
	rescue => e
		puts "テーブルの作成に失敗しました(#{e.to_s})。"
	end
#
# わざと2重にテーブルを作成してみる
#
	begin
		sql = <<SQL
			create table member (
				id INT PRIMARY KEY,
				name VARCHAR(50),
				job VARCHAR(50)
			)
SQL
		dbh.do(sql)
		puts "テーブルの作成に成功しました(2)。"
	rescue => e
		puts "テーブルの作成に失敗しました(2)(#{e.to_s})。"
	end
#
# インデックスの作成
#
	sql = <<SQL
		create index i_member_name on member(name)
SQL
	dbh.do(sql)
	puts "インデックスの作成に成功しました。"
}
#
# トランザクション(2)
#
dbh.transaction {|dbh|
#
# データの追加
#
	sql = <<SQL
		insert into member (id, name, job) values (?, ?, ?)
SQL
	sth = dbh.prepare(sql)
	sth.execute(1, '伊藤 太郎', 'サラリーマン')
	puts "インサートに成功しました。"
	sth.execute(2, '山田 太郎', '野球選手')
	puts "インサートに成功しました。"
	sth.execute(3, '山田 花子', 'タレント')
	puts "インサートに成功しました。"
#
# わざと2重キーで登録してみる
#
	begin
		sth.execute(3, '山田 花子', 'タレント')
		puts "インサートに成功しました。"
	rescue => e
		puts "インサートに失敗しました(#{e.to_s})。"
	end
	sth.finish
}
#
# データの検索
#
sql = <<SQL
	select * from member where id >= ?
SQL
sth = dbh.prepare(sql)
sth.execute(1)
while (row = sth.fetch)
	puts "セレクトに成功しました(id=#{row['id']})(name=#{row['name']})(job=#{row['job']})"
end
sth.finish
#
# トランザクション(3)
#
dbh.transaction {|dbh|
#
# データの更新
#
	sql = <<SQL
		update member set job = ? where name = ?
SQL
	sth = dbh.prepare(sql)
	sth.execute('裁判官', '山田 太郎')
	puts ("アップデートに成功しました。")
	sth.finish
}
#
# 更新結果の確認
#
sql = <<SQL
	select * from member where name = ?
SQL
sth = dbh.prepare(sql)
sth.execute('山田 太郎')
while (row = sth.fetch)
	puts "アップデートの確認(id=#{row['id']})(name=#{row['name']})(job=#{row['job']})"
end
sth.finish
#
# トランザクション(4)
#
dbh.transaction {|dbh|
#
# データの削除
#
	sql = <<SQL
		delete from member where name like ?
SQL
	sth = dbh.prepare(sql)
	sth.execute('山田%')
	puts ("デリートに成功しました。")
	sth.finish
}
#
# 削除の確認
#
sql = <<SQL
	select * from member
SQL
sth = dbh.prepare(sql)
sth.execute()
while (row = sth.fetch)
	puts "デリートの確認(id=#{row['id']})(name=#{row['name']})(job=#{row['job']})"
end
sth.finish
#
# メタデータの取得
#
sql = <<SQL
	select * from member
SQL
sth = dbh.prepare(sql)
sth.execute()
puts "メタデータ カラム数=#{sth.column_names.size}"
print "メタデータ カラム名="
sth.column_names.each {|name|
	print "#{name}\t"
}
puts ""
#
sth.column_info.each_with_index {|info, i|
        print "項番 = #{i} / "
        print "カラム名 = #{info.name} / "
        print "精度 = #{info.precision} / "
        print "スケール = #{info.scale}\n"
}
sth.finish
#
# (手動で)のコミット(またはロールバック)の実行
#
#dbh.rollback
#puts "ロールバックしました。"
dbh.commit
puts "コミットしました。"
#
# データベースからの切断
#
dbh.disconnect
puts("データベース(dbitestdb)から切断しました。")

実行結果

データベース(dbitestdb)に接続しました。
日本語文字コードをujisに設定しました(MySQL依存設定)。
自動コミット停止しました(トランザクションの開始)。
テーブルの削除に成功しました。
テーブルの作成に成功しました。
テーブルの作成に失敗しました(2)(Table 'member' already exists)。
インデックスの作成に成功しました。
インサートに成功しました。
インサートに成功しました。
インサートに成功しました。
インサートに失敗しました(Duplicate entry '3' for key 1)。
セレクトに成功しました(id=1)(name=伊藤 太郎)(job=サラリーマン)
セレクトに成功しました(id=2)(name=山田 太郎)(job=野球選手)
セレクトに成功しました(id=3)(name=山田 花子)(job=タレント)
アップデートに成功しました。
アップデートの確認(id=2)(name=山田 太郎)(job=裁判官)
デリートに成功しました。
デリートの確認(id=1)(name=伊藤 太郎)(job=サラリーマン)
メタデータ カラム数=3
メタデータ カラム名=id  name    job
項番 = 0 / カラム名 = id / 精度 = 11 / スケール = 0
項番 = 1 / カラム名 = name / 精度 = 150 / スケール = 0
項番 = 2 / カラム名 = job / 精度 = 150 / スケール = 0
コミットしました。
データベース(dbitestdb)から切断しました。

_ googleearth on Libretto U100(Slackware-12.2)

googleearthを入れてみた。十分な速度で動いてくれた。ただし、日本語メニューが化けている。

どうやらパッケージに同梱されている libQt*.so.4 が国際化対応でビルドされた物ではないようだ。そこで qt-x11-opensource-src-4.5.2.tar.gzを取得して ./configure && make && make install でインストールし、 /etc/ld.so.conf に /usr/local/Trolltech/Qt-4.5.2/lib を追加して ldconfig した後、念のために ~/google-earth/配下にある、

$ ls -al google-earth/libQt*
-rwxr-xr-x 1 m-ito m-ito 2244156 2009-07-09 20:38 google-earth/libQtCore.so.4
-rwxr-xr-x 1 m-ito m-ito 7305864 2009-07-09 20:38 google-earth/libQtGui.so.4
-rwxr-xr-x 1 m-ito m-ito  774340 2009-07-09 20:38 google-earth/libQtNetwork.so.4
-rwxr-xr-x 1 m-ito m-ito 7265852 2009-07-09 20:38 google-earth/libQtWebKit.so.4

を削除するなり、リネームするなりして参照されないようにする。

これで無事、日本語メニューも出るようになった。