pg-cli

2.0.1 • Public • Published

pg-cli

a small but quite useful lib for postgres 一个基于node-pg( npm install pg )封装的更易用的pg客户端库

  • 暴露callbakc api、thunk api、promise api,方便自行选择
  • 支持初始化多个数据库的连接池
  • 支持单数据库事务和多数据库事务

按照自己给定的配置初始化一个postgres客户端助手

var pgHelper = require('pg-cli');
var pgConf = {
  user: 'postgres',
  database: 'test',
  password: '123456',
  host:'localhost',
  port: 5432,
  max: 10, // max number of clients in pool
  min: 4,
  idleTimeoutMillis: 30000, // how long a client is allowed to remain idle before being closed
}
pgHelper.initPool(pgConf);

执行原生sql语句

pgHelper.query('select * from "User" where "name"=$1', ['admin'], (err, reply)=>{
    if(err) console.log(err);// err coming from pg
    console.log(reply.rows);//data set
    console.log(reply.rowCount);//data count
});

简单的select查询

  • 在User表里查询name等于admin的数据集
pgHelper.select('User', [], {name:'admin'},(err, reply)=>{
    //your code here
});
pgHelper.select('User', [], {name:{'$eq':'admin'}}, (err, reply)=>{
    //your code here
});
  • 在User表里查询name等于admin的数据集,返回的数据里只包含name,age,class 3个字段
pgHelper.select('User', ['name','age','class'], {name:{'$eq':'admin'}},  (err, reply)=>{
    //your code here
});
  • 在User表里查询name等于admin的数据集,并返回
pgHelper.select('User', [], {name:'admin'}, (err, reply)=>{
    //your code here
});
pgHelper.select('User', [], {name:{'$eq':'admin'}}, (err, reply)=>{
    //your code here
});
  • 在User表里查询name不等于admin的数据集
pgHelper.select('User', [], {name:{'$ne':'admin'}}, (err, reply)=>{
    //your code here
});
  • 在User表里查询age>=13 且 <=19,和性别为男 数据集
pgHelper.select('User', [], {age:{'$gte':13,'$lte':19},sex:'male'}, (err, reply)=>{
    //your code here
});

各种$操作符映射的sql操作符{'$gte': '>=', '$gt': '>', '$eq': '=', '$lte': '<=', '$lt': '<', '$ne': '!=', '$in': 'in', '$like': 'like'}

插入操作

  • 向User表插入一条数据
var toInsert = {name:'admin',age:22,class:19,addr:'BeiJing'};
pgHelper.insert('User', toInsert, [], (err, reply)=>{
    //your code here
});
  • 向User表插入多条数据
var toInsertBatch = [{name:'admin',age:22,class:19,addr:'BeiJing'},{name:'admin2',age:29,class:15,addr:'ShangHai'}];
pgHelper.insertBatch('User', toInsertBatch, [], (err, reply)=>{
    //your code here
});

更新操作

  • 更新User表中id为1的对象的age字段值为100
pgHelper.update('User', {age:100}, {id:1}, [], (err, reply)=>{
    //your code here
});

批量更新操作

  • 更新User表中id为5,6,7的3行数据,where子句中匹配的属性为id,更新完毕后返回这些被更新行的'id','name','age','email'数据
pgHelper.updateBatch('User', [{id:4,age:12},{id:5,age:18},{id:6,age:19,name:'nick'}], 'id', ['id','name','age','email'], (err, reply)=>{
    //your code here
});
//生成的sql形如:
update "User" set 
"age" = case id when 4 then 12 when 5 then 18 when 6 then 19 end, 
"name" = case id when 6 then 'nick' end 
where "id" in(4,5,6) returning "id", "name", "age", "email"
  • 把所有grade为2的数据的age更新为15,把所有grade为3的数据的age更新为19,更新完毕后返回这些被更新行的'id','name','age','email'数据
pgHelper.updateBatch('User', [{grade:2,age:15},{grade:3,age:19}], 'grade', ['id','name','age','email'], (err, reply)=>{
    //your code here
});
//生成的sql形如:
update "User" set "age" = case grade when 2 then 15 when 3 then 19 end where "grade" in(2,3) 
returning "id", "name", "age", "email"
  • 跟新User表中id为1的行数据下的info字段,info为一个jsonb结构,{money:22,card:5,warehouse:{type:2,items:[{name:'sword',hp:200}]}},
  • 只更新type 2 为 3
var jsonbSet = pgHelper.jsonbSet;

pgHelper.update('User', {info:jsonbSet([{path:['warehouse','type'],value:3}])}, {id:1}, [], (err, reply)=>{
    //your code here
});
//生成的sql形如:
update "User" set "info" = jsonb_set("info",'{"warehouse","type"}',3) where "id" = 1;
  • 跟新User表中id为1的行数据下的info字段,info为一个jsonb结构,{money:22,card:5,warehouse:{type:2,items:[{name:'sword',hp:200}]}},
  • 更新type 2 为 3, 同时也更新 items[0]的name为sheild
var jsonbSet = pgHelper.jsonbSet;
//和path value 平级的还有一个字段:createMissing,不传的话走pg默认的规则true
var infoJsonb = jsonbSet([{path:['warehouse','type'],value:3},{path:['warehouse','items',0,'name'],value:'shield'}]);
pgHelper.update('User', {info:infoJsonb}, {id:1}, [], (err, reply)=>{
    //your code here
});
//生成的sql形如:
update "User" set "info" = jsonb_set(jsonb_set("info",'{"warehouse","type"}',3),'{"warehouse","items",0,"name"}','shield') where "id" = 1;
  • jsonb_set具体操作可参考官网

删除操作

  • 删除User表中id为1的对象
pgHelper.remove('User', {id:1}, (err, reply)=>{
    //your code here
});

事务操作

  • 先删除User表里满足id为1的数据,
  • 然后删除Score表里满足class为19的数据,
  • 然后向User表里添加一条数据,
  • 然后从Score表里选择出满足class为15的数据集,
  • 然后从这些class为15的数据集里挑出score>80的数据,插入到Log表里
//开始构建事务操作的一组操作对象,关于构建操作对象可参考api说明
//包括了: $select,$update,$insert,$remove,$insertBatch,$rawSql
var selectUser = {'$select': {table: 'User', filter: {id: 1}, key: 'selectUser'}};
var removeScore19 = {'$remove': {table: 'Score', filter: {class: 19}, key: 'removeScore19'}};
var addOneUser = {
  '$insert': {
    table: 'User',
    toInsert: {name: 'admin', age: 22, class: 19, addr: 'BeiJing'},
    key: 'addOneUser'
  }
};
var selectScore15 = {'$select': {table: 'Score', filter: {class: 19}, key: 'selectScore15'}};
var toLog = {
  '$insertBatch': {
    table: 'Log', toInsertBatch: [], key: 'toLog', preHandler: (selfOP, results, OPMap)=> {
      //selfOP指向当前这个操作对象自己: {table:'Log', toInsertBatch:[], key:'toLog' ......}
      //results收集前面已经执行好的结果: {selectUser: <result>, removeScore19:<result>, addOneUser:<result>, selectScore15:<result>}
      //OPMap是前面所有的操作对象map: {selectUser: <operation body for selectUser>, removeScore19:<operation body for removeScore19>, ......}
      var selectScore15Ret = results.selectScore15.rows;
      selfOP.toInsertBatch = selectScore15Ret;
    }
  }
};

var operationArr = [selectUser, removeScore19, addOneUser, selectScore15, toLog];
//queryWithTransaction会按序执行这些操作对象,中间任何一个失败,事务都会回滚
pgHelper.queryWithTransaction(operationArr, (err, results)=> {
  //results收集的是所有已执行好的结果: {selectUser: <result>, removeScore19:<result>, addOneUser:<result>, selectScore15:<result>, toLog:<toLog>}
  //your code here
});

使用promise 或者 thunk,执行多数据事务提交

//把grade为2的所有用户age改为18
const { $apiPromise:ap } = require('pg-cli');
var conf1 = {
  user: 'financeuser',
  password: 'financeuserpwd',
  host:'localhost',
  port: 5432,
  database: 'zzk',
  max: 10,
  min: 4,
  idleTimeoutMillis: 30000
};
var conf2 = {
  user: 'financeuser',
  password: 'financeuserpwd',
  host:'localhost',
  port: 5432,
  database: 'game',
  max: 10,
  min: 4,
  idleTimeoutMillis: 30000
};
ap.initPool(conf1);
ap.initPool(conf2);

async function main() {
  const user1 = await hp.select(User, { filter: { id: 1 }, fields: ['id', 'balance'] });
  const user2 = await hp.select(User, { filter: { id: 1 } });
  const matrix = await hp.select(Matrix, { filter: { id: 1 }, db: 'game' });

  await hp.startMultiDbTransaction(async function(clientMap){
    const user = await hp.select(User, { client:clientMap.zzk, filter: { id: 1 }, fields: ['id', 'balance'] });
    const matrix = await hp.select(Matrix, { client:clientMap.game, filter: { id: 1 } });
    console.log(user, matrix);
  });
  console.log('end startMultiDbTransaction');
}

main().catch(err=>console.log(err));

Package Sidebar

Install

npm i pg-cli

Weekly Downloads

0

Version

2.0.1

License

ISC

Unpacked Size

66.4 kB

Total Files

17

Last publish

Collaborators

  • fantasticsoul