/**
 * Sqliteクラス
 */
class Sqlite
{
	/**
	 * コンストラクタ
	 * @param database データベースファイル
	 * @param readonly 読み込み専用で開く
	 * ※読み込み専用時は吉里吉里のファイル機構が使われます。そうでない場合はOSの機構を使います。
	 */
	function Sqlite(database, readonly=false);

	/**
	 * SQLを実行する。
	 * @param sql 実行するSQL
	 * @param params sqlにバインドするパラメータ(配列または辞書)
	 * @param callback コールバック (引数にカラムが列挙されます)
	 * @return 成功なら true
	 */
	function exec(sql, params=void, callback=void);

	/**
	 * 値取得用にSQLを実行する。
	 * @param sql 実行するSQL
	 * @param params sqlにバインドするパラメータ(配列または辞書)
	 * @return 結果の第一カラム。エラーの場合は void
	 */
	function execValue(sql, params);

	/**
	 * トランザクションの開始
	 * @return 成功なら true
	 */
	function begin();

	/**
	 * トランザクションのコミット
	 * @return 成功なら true
	 */
	function commit();

	/**
	 * トランザクションのロールバック
	 * @return 成功なら true
	 */
	function rollback();

	/**
	 * 直前の挿入の行ID
	 */
	property lastInsertRowId;
	
	/**
	 * 直前のコマンド実行のエラーコード
	 */
	property errorCode;
	
	/**
	 * 直前のコマンド実行のエラーメッセージ
	 */
	property errorMessage;

	// エラーコード
	
	SQLITE_OK         =  0;   /* Successful result */
	SQLITE_ERROR      =  1;   /* SQL error or missing database */
	SQLITE_INTERNAL   =  2;   /* Internal logic error in SQLite */
	SQLITE_PERM       =  3;   /* Access permission denied */
	SQLITE_ABORT      =  4;   /* Callback routine requested an abort */
	SQLITE_BUSY       =  5;   /* The database file is locked */
	SQLITE_LOCKED     =  6;   /* A table in the database is locked */
	SQLITE_NOMEM      =  7;   /* A malloc() failed */
	SQLITE_READONLY   =  8;   /* Attempt to write a readonly database */
	SQLITE_INTERRUPT  =  9;   /* Operation terminated by sqlite3_interrupt()*/
	SQLITE_IOERR      = 10;   /* Some kind of disk I/O error occurred */
	SQLITE_CORRUPT    = 11;   /* The database disk image is malformed */
	SQLITE_NOTFOUND   = 12;   /* NOT USED. Table or record not found */
	SQLITE_FULL       = 13;   /* Insertion failed because database is full */
	SQLITE_CANTOPEN   = 14;   /* Unable to open the database file */
	SQLITE_PROTOCOL   = 15;   /* NOT USED. Database lock protocol error */
	SQLITE_EMPTY      = 16;   /* Database is empty */
	SQLITE_SCHEMA     = 17;   /* The database schema changed */
	SQLITE_TOOBIG     = 18;   /* String or BLOB exceeds size limit */
	SQLITE_CONSTRAINT = 19;   /* Abort due to constraint violation */
	SQLITE_MISMATCH   = 20;   /* Data type mismatch */
	SQLITE_MISUSE     = 21;   /* Library used incorrectly */
	SQLITE_NOLFS      = 22;   /* Uses OS features not supported on host */
	SQLITE_AUTH       = 23;   /* Authorization denied */
	SQLITE_FORMAT     = 24;   /* Auxiliary database format error */
	SQLITE_RANGE      = 25;   /* 2nd parameter to sqlite3_bind out of range */
	SQLITE_NOTADB     = 26;   /* File opened that is not a database file */
	SQLITE_ROW        = 100;  /* sqlite3_step() has another row ready */
	SQLITE_DONE       = 101;  /* sqlite3_step() has finished executing */
};

/**
 * Sqliteのステートメントを扱うクラス
 */
class SqliteStatement
{
	/**
	 * コンストラクタ
	 * @param sqlite データベース (Sqliteクラスのインスタンス)
	 * @param sql SQL 指定すると自動的に open します
	 * @param params バインドするパラメータ(配列または辞書)
	 * @throw "use Sqlite class Object" 第一引数が異常
	 * @throw "failed to open" 指定されたSQLのopenに失敗
	 */
	SqliteStatement(sqlite, sql=void, params=void);

	/**
	 * 新規ステートを開く
	 * @param sql SQL
	 * @param params バインドするパラメータ(配列または辞書)
	 * @return エラーコード
	 */
	function open(sql, params=void);

	/**
	 * ステートを閉じる
	 */
	function close();
	
	/**
	 * 元SQL(読み込み専用)
	 */
	property sql;

	/**
	 * バインド状態のリセット
	 * @return エラーコード
	 */
	function reset();
	
	/**
	 * パラメータのバインド
	 * @parma params バインドするパラメータ(配列または辞書)
	 * @return エラーコード
	 */
	function bind(params);

	/**
	 * パラメータのバインド
	 * @parma value 値
	 * @param pos パラメータ位置(省略時は前回指定値の次)
	 * @return エラーコード
	 */
	function bindAt(value, pos=void);
	
	/**
	 * ステートメント実行
	 * @return エラーコード
	 */
	function exec();

	/**
	 * ステートメントステップ実行
	 * @return 取得データがあれば true
	 */
	function step();
	
	/**
	 * データ数(読み込み専用)
	 * step の後設定されます
	 */
	property count;

	/**
	 * カラム数(読み込み専用)
	 */
	property columnCount;

	/**
	 * カラムのNULL判定
	 * @param column カラム番号またはカラム名
	 * @return 指定カラムが NULL かどうか
	 */
	function isNull(column);

	// カラムの型識別用
	SQLITE_INTEGER = 1;
	SQLITE_FLOAT = 2;
	SQLITE_TEXT = 3;
	SQLITE_BLOB = 4;
	SQLITE_NULL = 5;

	/**
	 * カラムの型の取得
	 * @param column カラム番号またはカラム名
	 * @return カラムの型コード
	 */
	function getType(column);

	/**
	 * カラム名の取得
	 * @param column カラム番号またはカラム名
	 * @return カラム名
	 */
	function getName(column);
	
	/**
	 * 結果の取得。
	 * @param column カラム番号またはカラム名。未指定の場合は、行全てを配列で返します
	 * @param defaultValue デフォルト値。カラムが NULL の場合にこの値を返します
	 * @return 行、または指定カラムの値
	 */
	function get(column=void, defaultValue=void);

	/**
	 * このクラスのメンバ名とかぶらないカラムのデータについては
	 * state.名前 で直接参照可能です
	 */
};

/**
 * sqliteのスレッド実行サポート
 */
class SqliteThread
{
	/**
	 * コンストラクタ
	 * @param window イベント処理用のウインドウ(Windowクラスのインスタンス)
	 * @param sqlite データベース (Sqliteクラスのインスタンス)
	 * @throw "use Window class Object" 第一引数が異常
	 * @throw "use Sqlite class Object" 第一引数が異常
	 */
	function SqliteThread(window, sqlite);
	
	/**
	 * 検索処理をバックグランドで実行する。
	 * 結果は内部に蓄積されて完了後に引き渡されます。
	 * @param sql 実行するSQL
	 * @param params バインドするパラメータ(配列または辞書)
	 * @return 処理が開始されたら true
	 */
	function select(sql, params);
	
	/**
	 * 更新処理をバックグランドでトランザクション実行する。
	 * @param sql 実行するSQL
	 * @param datas 更新用パラメータ(配列または辞書)の配列
	 * @return 処理が開始されたら true
	 */
	function update(sql, datas);
	
	/**
	 * 実行処理を中止させます。
	 * また記録されてる処理結果を破棄します。
	 */
	function abort();

	// ステート指定
	INIT    = 0; ///< 初期状態
	WORKING = 1; ///< 処理中
	DONE    = 2; ///< 処理完了

	/**
	 * 実行ステート
	 */
	property state;

	/**
	 * エラーコード
	 * 処理中での最後のエラーコードを返します
	 */
	property errorCode;
	
	/**
	 * select取得データ(配列)
	 */
	property selectResult;

	/**
	 * onProgress で呼び出す頻度指定
	 * 指定されてる数を取得するたびに呼び出しが行われる
	 */
	property progressUpdateCount;

	// ----------------------------------------------
	// イベント
	// ----------------------------------------------

	/**
	 * 状態変更
	 * @param state 新規状態
	 */
	function onStateChange(state);

	/**
	 * 更新処理経過
	 * @param num 取得データ数
	 */
	function onProgress(num);
};
