npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pg-cli

v2.0.1

Published

a small lib for postgres client

Downloads

25

Readme

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));