pre Ruby 用の sqlite3-ruby パッケージを利用して Ruby から SQLite バージョン 3 を使う

Ruby 用の sqlite3-ruby パッケージを利用して Ruby から SQLite バージョン 3 を使う

Ruby 言語を使い,リレーショナルデータベースを扱うプログラムを簡単に書くことが出来ます.

このページでは,組み込み型のリレーショナルデータベース管理システム SQLite 3 を使うことにする.

SQL を用いたテーブル定義については,「リレーショナルデータベースのデータ構造と一貫性制約の Web ページで詳しく説明している.

SQLite 3の SQL に関する詳しい説明は:

前準備

必要となるソフトウェア

次のソフトウェアのインストールが済んでいること.「Ruby プログラミング」の Web ページを参考にしてください.

あらかじめ決めておく事項

使用する SQLite 3のデータベースのデータベースファイル名を決めておくこと. このページでは,次のように書く.Ruby の流儀で,Windows の場合は「\」のことを「\\」と書く.

SQL を用いたテーブル定義と

Ruby プログラムの中に SQL プログラムを埋め込み,SQLite 3 上で動かします. Ruby 用の sqlite3-ruby パッケージを使うことにします.JRuby では sqlite3-ruby パッケージは動かない (2009/11 時点) みたいなので,JRuby を使いたい人は,この Web ページを参考にしないこと.

テーブル定義の要点

ここでは,Rails の流儀に習って, テーブルには「id」という名前が付いた属性 を含ることにします.また id のデータ型は「integer primary key autoincrement not null」に設定します.

テーブル定義の SQL は次の通りです.

create table products (
    id            INTEGER  PRIMARY KEY autoincrement not null,
    product_name  TEXT     UNIQUE not null,
    type          TEXT     not null,
    cost          real,
    created_at    DATETIME not null );

テーブルへの行の挿入の要点

products テーブルを作る.

89.xls

Ruby でプログラムを作るときの要点は:

テーブルへの行の挿入の SQL は次の通りです.

insert into products values( 1, 'Fukuoka apple',     'apple',  50, datetime('now', 'localtime') );
insert into products values( 2, 'Kumamoto orange L', 'orange', 30, datetime('now', 'localtime') );
insert into products values( 3, 'Kumamoto orange M', 'orange', 20, datetime('now', 'localtime') );
insert into products values( 4, 'Fukuoka melon',     'melon',  NULL, datetime('now', 'localtime') );

プログラムの例

Ruby のプログラムは次のようになる.

#! ruby -Ks
# coding: windows-31j

require 'pp'
require 'rubygems'
require 'sqlite3'

# SQLite 3 のデータベースファイル名を DBNAME に設定してください.
# Windows の場合. 「\\」で区切る
# DBNAME = "C:\\SQLite\\testdb"
# Linux の場合
DBNAME = "/var/SQLite/testdb"
DBDIR = File.dirname( DBNAME )
DBBASENAME = File.basename( DBNAME )

# データベースオープン
Dir.chdir( File.dirname( File.expand_path( DBNAME ) ) )
db = SQLite 3::Database.new( DBNAME )

# SQL を用いた products テーブルの定義
sql = <<SQL
create table products (
    id            INTEGER  PRIMARY KEY autoincrement not null,
    product_name  TEXT     UNIQUE not null,
    type          TEXT     not null,
    cost          real,
    created_at    DATETIME not null );
SQL
db.execute(sql)

# SQL を用いた行の挿入
sql = <<SQL
insert into products values( 1, 'Fukuoka apple',     'apple',  50, datetime('now', 'localtime') );
insert into products values( 2, 'Kumamoto orange L', 'orange', 30, datetime('now', 'localtime') );
insert into products values( 3, 'Kumamoto orange M', 'orange', 20, datetime('now', 'localtime') );
insert into products values( 4, 'Fukuoka melon',     'melon',  NULL, datetime('now', 'localtime') );
SQL
# db.execute_batch(...) は複数の SQL をi度に実行するためのもの
db.transaction do |db| db.execute_batch( sql ) end

# 問い合わせの例 (確認のため全ての行を表示)
sql = <<SQL
SELECT * FROM products;
SQL
# db.execute(...) do |row| ... end は,結果が複数の行になるときの決まり文句
db.execute(sql) do |row|
    p row
end

【実行結果の例】

require 'rexml/document' require 'rexml/validation/relaxng' require 'rexml/parsers/sax2parser' # Ruby 1.8.6のREXMLのバリデータはXML文書の空白の扱いがまずいので、簡単にラップする。 class WrapValidator def initialize v @validator = v end def receive event return if event[0] == :text && event[1].strip == "" @validator.receive event end end # RELAX NG validator = REXML::Validation::RelaxNG.new < RELAXNG wrapper = WrapValidator.new validator # XML文書を用意する。 source = < John Smith js@example.com js@example.com John Smith js@example.com John Smith js@example.com XML # SAX2パーサ parser = REXML::Parsers::SAX2Parser.new source parser.add_listener wrapper # パース parser.parse
#! ruby -Ks # coding: windows-31j require 'pp' require 'rubygems' require 'sqlite3' # SQLite 3 のデータベースファイル名を DBNAME に設定してください. # Windows の場合. 「\\」で区切る # DBNAME = "C:\\SQLite\\testdb" # Linux の場合 DBNAME = "/var/SQLite/testdb" DBDIR = File.dirname( DBNAME ) DBBASENAME = File.basename( DBNAME ) # データベースオープン Dir.chdir( File.dirname( File.expand_path( DBNAME ) ) ) db = SQLite 3::Database.new( DBNAME ) # SQL を用いた products テーブルの定義 sql = <', 'test', NULL, datetime('now', 'localtime') ); insert into products values( 6, 'test record \x97''', 'test', NULL, datetime('now', 'localtime') ); insert into products values( 7, 'テストレコード 表 予 ‖〜−¢£¬|①②〒', 'test', NULL, datetime('now', 'localtime') ); SQL # db.transaction do |db| db.execute( "insert into products values( 1, :procuct_name, 'apple', 50, datetime('now', 'localtime') )", "Fukuoka apple" ) end # 問い合わせの例 (確認のため全ての行を表示) sql = <