SQLiteことはじめ

世間ではよく使われている SQLite ですが、自分は使う機会がなかったので、勉強してみました。お手軽なデータベースとしては非常によさそうです。

文字コード

VineLinux は、デフォルトの文字コードEUC です。Template::Toolkit や SQLitesubversionTrac を使うには UTF-8 のほうが便利なので、「/etc/sysconfig/i18n」を修正します。他に PoderosaTeraterm 改のように UTF-8 を扱えるターミナルが必要です。

LANG="ja_JP.UTF-8"
SUPPORTED="ja_JP.UTF-8:ja_JP.eucJP:ja_JP:ja"
SYSFONT="lat0-sun16"
SYSFONTACM="8859-15"

インストール

sqlite 本体と Perl 用のデータベースドライバ(DBD::SQLite)、O/Rマッパー(Class::DBIClass::DBI::SQLite)をインストールします。VineLinux では sqlite だけだと古いバージョンがインストールされるので、最新版の sqlite3 を指定します。

# cpan DBI
# cpan Class::DBI
# apt-get install sqlite3 sqlite3-devel
# cpan DBD::SQLite
# cpan Class::DBI::SQLite

test.sql

とりあえず1個テーブルを作ってみましょう。ちなみに id を「integer primary key」型にしておくと、INSERT 時に id を指定しなければオートインクリメントしてくれます。

BEGIN TRANSACTION;
CREATE TABLE user (id integer primary key, name text);
INSERT INTO "user"(name) VALUES('hogehoge');
INSERT INTO "user"(name) VALUES('fugafuga');
INSERT INTO "user"(name) VALUES('もげもげ');
COMMIT;

データベース作成

sqlite3 は psql や sqlplus のような対話的コンソールです。引数にデータベースファイル名を取ります。引数に指定されたデータベースファイル名が存在しなかったときは新たに作ってくれます。

sqlite3 test.db
sqlite3 test.db < test.sql

Perl でテスト

早速ユーザー一覧を表示してみましょう。

#!/usr/bin/perl

package Test::User;

use strict;
use Data::Dumper;
use base qw(Class::DBI);
use base qw(Class::DBI::SQLite);

__PACKAGE__->set_db('test', 'dbi:SQLite:dbname=test.db', 'shimizu', 'hogehoge');
__PACKAGE__->set_up_table('user');

1;

# 全件検索
my @users = Test::User->retrieve_all();

# 一件ずつ表示
foreach my $user (@users) {
    $user->_as_hash();
    print Dumper $user;
}

C言語でテスト

文字コードUTF-8 で保存すれば、日本語も何の問題もなく格納できるようです。こんな簡単に使えるのか・・。便利だなぁ・・。

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>

#define INSERT_COUNT 1000

int main(int argc, char *argv[]) {
    sqlite3 *db;
    char *errmsg;
    int i;

    /* SQLite データベースを OPEN */
    sqlite3_open("test.db", &db);
    if (!db) {
        printf("%s: %s\n", argv[0], errmsg);
        exit(-1);
    }

    /* BEGIN TRANSACTION */
    (void)sqlite3_exec(db, "BEGIN", NULL, NULL, &errmsg);

    /* CREATE TABLE */
    {
        char *sql;
        sql = sqlite3_mprintf("CREATE TABLE user (id integer primary key, name text)");
        (void)sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    }

    /* INSERT */
    for (i = 0; i < INSERT_COUNT; i++) {
        char *sql;
        sql = sqlite3_mprintf("INSERT INTO user (name) VALUES ('%s')", "ほげほげ");
        (void)sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    }

    /* COMMIT TRANSACTION */
    (void)sqlite3_exec(db, "COMMIT", NULL, NULL, &errmsg);

    sqlite3_close(db);
}
gcc -lsqlite3 -o instest instest.c
./instest