More ... | 編集履歴:差分記録開始以来の設定管理モジュール,プログラムの設定を管理したり,ファイルに書き出したり読み込んだりの変更箇所
+ * 用語について + :エリア:他の設定に影響を及ぼさない大きな区分(SQLのテーブルに相当) + :セクション:設定内の区分 + + * 扱える設定ファイルの書式 + {{{ + # 一行コメント(行末コメントには非対応) + セクション名 { + キー1: 値 + キー2: 値 + キー3: 値 + } + }}} + + * サンプル + {{{ + /* 2015/8/16 + * サンプルスクリプト + */ + + #include "sioc.hsp" + + #define CONFIG "config.cfg" + + // 初期化 + sioc_init MODE_NORMAL + + sioc_createArea "SampleConfig" + + // セクションを決める + sioc_setSection "General" + + // 値を設定する + sioc_setValue "Config1", "test1" + sioc_setValue "Config2", "test2" + sioc_setValue "Config3", "test3" + + + // 設定ファイルに出力 + sioc_exportToFile CONFIG + + // リセットする + sioc_resetArea + + // 設定ファイルを読み込む + sioc_importFromFile CONFIG + + sioc_setSection "General" + + // 値を読み込む + mes "Config1="+sioc_getValue("Config1") + mes "Config2="+sioc_getValue("Config2") + mes "Config3="+sioc_getValue("Config3") + + sioc_end + }}} + + * sioc.hsp + {{{ + /* 2015/09/07 + * sioc.hsp v1.4 + * 設定管理モジュール。 + * 必須: sqlele.hsp sqlite3.dll + */ + #include "sqlele.hsp" + + #ifndef __CTL_SIO__ + #define global __CTL_SIO__ + + #const global MODE_NORMAL 0 + #const global MODE_DEBUG 1 + + #module "sioc" + + #define global sioc_init(%1=0) _sioc_init %1 + #deffunc _sioc_init int debug //MODE_DEBUGでデバッグ。データベースファイルが残る。 + if (initialized == 1) :return + + sdim nowTableID + sdim nowSect + nowSect = "global" + initialized = 1 + + + if (debug) { ;on + sql_open "debug.db" + } else { ;off + sql_open ":memory:" + } + + return + + #deffunc sioc_end + sql_close + return + + + #defcfunc sioc_newArea + /* sioc_newArea + * 返り値 : エリアID + * 新しいエリア(テーブル)を作成する。 + */ + + nowTableID = sioc_uniqStr() + + + sql = strf("CREATE TABLE \"%s\"", nowTableID) + sql += "(" + sql += "id INTEGER PRIMARY KEY," + sql += "section VARCHAR(256)," + sql += "key VARCHAR(256) NOT NULL," + sql += "value VARCHAR(512)" + sql += ")" + sql_q sql + return nowTableID + + #deffunc sioc_setFocus str ID + /* sioc_setFocus + * 引数 : "エリアID" + * 対象となるエリアのIDを変更する。 + * 必ず指定するように。 + */ + + if (ID != "") { + nowTableID = ID + } else { + return -1 + } + return + + #defcfunc sioc_getFocus + /* sioc_getFocus + * 返り値 : エリアID + * 現在のエリアIDを返す. + */ + return nowTableID + + #defcfunc sioc_uniqStr + /* sioc_uniqStr + * 返り値 : "ユニークな文字列" + * 重複のない文字列を作成する。 + */ + + result = "" + + result = strf("%02d%02d%02d%02d", getTime(4), getTime(5), getTime(6), getTime(7)) + return result + + #deffunc sioc_createArea str id + /* sioc_createArea + * 引数 : "エリアID" + * エリアIDを指定して作成する。 + */ + + sql = "" + nowTableID = id + + + sql = strf("CREATE TABLE IF NOT EXISTS \"%s\"", id) + sql += "(" + sql += "id INTEGER PRIMARY KEY," + sql += "section VARCHAR(256)," + sql += "key VARCHAR(256) NOT NULL," + sql += "value VARCHAR(512)" + sql += ")" + sql_q sql + return + + #deffunc sioc_importFromFile str path + /* sioc_importFromFile + * 引数 : "パス" + * 現在選択されているエリアに設定ファイルを読み込む。 + * このとき初期化されるので注意。 + */ + + nowScope = "global" + scopeStrIndex = -1 + keyDelimitIndex = -1 + scopeEndIndex = -1 + lineTemp = "" + keyTemp = "" + valueTemp = "" + fileBuf = "" + + + exist path + if (strsize <= 0) :return -1 + sioc_resetArea + notesel fileBuf + noteload path + repeat notemax + noteget lineTemp, cnt + lineTemp = sioc_trimWhiteSpace(lineTemp) + + scopeStrIndex = instr(lineTemp, 0, "{") + keyDelimitIndex = instr(lineTemp, 0, ":") + scopeEndIndex = instr(lineTemp, 0, "}") + + if (strmid(lineTemp, 0, 1) == "#") :continue + + if (scopeStrIndex != -1) { + nowScope = strmid(lineTemp, 0, scopeStrIndex) + } + + if (scopeEndIndex != -1) { + nowScope = "global" + } + + if (keyDelimitIndex != -1) { + keyTemp = strmid(lineTemp, 0, keyDelimitIndex) + valueTemp = strmid(lineTemp, -1, strlen(lineTemp) -keyDelimitIndex -1) + sql = strf("INSERT INTO \"%s\"", nowTableID) + sql += "(" + sql += "section, key, value" + sql += ") VALUES (" + sql += strf("\"%s\", \"%s\", \"%s\"", nowScope, keyTemp, valueTemp) + sql += ")" + sql_q sql + } + loop + return + + #deffunc sioc_exportToFile str file + /* sioc_exportToFile + * 引数 : "パス" + * 現在選択されているエリアを設定ファイルに書き込む。 + */ + + sql = "" + nowScope = "global" + fileBuf = "" + keyTemp = "" + scopeTemp = "" + valueTemp = "" + indentLevel = 0 + + sql = strf("SELECT * FROM \"%s\" ORDER BY \"section\" ASC, \"key\" ASC", nowTableID) + sql_q sql + + len = stat + + notesel fileBuf + + repeat len + scopeTemp = sql_v("section") + keyTemp = sql_v("key") + valueTemp = sql_v("value") + + if (nowScope != scopeTemp) { + if (nowScope != "global") { + indentLevel-- + noteadd strf("%"+(indentLevel*2)+"s}", "") + } + + noteadd strf("%"+(indentLevel*2)+"s%s {", "", scopeTemp) + nowScope = scopeTemp + indentLevel++ + } + + noteadd strf("%"+(indentLevel*2)+"s%s: %s", "", keyTemp, valueTemp) + + sql_next + loop + + if (nowScope != "global") { + indentLevel-- + noteadd strf("%"+(indentLevel*2)+"s}", "") + } + + notesave file + + return + + #defcfunc sioc_trimWhiteSpace str data + /* sioc_trimWhiteSpace + * 引数 : "元データ" + * 返り値: "トリム後データ" + * 空白文字を削除する。 + */ + + result = data + + result = strtrim(result, 3, ' ') + result = strtrim(result, 3, '\t') + result = strtrim(result, 3, ' ') + return result + + #deffunc sioc_resetArea + /* sioc_resetArea + * 引数、返り値なし。 + * 現在選択されているエリアをリセットする。 + */ + + tempID = nowTableID + + sioc_deleteArea + sioc_createArea tempID + return + + #deffunc sioc_deleteArea + /* sioc_deleteArea + * 引数、返り値なし。 + * 現在選択されているエリアを削除する。 + */ + + sql = "" + + sql = strf("DROP TABLE \"%s\"", nowTableID) + sql_q sql + nowTableID = "" + return + + #deffunc sioc_setSection str sectTemp + /* sioc_setSection + * 引数 : "セクション名" + * 読み込むセクションを変更する。 + */ + + if (sectTemp == "") :return -1 + nowSect = sectTemp + return + + #defcfunc sioc_getSection + return nowSect + + #deffunc sioc_getKeys array out + /* sioc_getKeys + * 引数: 出力先の配列 + * 現在選択されているエリア、セクションのキー一覧を取得する。 + */ + sql = strf("SELECT key FROM \"%s\" WHERE section=\"%s\"", nowTableID, nowSect) + + sql_q sql + count = stat + + if (count <= 0) : return 0 + + sdim out,, count + repeat count + out(cnt) = sql_v("key") + sql_next + loop + + return count + + #defcfunc sioc_getValue str key + /* sioc_getValue + * 引数 : "キー" + * 現在選択されているエリア、セクションのキーに対応する値を取得する。 + */ + + tmparr(0, 0) = "" + sql = "" + + sql = strf("SELECT value FROM \"%s\" WHERE key=\"%s\" AND section=\"%s\"", nowTableID, key, nowSect) + sql_q sql + + if (stat < 1) : return "" + return tmparr(0, 0) + + #deffunc sioc_setValue str key, str value + /* sioc_setValue + * 引数 : "キー", "値" + * 現在選択されているエリア、セクションのキーに対応する値を設定する。 + */ + + if (sioc_existsValue(key)) { + sioc_updateValue key, value + } else { + sioc_addValue key, value + } + + return + + #defcfunc sioc_existsValue str key + /* sioc_existsValue + * 引数 : "キー" + * 現在選択されているエリア、セクションにキーが存在するかを取得する。 + */ + + sql = "" + + sql = strf("SELECT \"id\" FROM \"%s\" WHERE key=\"%s\" AND section=\"%s\"", nowTableID, key, nowSect) + sql_q sql + + return (stat > 0) + + #deffunc sioc_addValue str key, str value + /* sioc_addValue + * 引数 : "キー", "値" + * 現在選択されているエリア、セクションにキーに対応する値を作成する。 + * 通常はsioc_setValueを使用してください。 + */ + + sql = "" + + sql = strf("INSERT INTO \"%s\" (\"section\", \"key\", \"value\") VALUES (\"%s\", \"%s\", \"%s\")", nowTableID, nowSect, key, value) + sql_q sql + return + + #deffunc sioc_updateValue str key, str value + /* sioc_updateValue + * 引数 : "キー", "値" + * 現在選択されているエリア、セクションにキーに対応する値を更新する。 + * 通常はsioc_setValueを使用してください。 + */ + + sql = "" + + sql = strf("UPDATE \"%s\" SET value=\"%s\" WHERE key=\"%s\"", nowTableID, value, key) + sql_q sql + return + + #deffunc sioc_deleteValue str key + /* sioc_deleteValue + * 引数 : "キー" + * 現在選択されているエリア、セクションにキーを削除する。 + */ + + sql = "" + sql = strf("DELETE FROM \"%s\" WHERE key=\"%s\"", nowTableID, key) + sql_q sql + return + + #global + #endif + }}} |