使用Promise的异步处理方式在nodejs中使用sqlite3模块
在Node.js中,sqlite3是最常用的SQLite模块,它具有最高的下载数量。
https://www.npmjs.com/package/sqlite3
https://github.com/mapbox/node-sqlite3
因为我不再想使用回调函数,所以将其改为Promise支持。只是在回调函数中加了Promise.resolve()而已。
因为npm上的其他sqlite模块的下载数太少且存在风险,所以选择自行开发。
备注
-
- 既存のsqlite3モジュールはコールバックの他に、runで独自のthisをbindしているのでアロー関数が使えない。
-
- foreachは途中でキャンセルが出来なくて無意味との事なのでスルー。allでやる。
- その結果、run、get、all、prepareで十分 のはず。serializeやparallelizeは正直良くわからん
const sqlite = require('sqlite3').verbose();
class sqlite3{
constructor(dbFileName){
// https://github.com/mapbox/node-sqlite3/wiki/API
this.db = new sqlite.Database(dbFileName);
}
/// 戻り値は数字。updateとかdelete分に使う
run(query,param){
const p = new Promise((ok,ng)=>{
this.db.run(query,param,function(err,res){
// bindしてthisを書き換えてるのでアロー関数は出来ない
let lastId = this.lastID || -1;
let changes = this.changes || -1;
if(err){
ng(new Error(err));
}else{
ok({lastId:lastId,changes:changes});
};
});
});
return p;
}
/// 1アイテムだけselectする。結果が0件の時はundefinedになる
get(query,param){
const p = new Promise((ok,ng)=>{
this.db.get(query,param,(err,res)=>{
if(err){
ng(new Error(err));
}else{
ok(res);
};
})
});
return p;
}
/// 全てselectする
all(query,param){
const p = new Promise((ok,ng)=>{
this.db.all(query,param,(err,res)=>{
if(err){
ng(new Error(err));
}else{
ok(res);
};
})
});
return p;
}
prepare(query){
// ここのパラメーターが有効になる条件がわからなかったので、prepareの引数はクエリ文字だけで
let r = this.db.prepare(query,{});
return new sqlite3_prepare(r);
}
}
// finalizeやresetの使い方がわからなかったのでrunだけ
class sqlite3_prepare{
constructor(statement){
this.statement = statement;
}
run(query){
const p = new Promise((ok,ng)=>{
this.statement.run(query,()=>{ok()});
});
return p;
}
}
module.exports = sqlite3;
使用方法如下
const sqlite3 = require('./sqlite3');
async function main(){
const db = new sqlite3("./database.db");
let yyyList = await transactionText(db);
}
main();
function transactionText(db){
return Promise.resolve()
.then(()=>{
return db.run("BEGIN");
}).then(()=>db.run(`insert into xxx (v)values(?)`,["test"]))
.then((item)=>{
let insertId = item.lastId;
let statement = db.prepare("INSERT INTO yyy (sub_id,val) VALUES (?,?)");
return Promise.all(["a","b","c"].map((id)=>{
return statement.run([insertId,id]);
}));
}).then(()=>db.run("COMMIT"))
}).then(()=>db.get(`select * from yyy`));
}