#include <sqlite3.h>
#include <vcclr.h>

int callback(void* option, int count, wchar_t** values, wchar_t** names) {
  for ( int i = 0; i < count; ++i ) {
    System::Console::Write("{0} = [{1}] ", 
                           gcnew System::String(names[i]), 
                           gcnew System::String(values[i]));
  }
  System::Console::WriteLine();
  return 0;
}

int main() {

  sqlite3* db;
  if ( sqlite3_open16(L":memory:", &db) ) {
    System::Console::Error->WriteLine("Error : Can't open database : {0}", 
      gcnew System::String(static_cast<const wchar_t*>(sqlite3_errmsg16(db)))); 
    sqlite3_close(db);
    return 1;
  }

  array<System::String^>^ statements = {
    "CREATE TABLE item (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price REAL NOT NULL)", 
    "INSERT INTO item VALUES ( 1, 'ばなな', 123)", 
    "INSERT INTO item VALUES ( 2, 'りんご', 234)", 
    "INSERT INTO item VALUES ( 3, 'みかん', 345)", 
    "INSERT INTO item VALUES ( 4, 'なし',   456)", 
    "INSERT INTO item VALUES ( 5, 'もも',   567)", 

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

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

  for each ( System::String^ statement in statements ) {
    wchar_t * errmsg;
    System::Console::WriteLine(statement);
    pin_ptr<wchar_t> pin = &statement->ToCharArray()[0];
    if ( sqlite3_exec16(db, pin, callback, 0, &errmsg) != SQLITE_OK ) {
      System::Console::Error->WriteLine("Error : {0}", gcnew System::String(errmsg));
      sqlite3_free(reinterpret_cast<char*>(errmsg));
      sqlite3_close(db);
      return 1;
    }
  }
  sqlite3_close(db);

  return 0;
}

struct sqlite3 {}; /* dirty workaround to suppress warning :LNK4248 */
