Debian lenny で Ruby から MySQL を使おうと思ってライブラリを探してみたら4つほど見つかった。

- MySQL/Ruby
- Ruby/MySQL
- Ruby/DBI - Direct database access layer for Ruby
- brianmario/mysql2 - GitHub

Debian lenny の パッケージを探してみたら、libdbd-mysql-ruby と libmysql-ruby ぐらい。
libmysql-ruby パッケージはどうやら MySQL/Ruby らしい。じゃあ、これで。


# uname -mvrs
Linux 2.6.26-2-amd64 #1 SMP Tue Jan 25 05:59:43 UTC 2011 x86_64
 
# ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux]
 
# aptitude search mysql | grep ruby
p   libdataobjects-mysql-ruby1.8    - MySQL adapter for libdataobjects-ruby1.8
p   libdbd-mysql-ruby               - Ruby/DBI driver for MySQL
p   libdbd-mysql-ruby1.8            - Ruby/DBI MySQL driver for Ruby 1.8
i   libmysql-ruby                   - MySQL module for Ruby
i   libmysql-ruby1.8                - MySQL module for Ruby 1.8
 
# aptitude install libmysql-ruby

libmysql-ruby1.8 がインストールされた。

メソッド名は C API の関数から mysql_ 接頭辞を除いたものと同じです。メソッドの使用方法も基本的に対応する C API 関数と同様ですので、詳細は MySQL のマニュアルを見てください。

MySQL/Ruby

MySQL/Rubyのクラス一覧。

クラス概要
MysqlMySQL を操作する
Mysql::Resultクエリ結果
Mysql::Field項目の詳細を表す
Mysql::Stmtプリペアドステートメントを扱う
Mysql::TimeMysql::Stmt で使う日時型(DATE, DATETIME, TIMESTAMP, TIME)
Mysql::ErrorMySQL のエラーが発生した場合に例外として生成

というわけで、ざっとサンプルコード。


#!/usr/bin/env ruby
$KCODE='u'
 
require 'mysql'
 
begin
  mysql = Mysql::new('localhost','username','password','databasename')
  mysql.query("select * from hogetable limit 10"){|res|
    # res is a instance of Mysql::Result
    res.each_hash(){|record|
      puts record['id']
      puts record['name']
      puts record.inspect
    }
  }
  mysql.close
rescue
  $stderr.puts $!.inspect
end

これはさっくり書けて便利。

そういえば、Timestamp型を使いたいんだった。

DATETIME型 / TIMESTAMP型

日付と時刻を文字列として指定する場合、'YYYY-MM-DD HH:MM:SS'が基本となるフォーマットですが、次のような指定方法も許可されています。

フォーマット 入力例
----------------------- -------------------------
'YYYY-MM-DD HH:MM:SS' '2009-10-04 15:25:07'
'YY-MM-DD HH:MM:SS' '09-10-04 15:25:07'
'YYYYMMDDHHMMSS' '20091004152507'
'YYMMDDHHMMSS' '091004152507'

(中略)

数値として指定することもできます。

フォーマット 入力例
----------------------- -------------------------
YYYYMMDDHHMMSS 20091004152507
YYMMDDHHMMSS 091004152507

日付型と時刻型 - MySQLのデータ型 - MySQLの使い方

こんな感じで書けるなんて便利。
MySQL monitor から。


mysql> select count(*) from cachedb where cachedtime < 20110416100000;
+----------+
| count(*) |
+----------+
|     2970 |
+----------+
1 row in set (0.09 sec)

以下、自前のキャッシュDBにある30日前とか1時間前のデータを削除するサンプルコード。
delete クエリーの結果が返ってこないみたいなので、select count(*) で処理前後のレコード数を取得するようにしてみた。
厳密な数じゃなくていいので他のプログラムから追加・削除された数は考慮しない。


#!/usr/bin/env ruby
$KCODE='u'
 
require 'mysql'
 
puts "start: #{Time.now}"
 
begin
  mysql = Mysql::new('localhost','username','password','databasename')
  # 件数をカウント
  count_query = "select count(*) from cachedb"
  mysql.query(count_query).each_hash(){|r| puts r.inspect }
  # レコードを削除
  #t = Time.now - (30 * 24 * 60 * 60) # 30日前
  t = Time.now - (1 * 60 * 60) # 1時間前
  delete_query = "delete from cachedb where cachedtime < #{t.strftime('%Y%m%d%H%M%S')}"
  puts "delete query: #{delete_query}"
  mysql.query(delete_query)
  # 件数をカウント
  mysql.query(count_query).each_hash(){|r| puts r.inspect }
  mysql.close
rescue
  $stderr.puts $!.inspect
end
 
puts "finished: #{Time.now}"

実行してみた結果。


$ ruby ./clear_cachedb.rb
start: Sat Apr 16 10:19:54 +0900 2011
{"count(*)"=>"2984"}
delete query: delete from cachedb where cachedtime < 20110416091954
{"count(*)"=>"2787"}
finished: Sat Apr 16 10:19:54 +0900 2011

Ref.
- MySQL/Ruby
- Debian -- lenny の libmysql-ruby1.8 パッケージに関する詳細
- MySQL :: Download Ruby MySQL modules
- [-*煙猴*-]: Ruby+MeCab+MySQLでスクリプト書いた
- 逆引きRuby - 日付と時刻
- [ヅラド] MySQLのテーブルから大量のデータを削除

tags: ruby mysql debian

Posted by NI-Lab. (@nilab)