boost with sqlite3

// -*- coding: utf-8-with-signature-dos -*-
//==============================================================================

#include <sqlite3.h>
#include <boost/format.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
#include <functional>

using boost::format;
using boost::bind;
using std::string;
using std::cout;
using std::endl;
using std::function;

template<typename F>
static int callback(void* self, int argc, char** argv, char** column_name)
{
    F& func = *(F*)self;
    func(argc, argv, column_name);
    return SQLITE_OK;
}

template<typename F>
static inline void exec(sqlite3* db, const string& command, F& func)
{
    char* errmsg = 0;
    if(sqlite3_exec(db, command.c_str(), &callback<F>, (void*)&func, &errmsg)){
        throw std::exception(errmsg);
    }
}
static inline void exec(sqlite3* db, const string& command)
{
    char* errmsg = 0;
    if(sqlite3_exec(db, command.c_str(), 0, 0, &errmsg)){
        throw std::exception(errmsg);
    }
}

class Hoge
{
public:
    void doit(int argc, char** argv, char** column_name)
    {
        cout << "[";
        for(int Li = 0; Li < argc; ++Li){
            cout << format("%s = %s, ") % column_name[Li] % argv[Li];
        }
        cout << "]" << endl;
    }
};

int main(int argc, char *argv[])
{
    sqlite3* db = 0;

    int hr = sqlite3_open(":memory:", &db);

    string create_sql = "CREATE TABLE sample ("
                        "  id     INTEGER PRIMARY KEY,"
                        "  worker TEXT NOT NULL,"
                        "  place  TEXT NOT NULL )";

    auto format_string = format("INSERT INTO sample (worker, place) values ('%s', '%s')");

    try {
        exec(db, create_sql);
        exec(db, (format_string % "john" % "newyork").str());
        exec(db, (format_string % "osamu" % "tokyo").str());
        exec(db, (format_string % "george" % "germany").str());

        Hoge hoge;
        exec(db, "SELECT place, worker, id FROM sample", bind(&Hoge::doit, &hoge, _1, _2, _3));
    }
    catch(const std::exception& ex){
        cout << ex.what() << endl;
    }

    sqlite3_close(db);

    return 0;
}

↑で↓こうなる

$ main.exe
[place = newyork, worker = john, id = 1, ]
[place = tokyo, worker = osamu, id = 2, ]
[place = germany, worker = george, id = 3, ]