/*
 * Oblaat.h
 * SQLite .NET‚Ì‚½‚ß‚Ì”–”ç
 */
#ifndef OBLAAT_H__
#define OBLAAT_H__

#include <sqlite3.h>

using namespace System;

namespace Oblaat {

  namespace SQLite3 {

    public enum class Result : int { 
      OK         = SQLITE_OK,
      ERROR      = SQLITE_ERROR,
      INTERNAL   = SQLITE_INTERNAL,
      PERM       = SQLITE_PERM,
      ABORT      = SQLITE_ABORT,
      BUSY       = SQLITE_BUSY,
      LOCKED     = SQLITE_LOCKED,
      NOMEM      = SQLITE_NOMEM,
      READONLY   = SQLITE_READONLY,
      INTERRUPT  = SQLITE_INTERRUPT,
      IOERR      = SQLITE_IOERR,
      CORRUPT    = SQLITE_CORRUPT,
      NOTFOUND   = SQLITE_NOTFOUND,
      FULL       = SQLITE_FULL,
      CANTOPEN   = SQLITE_CANTOPEN,
      PROTOCOL   = SQLITE_PROTOCOL,
      EMPTY      = SQLITE_EMPTY,
      SCHEMA     = SQLITE_SCHEMA,
      TOOBIG     = SQLITE_TOOBIG,
      CONSTRAINT = SQLITE_CONSTRAINT,
      MISMATCH   = SQLITE_MISMATCH,
      MISUSE     = SQLITE_MISUSE,
      NOLFS      = SQLITE_NOLFS,
      AUTH       = SQLITE_AUTH,
      FORMAT     = SQLITE_FORMAT,
      RANGE      = SQLITE_RANGE,
      NOTADB     = SQLITE_NOTADB,
      ROW        = SQLITE_ROW,
      DONE       = SQLITE_DONE,
    };

    public enum class Type : int { 
      TYPE_INTEGER = SQLITE_INTEGER,
      TYPE_FLOAT   = SQLITE_FLOAT,
      TYPE_TEXT    = SQLITE_TEXT,
      TYPE_BLOB    = SQLITE_BLOB,
      TYPE_NULL    = SQLITE_NULL,
    };

    public value class NVPair {
    public:
      String^ name;
      String^ value;
      NVPair(const wchar_t* n, const wchar_t* v) {
        name  = gcnew String(n);
        value = gcnew String(v);
      }
    };

    public delegate bool Callback(System::Object^ option, array<NVPair^>^ results);

    public ref class Statement {
    internal:
      sqlite3_stmt* stmt_;
    public:
      Statement();
     ~Statement();
      Result reset();
      Result  bind_int(int col, int value);
      Result  bind_double(int col, double value);
      Result  bind_null(int col);
      Result  bind_text(int col, String^ value);
      int     column_int(int col);
      double  column_double(int col);
      String^ column_text(int col);
      Type    column_type(int col);
      Result  finalize();
      Result  step();
    };

    public ref class Database {
    private:
      sqlite3* db_;
    public:
              Database();
             ~Database();
      Result  open(System::String^ filename);
      Result  open(); // DB in memory
      Result  close();
      String^ errmsg();
      Result  exec(String^ sql, Callback^ callback, System::Object^ option, [System::Runtime::InteropServices::Out] String^% errmsg);
      Result  prepare(String^ sql, [System::Runtime::InteropServices::Out] Statement^% statement);
    };

  }
}

#endif
