使用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`));
}
广告
将在 10 秒后关闭
bannerAds