自己实现PostgresQL的nodejs驱动,分享给大家
来源:互联网 发布:计划进度表软件下载 编辑:程序博客网 时间:2024/05/21 17:59
PostgresQL性能上不输Mysql,而且支持很多高级特性,于是我写了这个项目,根据libpg的c驱动,封装了这个nodejs驱动。
项目地址:
git clone https://code.csdn.net/limite_god/pgsql.git
开发难点、待实现功能、特性
1、nodejs的v0.12.0开始,api有了不少变化,熟悉这些变化用来不少时间;
2、libpg-c的api的熟悉,全英文的,得一行行认真看;
3、makefile,这里面的知识杂而细,只写了个linux下编译的;
4、libpg的executeParam方法暂未实现,所以添加了escape的连接池,专门用来处理escape;
5、数据类型支持,现在只对libpg的int4及int8做了转换,其它格式会返回字符串(比如日期);
6、连接池使用了nodejs的EventEmitter实现,sql命令会在压力较大的时候进行排队,这一块策略非常重要,涉及了nodejs的核心思想,尽量发挥慢速资源的最大性能,Pool.js,大家可以细看;
7、Database对象cmPool和trPool、esPool,cm处理无需声明事务的sql,tr用来专门执行事务连接,es专门用来escape字符串;
8、api尽量做到给调用者最大的自由,协调资源交给驱动。
9、很多地方注释缺少,等待以后添加;
10、table实现了类mongodb的find,update,remove,save,都可以传递options参数,options参数暂时只支持4个key,ret,sort,limit,offset;
11、我会持续对项目进行维护,添加更多功能,有建议请留言。
环境准备
操作系统centos6+,安装nodejs版本v0.12.0+,postgresql版本9.4.1
需要说明的是,nodejs和postgresql都需要从源码安装,postgress的安装目录采用默认目录,/usr/local/pgsql/,如果你的目录不同,请修改项目跟目录下的makefile
下载代码并编译
git clone https://code.csdn.net/limite_god/pgsql.git
cd pgsqlmake
如果头文件未找到
如果提示方法实现未找到
DEMO
var async = require('async');
var pgsql = require('pgsql');var DataBase = pgsql.DataBase;var Table = pgsql.Table;var Column = pgsql.Column;var db = new DataBase({ url:"host=127.0.0.1 dbname=test user=postgres", cmPoolSize:20, //通过table.find,update,remove,save都使用这个连接池的连接 trPoolSize:5, //db.getConn获得连接都是这个连接池的连接 esPoolSize:1 //这个一个连接的连接池专门用来执行escape});var testTable = new Table("test",[ new Column("id", "SERIAL", 0, "primary key"), new Column("index", "SERIAL", 0, ""), new Column("name", "text", -1, ""), new Column("description", "text", -1, "") ]);testTable.colList['description'].escape = true; //需要对文本进行转义db.put(testTable);async.waterfall([ function(cb){ //连接数据库 db.init(function(err, data){ console.log(data); cb(err); }); }, function(cb) { var t = db.get("test"); console.log(t.getDdl()); t.find({id:3}, {}, function(err, data){ console.log(data); cb(err); }); }, function(cb) { var t = db.get("test"); var doc = { $set:{ name:"just a test." } }; t.update({id:3}, doc, function(err, data){ console.log(data); cb(err); }); }, function(cb) { var t = db.get("test"); var options = { limit:10, offset:0, sort:{ id:-1 } }; t.find({id:3}, {}, options, function(err, data){ console.log(data); cb(err); }); }, function(cb) //save a set { var t = db.get("test"); t.save({name:"liming", description:'a\'b'}, function(err, data){ console.log(data); cb(err); }); }, function(cb) //保存记录,并返回自增长的id { var t = db.get("test"); var options = { ret:{ id:1 } }; t.save({name:"liming", description:'a\'b'}, options, function(err, data){ console.log(data); cb(err); }); }, function(cb) { var t = db.get("test"); t.remove({name:"test222"}, function(err, data){ console.log(data); cb(err); }); }, function(cb) //跨表的语句,请使用db.execute直接执行 { db.execute("select * from customer", function(err, data){ console.log(data); cb(err); }); }, /* 执行事务 */ function(cb){ db.getConn(function(err, conn){ cb(err, conn); }); }, function(conn, cb) { conn.execute("BEGIN", function(err, data){ console.log(data); cb(err, conn); }); }, function(conn, cb) { conn.execute("DECLARE myportal CURSOR FOR select * from test", function(err, data){ console.log(data); cb(err, conn); }); }, function(conn, cb) { var hasNext = true; async.whilst( //条件 function() { return hasNext; //true,则第二个函数会继续执行,否则,调出循环 }, function(whileCb) { //循环的主体 conn.execute("FETCH NEXT in myportal", function(err, data){ if(data && data.affected > 0) { console.log(data); } else { hasNext = false; } whileCb(err); }); }, function(err) { //here 如果条件不满足,或者发生异常 cb(err, conn); } ); }, function(conn, cb) { conn.execute("CLOSE myportal", function(err, data){ console.log(data); cb(err, conn); }); }, function(conn, cb) { conn.execute("END", function(err, data){ console.log(data); cb(err, conn); }); }], function (err, conn) { if(conn) { //使用完连接,记得归还给连接池 db.unLock(conn); } if(err) { console.log("the error is:"); console.error(err); }});
输出如下:
init success!create table test(id SERIAL primary key, index SERIAL , name text , description text );select * from test where (id = '3'){ affected: 0, rst: [] }update test set name = 'just a test.' where (id = '3'){ affected: 0, rst: [] }select * from test where (id = '3') order by id desc limit 10{ affected: 0, rst: [] }insert into test(name,description) values('liming','a''b'){ affected: 1, rst: [] }insert into test(name,description) values('liming','a''b') returning id{ affected: 1, rst: [ { id: 23 } ] }delete from test where (name = 'test222'){ affected: 0, rst: [] }{ affected: 1, rst: [ { id: 1, username: 'liming', password: '123456', reg_time: '2015-03-25 22:26:30', type: 1, status: 1 } ] }{ affected: 0, rst: [] }{ affected: 0, rst: [] }{ affected: 1, rst: [ { id: 18, index: 18, name: 'liming', description: 'a\'b' } ] }{ affected: 1, rst: [ { id: 19, index: 19, name: 'liming', description: 'a\'b' } ] }{ affected: 1, rst: [ { id: 20, index: 20, name: 'liming', description: 'a\'b' } ] }{ affected: 1, rst: [ { id: 21, index: 21, name: 'liming', description: 'a\'b' } ] }{ affected: 1, rst: [ { id: 22, index: 22, name: 'liming', description: 'a\'b' } ] }{ affected: 1, rst: [ { id: 23, index: 23, name: 'liming', description: 'a\'b' } ] }{ affected: 0, rst: [] }{ affected: 0, rst: [] }
- 自己实现PostgresQL的nodejs驱动,分享给大家
- 自己写的博客系统,分享给大家
- 自己学android收集 的 一些 资料,便于自己查询,也分享给大家
- 给大家推荐一个好的网络资源,分享给大家。。。
- 分享给大家一个嵌入式linux驱动的入门程序解析(源代码)
- 自己写了很久的.net论坛源代码分享给大家
- 给大家分享一款自己编写的“智能增量网站快速同步”软件
- AS3 FPS 需要自己也会,但这外国佬的代码简明,值得分享给大家。
- 给大家分享一下自己写的验证码api,有汉字、字母数字两类
- 记录自己在centos虚拟机搭建简易git服务器的过程,分享给大家
- 给大家分享网站源码有12.9G需要的自己去下载吧
- 自己写了一个带placeHolder的textView,分享给大家
- 记录自己在centos虚拟机搭建简易git服务器的过程,分享给大家
- IOS自己封装的异步下载(get)Block方式回调给大家分享下
- 转载的发现对自己非常有用,来分享给大家
- 分享给大家几个好玩的网站
- 转载的,给大家分享,,希望有用
- 非常好的学习网站,分享给大家
- easyui 初始属性设置
- MVC应用程序使用Web Services(asmx)
- HDU - 1081 To The Max
- NoClassDefFoundError: org/junit/runners/model/MultipleFailureException
- 单链表逆序循环和递归2种方式
- 自己实现PostgresQL的nodejs驱动,分享给大家
- 莆田系开战百度 谁动了谁的奶酪?
- C++11中的右值引用及move语义编程
- mysql常用重要参数
- JavaScript闭包
- 低耦合与高内聚——面向对象设计原则初探
- 素数筛选法
- jstat命令用法
- 常用的DOS命令