/**
 * @description Sqliteクラス
 */
class Sqlite
{
	/**
	 * コンストラクタ
	 * @param database データベースファイル
	 * @param readonly 読み込み専用で開く
	 * @description ※読み込み専用時は吉里吉里のファイル機構が使われます。そうでない場合は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;

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

/**
 * @description 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);

	// カラムの型識別用
	const SQLITE_INTEGER = 1;
	cnost SQLITE_FLOAT = 2;
	cnost SQLITE_TEXT = 3;
	cnost SQLITE_BLOB = 4;
	cnost 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.名前 で直接参照可能です
	 */
};

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

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

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

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

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

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

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

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