SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

SQLiteで組み込みDB体験(2007年版)

組み込みDB:SQLiteをVisual C++ 2005 Express Edition で使う

  • X ポスト
  • このエントリーをはてなブックマークに追加

step-4:Unicode版サンプル

 追加したsqlite_exec16が正しく動作するか、「sample.cpp」をUTF-16に書き換えて試運転を行います。ソリューションにコンソール・アプリケーション・プロジェクト「sample16」を追加し、step-2と同様に依存関係とインクルードパスを設定します。

 ソースコード「sampe16.cpp」を追加し、「sample.cpp」のナカミをコピーして次のように手を加えます。以下は呼び出す関数sqlite3_xxxを適宜 sqlite3_xxx16に置き換え、文字列リテラルの先頭にUnicodeであることを示すL を付加したものです。

sample16.cpp
#include <sqlite3.h>
#include <iostream>
#include <locale>
#include <cassert>

/*
 * sqlite3_exec から呼ばれるコールバック
 * カラム名と値を出力する
 */
int callback(void* arg, int columns, wchar_t** value, wchar_t** name) {
  std::wostream* stream = static_cast<std::wostream*>(arg);
  for ( int i = 0; i < columns; ++i ) {
    *stream << L'[' << name[i] << L'=' << value[i] << L"] ";
  }
  *stream << std::endl;
  return 0;
}

int main() {
  std::locale loc("japanese");
  std::wcout.imbue(loc);
  std::wcerr.imbue(loc);

  sqlite3* db;
  /*
  ** databaseをオープン。
  ** ファイル名を ":memory:" とすれば、on-memory データベースとなる。
  */
  int result;
  result = sqlite3_open16(L":memory:", &db);
  assert(result==SQLITE_OK);

  /*
  ** TABLE を生成する。
  ** sqlite_exec の結果が SQLITE_OK でないとき、
  ** エラーメッセージが errmsg に返される。
  ** このエラーメッセージは sqlite_free で解放すべし。
  */
  wchar_t* errmsg;
  if ( sqlite3_exec16(db,
                    L"CREATE TABLE IF NOT EXISTS わんくま (
                                               ID INTEGER PRIMARY KEY, 
                                               名前 TEXT, 
                                               地域 TEXT)",
                     0, 0, &errmsg) != SQLITE_OK ) {
    std::wcerr << errmsg << std::endl;
    sqlite3_free(errmsg);
    sqlite3_close(db);
    return 1;
  }

  /*
  ** レコードを追加する。
  ** sqlite3_prepare によってSQL文をコンパイル。
  ** SQL文中の ? の箇所に sqlite3_bind_xxxx で
  ** 値をバインド(差し込み)する。
  */
  sqlite3_stmt* statement;
  sqlite3_prepare16(db, 
                 L"INSERT INTO わんくま (名前, 地域) VALUES ( ?, ? )", 
                 -1, 
                 &statement, 
                 NULL);
  const wchar_t* data[] = {
    L"επιστημη", L"横浜",
    L"えムナウ",         L"東京",
    L"中",               L"大阪",
    L"じゃんぬ",         L"名古屋",
    L"なおこ(・∀・)",   L"東京",
    0,                   0
  };
  /*
  ** 値のバインドと実行。
  ** sqlite3_reset のに続いて sqlite3_bind_xxx によってバインドする。
  ** このとき最初の ? はインデクス 1 であることに留意すべし。
  ** 引き続いて sqlite3_step によって実行される。
  ** 一連の実行の後、sqlite3_finalize すること。
  */
  for ( const wchar_t** p = data; *p != 0;) {
    sqlite3_reset(statement);
    sqlite3_bind_text16(statement, 1, *p, -1, SQLITE_STATIC); ++p;
    sqlite3_bind_text16(statement, 2, *p, -1, SQLITE_STATIC); ++p;
    sqlite3_step(statement);
  }
  sqlite3_finalize(statement);

  /*
  ** QUERY を行う。
  ** sqlite3_exec の結果がコールバック関数に引き渡される
  */
  result = sqlite3_exec16(db, 
                          L"SELECT * FROM わんくま", 
                          callback, 
                          &std::wcout, 
                          &errmsg);
  assert( result == SQLITE_OK );

  /*
  ** databaseをクローズする。
  */
  sqlite3_close(db);
  return 0;
}

 コンパイルして実行しましょう。正しい出力が得られたでしょうか。

sample16.cpp実行結果
sample16.cpp実行結果

まとめ

 以上駆け足でSQLiteのビルドとUTF-16(Unicode)化パッチ(?)の手順について解説しました。後半のUTF-16化はあるタクラミの伏線となっています。

 SQLiteはお手軽軽量なDBとしてさまざまなアプリケーションに使えるものと思います。このお手軽さを享受できるのがC/C++だけではもったいない。C++/CLIで薄いラッパーを被せれば、C#やVB.NETから使えるようにできるはずですが、そのお話はまたいずれ。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1252 2007/05/07 08:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング