WSH JScript環境でSQLite3をMongoDBのように操作する

プログラミング
スポンサーリンク

はじめに

こんにちは!なたでです!

「またまたWSHで何やっているんだ!」という話ですが、この度WSH JScript環境でSQLite3のDBをMongoDBのように操作するライブラリを作りましたので、紹介したいと思います。

MongoDB っぽく SQLite3 用のDB操作をする

MongoDBとは

2012年ぐらいから流行り出したNoSQLというジャンルのデータベースです。JSONのように放り込みできるのが特徴です。ただ、以下のようにトランザクションの速度やライセンスの問題があります。

このように注意点はあるもののMongoDBは、SQL文を書かなくて良いというメリットがあり、その操作感が好きだったため、今回SQLiteをMongoDBのように実行できるライブラリを作ってみました。

始め方

以下のライブラリを利用します。ダウンロードして、Windows環境で中のtestフォルダ内にSQLiteTest.wsfを実行してみて下さい。

内容としてはすでに作成済のDBに対してMongoDBの操作感で以下のSQLite3コマンドが利用できます。

  • update
  • select
  • insert
  • delete

操作例

外部実行ファイルの設定

sqlite-tools-win32-x86 をダウンロードし、SQLite3.setSQLite3()で外部実行ファイルの設定します。

var libfile = new SFile("./lib/sqlite3.exe")
SQLite3.setSQLite3(libfile);

他の方法としては、SQLite3.install()でも可能です。

SQLite3.install();

SQLite3.install()を用いると、勝手にインターネットからダウンロードして、./lib/sqlite3.exeに設置し設定までされます。

データベースの設定

本ライブラリではデータベースの新規作成には対応しておらず、既存のデータベースを用意する必要があります。動作例として、/toolbox-wsh/test/SQLiteTest.dbなどを利用してみて下さい。

データベースは以下のように設定します。

var db_file = new SFile("./SQLiteTest.db");
var db = SQLite3.use(db_file);

これで、変数dbを用いて、データベースの操作をしていけます。今回は、/toolbox-wsh/test/SQLiteTest.dbを例に説明してみたいと思います。

データベースの中身をみる

データベースは、MongoDBのようにテーブル名.メソッドのように操作します。メソッドは、次のようなコマンドが利用できます。

例として、「students」というテーブルのレコード数をcountで見てみましょう。

console.log(db.students.count());

実行結果は以下のようになります。

4

では、findで中身も見てみましょう。

var record = db.students.find();
console.log(JSON.stringify(record));

実行結果は以下のようになり、データベースの中身がJavaScriptのオブジェクトで取得できていることが分かると思います。

[
{"rowid":1,"ID":"A001","NM_SEI":"佐藤","NM_MEI":"良一","PLACE":"愛知県","LOGIN_COUNT":180,"LAST_UPDATE":"Tue, 31 Mar 2020 15:00:00 UTC"},
{"rowid":2,"ID":"A002","NM_SEI":"青木","NM_MEI":"桃子","PLACE":"岐阜県","LOGIN_COUNT":177,"LAST_UPDATE":"Wed, 31 Mar 2021 15:00:00 UTC"},
{"rowid":3,"ID":"S001","NM_SEI":"加藤","NM_MEI":"さゆり","PLACE":"岐阜県","LOGIN_COUNT":322,"LAST_UPDATE":"Wed, 29 May 2019 15:00:00 UTC"},
{"rowid":4,"ID":"S002","NM_SEI":"田中","NM_MEI":"健太郎","PLACE":"三重県","LOGIN_COUNT":302,"LAST_UPDATE":"Mon, 2 Sep 2019 15:00:00 UTC"}
]

条件文を使ってみる

MongoDB特有の条件の操作方法でレコードをselectしてみましょう。

以下は、PLACE = "愛知県" or PLACE = "三重県" の条件を拾ってくるコードです。

var record = db.A.find({ $or: [{PLACE: "愛知県"} , {PLACE: "三重県" }]});
console.log(JSON.stringify(record));

実行結果は以下のようになります。

[
{"rowid":1,"ID":"A001","NM_SEI":"佐藤","NM_MEI":"良一","PLACE":"愛知県","LOGIN_COUNT":180,"LAST_UPDATE":"Tue, 31 Mar 2020 15:00:00 UTC"},
{"rowid":4,"ID":"S002","NM_SEI":"田中","NM_MEI":"健太郎","PLACE":"三重県","LOGIN_COUNT":302,"LAST_UPDATE":"Mon, 2 Sep 2019 15:00:00 UTC"}
]

実行結果が長いため名前部分だけ表示してみます。

var record = db.A.find({ $or: [{PLACE: "愛知県"} , {PLACE: "三重県" }]}, { NM_SEI : 1, NM_MEI : 1 });
console.log(JSON.stringify(record));

実行結果は以下のようになります。

[{"NM_SEI":"佐藤","NM_MEI":"良一"},{"NM_SEI":"田中","NM_MEI":"健太郎"}]

とまあ、このようにJavaScriptで簡単にDBを扱うことが可能となります。

サンプルスクリプト

上記の使い方含めて、/toolbox-wsh/test/SQLiteTest.jsのスクリプトの紹介とその動作結果を紹介します。

スクリプト

/toolbox-wsh/test/SQLiteTest.jsのスクリプトは以下の通りです。createSQLは内部で実行するコードで、どのようなSQL文が作成されている物なのかデバッグのために表示させてみました。

//@ts-check
/// <reference path="../include/SenkoWSH.d.ts" />
/// <reference path="../build/toolbox-wsh.d.ts" />

System.executeOnCScript();
System.initializeCurrentDirectory();

console.log("SQLite3 をインストール/設定します。");
SQLite3.install();
console.log("")

console.log("データベースを取得します。");
var db_file = new SFile("./SQLiteTest.db");
var db = SQLite3.use(db_file);
console.log("")

console.log("テーブルの情報を確認します。");
for(var key in db) {
	console.log("table : " + key);
	console.log("types : " + JSON.stringify(db[key].getTypes()));
	console.log("count : " + JSON.stringify(db[key].count()));
	console.log("data : " + JSON.stringify(db[key].find()));
	console.log("")
}

var where, select, setdata;

console.log("条件文の動作1");
where = { LOGIN_COUNT : { $ne: 177 } , PLACE : "岐阜県" };
console.log(db.students.createSQL( "select", where ));
console.log(JSON.stringify(db.students.find( where )));
console.log("");

console.log("条件文の動作2");
where = { LOGIN_COUNT : { $gt: 100, $lte: 200 }};
console.log(db.students.createSQL( "select", where ));
console.log(JSON.stringify(db.students.find( where )));
console.log("");

console.log("条件文の動作3");
where = { $or: [{PLACE: "愛知県"} , {PLACE: "三重県" }]};
select = { NM_SEI : 1, NM_MEI : 1 };
console.log(db.students.createSQL( "select", where, select ));
console.log(JSON.stringify(db.students.find( where, select )));
console.log("");

console.log("データを追加");
setdata = {
	ID: Format.textf("B%04d", Math.trunc(Math.random() * 1000)),
	NM_SEI: "森井",
	NM_MEI: "大輔",
	PLACE: "北海道",
	LAST_UPDATE: new Date()
};
console.log(db.students.createSQL( "insert", undefined, undefined, setdata));
db.students.insert( setdata );
console.log(JSON.stringify(db.students.find({PLACE: "北海道"}, { ID : 1, NM_SEI : 1, NM_MEI : 1, PLACE : 1 })));
console.log("");

console.log("データを更新");
where = { "PLACE" : "沖縄県" };
setdata = { "PLACE" : "北海道" };
console.log(db.students.createSQL( "update", where, undefined, setdata));
db.students.update( where, setdata );
console.log(JSON.stringify(db.students.find({NM_MEI: "大輔"}, { ID : 1, NM_SEI : 1, NM_MEI : 1, PLACE : 1 })));
console.log("");

console.log("データを削除");
where = { NM_MEI: "大輔" };
console.log(db.students.createSQL( "delete", where ));
db.students.remove( where );
console.log(JSON.stringify(db.students.find({NM_MEI: "大輔"}, { ID : 1, NM_SEI : 1, NM_MEI : 1, PLACE : 1 })));
console.log("");

console.log("終了");
System.stop();

実行結果

/toolbox-wsh/test/SQLiteTest.wsfの実行結果となります。

SQLite3 をインストール/設定します。

データベースを取得します。

テーブルの情報を確認します。
table : empty_table
types : {"NUM":{"cid":0,"name":"NUM","type":"INTEGER","size":-1,"dflt_value":"0","is_not_null":false}}
count : 0
data : []

table : students
types : {"ID":{"cid":0,"name":"ID","type":"VARCHAR","size":10,"dflt_value":"A000","is_not_null":true},"NM_SEI":{"cid":1,"name":"NM_SEI","type":"TEXT","size":-1,"dflt_value":"","is_not_null":true},"NM_MEI":{"cid":2,"name":"NM_MEI","type":"TEXT","size":-1,"dflt_value":"","is_not_null":true},"PLACE":{"cid":3,"name":"PLACE","type":"TEXT","size":-1,"dflt_value":"","is_not_null":true},"LOGIN_COUNT":{"cid":4,"name":"LOGIN_COUNT","type":"INTEGER","size":-1,"dflt_value":"0","is_not_null":true},"LAST_UPDATE":{"cid":5,"name":"LAST_UPDATE","type":"DATETIME","size":-1,"dflt_value":"0","is_not_null":true}}
count : 5
data : [{"rowid":1,"ID":"A001","NM_SEI":"佐藤","NM_MEI":"良一","PLACE":"愛知県","LOGIN_COUNT":180,"LAST_UPDATE":"Tue, 31 Mar 2020 15:00:00 UTC"},{"rowid":2,"ID":"A002","NM_SEI":"青木","NM_MEI":"桃子","PLACE":"岐阜県","LOGIN_COUNT":177,"LAST_UPDATE":"Wed, 31 Mar 2021 15:00:00 UTC"},{"rowid":3,"ID":"S001","NM_SEI":"加藤","NM_MEI":"さゆり","PLACE":"岐阜県","LOGIN_COUNT":322,"LAST_UPDATE":"Wed, 29 May 2019 15:00:00 UTC"},{"rowid":4,"ID":"S002","NM_SEI":"田中","NM_MEI":"健太郎","PLACE":"三重県","LOGIN_COUNT":302,"LAST_UPDATE":"Mon, 2 Sep 2019 15:00:00 UTC"},{"rowid":5,"ID":"B0291","NM_SEI":"森井","NM_MEI":"大輔","PLACE":"北海道","LOGIN_COUNT":0,"LAST_UPDATE":"Sun, 30 May 2021 02:31:40 UTC"}]

table : type_table
types : {"A_TXT":{"cid":0,"name":"A_TXT","type":"TEXT","size":-1,"dflt_value":null,"is_not_null":false},"B_INT":{"cid":1,"name":"B_INT","type":"INTEGER","size":-1,"dflt_value":null,"is_not_null":false},"C_REAL":{"cid":2,"name":"C_REAL","type":"REAL","size":-1,"dflt_value":null,"is_not_null":false},"D_DATE":{"cid":3,"name":"D_DATE","type":"DATETIME","size":-1,"dflt_value":null,"is_not_null":false},"E_BOOL":{"cid":4,"name":"E_BOOL","type":"BOOLEAN","size":-1,"dflt_value":null,"is_not_null":false}}
count : 3
data : [{"rowid":1,"A_TXT":"レコード1","B_INT":30,"C_REAL":12.34,"D_DATE":"Fri, 12 Feb 2021 15:00:00 UTC","E_BOOL":true},{"rowid":2,"A_TXT":"レコード2","B_INT":123456789,"C_REAL":-4.5,"D_DATE":"Tue, 3 May 1988 15:00:00 UTC","E_BOOL":false},{"rowid":3,"A_TXT":"レコード3","B_INT":-40,"C_REAL":100000000000000000000,"D_DATE":"Wed, 8 Sep 1999 15:00:00 UTC","E_BOOL":true}]

条件文の動作1
select rowid, ID, NM_SEI, NM_MEI, PLACE, LOGIN_COUNT, LAST_UPDATE from students where ( LOGIN_COUNT != 177 ) and ( PLACE = '岐阜県' );
[{"rowid":3,"ID":"S001","NM_SEI":"加藤","NM_MEI":"さゆり","PLACE":"岐阜県","LOGIN_COUNT":322,"LAST_UPDATE":"Wed, 29 May 2019 15:00:00 UTC"}]

条件文の動作2
select rowid, ID, NM_SEI, NM_MEI, PLACE, LOGIN_COUNT, LAST_UPDATE from students where ( LOGIN_COUNT > 100 ) and ( LOGIN_COUNT <= 200 );
[{"rowid":1,"ID":"A001","NM_SEI":"佐藤","NM_MEI":"良一","PLACE":"愛知県","LOGIN_COUNT":180,"LAST_UPDATE":"Tue, 31 Mar 2020 15:00:00 UTC"},{"rowid":2,"ID":"A002","NM_SEI":"青木","NM_MEI":"桃子","PLACE":"岐阜県","LOGIN_COUNT":177,"LAST_UPDATE":"Wed, 31 Mar 2021 15:00:00 UTC"}]

条件文の動作3
select NM_SEI, NM_MEI from students where ( ( PLACE = '愛知県' ) ) or ( ( PLACE = '三重県' ) );
[{"NM_SEI":"佐藤","NM_MEI":"良一"},{"NM_SEI":"田中","NM_MEI":"健太郎"}]

データを追加
insert into students values('B0376', '森井', '大輔', '北海道', 0, '2021-05-30 11:39:19');
[{"ID":"B0291","NM_SEI":"森井","NM_MEI":"大輔","PLACE":"北海道"},{"ID":"B0376","NM_SEI":"森井","NM_MEI":"大輔","PLACE":"北海道"}]

データを更新
update students set PLACE = '北海道' where ( PLACE = '沖縄県' );
[{"ID":"B0291","NM_SEI":"森井","NM_MEI":"大輔","PLACE":"北海道"},{"ID":"B0376","NM_SEI":"森井","NM_MEI":"大輔","PLACE":"北海道"}]

データを削除
delete from students where ( NM_MEI = '大輔' );
[]

終了

おわりに

いかがでしょうか。

今回はSQLite3を利用したJScript環境用のデータベース操作用の機能を作成しましたが、今後はffmpegを用いたマルチメディアや、WinSCPを用いたFTP関係の機能も作っていけたらいいなともいます。

コメント

タイトルとURLをコピーしました