#include <iostream>
#include <sqlite3.h>
#include <locale>

int callback(void* option, int columnCount, wchar_t** columnValues, wchar_t** columnNames) {
  for ( int i = 0; i < columnCount; ++i ) {
    *static_cast<std::wostream*>(option) << columnNames[i] << L" = [" << columnValues[i] << L"] ";
  }
  std::wcout << std::endl;
  return 0;
}

int main() {
  std::wcout.imbue(std::locale("japanese"));
  sqlite3* db;
  if ( sqlite3_open16(L":memory:", &db) ) {
    std::cerr << "Error " << __FILE__ << ' ' << __LINE__ 
              << ": Can't open database " << sqlite3_errmsg(db) 
              << std::endl;
    sqlite3_close(db);
    return 1;
  }

  const wchar_t* statements[] = {
    L"CREATE TABLE item (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price REAL NOT NULL)", 
    L"INSERT INTO item VALUES ( 1 , 'ばなな', 123)", 
    L"INSERT INTO item VALUES ( 2 , 'りんご', 234)", 
    L"INSERT INTO item VALUES ( 3 , 'みかん', 345)", 
    L"INSERT INTO item VALUES ( 4 , 'なし',   456)", 
    L"INSERT INTO item VALUES ( 5 , 'もも',   567)", 
    L"INSERT INTO item VALUES ( 6 , 'びわ',   789)", 
    L"INSERT INTO item VALUES ( 7 , 'くり',   891)",

    L"CREATE TABLE sales (id INTEGER PRIMARY KEY, quantity NOT NULL )", 
    L"INSERT INTO sales VALUES ( 1, 6 )",
    L"INSERT INTO sales VALUES ( 3, 4 )",
    L"INSERT INTO sales VALUES ( 5, 2 )",

    L"SELECT item.id, name, price, quantity, price*quantity FROM item, sales WHERE item.id = sales.id ORDER BY price*quantity",

    L"CREATE VIEW named_sales AS SELECT name, quantity FROM sales, item WHERE item.id = sales.id",
    L"SELECT * FROM named_sales",
    0
  };
  for ( int i = 0; statements[i]; ++i ) {
    wchar_t* errmsg;
    std::wcout << statements[i] << std::endl;
    if ( sqlite3_exec16(db, statements[i], callback, &std::wcout, &errmsg) != SQLITE_OK ) {
      std::cerr << "Error " << __FILE__ << ' ' << __LINE__ 
                << ": " << errmsg << std::endl;
      sqlite3_free((char*)errmsg);
      sqlite3_close(db);
      return 1;
    }
  }
  
  return 0;
}

    