brianc/node-postgres — pull request #657 by brianc (2014-10-11 18:53:12+00:00)
Title: Rewrite native bindings

The native bindings needed a full rewrite. They were complex, poorly written, and slow.

I broke the core of the native bindings into a module [closely mirroring the C libpq api](https://github.com/brianc/node-libpq). On top of this I've built a [modernized, higher-level API to node-libpq](https://github.com/brianc/node-pg-native). Now node-postgres itself consumes [node-pg-native](https://github.com/brianc/node-pg-native) which in turn consumes [node-libpq](https://github.com/brianc/node-libpq). This provides a much more modularized approach to things and one I plan on continuing going forward.

### before merging:

I need to test on more operating systems and versions of PostgreSQL. If you have non-mission-critical software I'd really love it if you could test out [node-pg-native](https://github.com/brianc/node-pg-native) and help me shake out bugs there. It is now the underpinnings of the native portion of this module.

I need to benchmark the new native bindings. Initial benchmarks show them to be >50% faster than the current version.

I will use some sort of npm `beta` tag for the new version of node-postgres for a while.

### breaking changes:

1) `COPY TO / COPY FROM` streaming support has been removed. This feature was buggy within node-postgres itself and has been replaced by the much more battle tested [pg-copy-streams](https://github.com/brianc/node-pg-copy-streams) module. [pg-native](https://github.com/brianc/node-pg-native/blob/master/test/copy-from.js) also provides native copy streams through libpq. Finally I plan on doing more experimentation with low-level copy operations within [pg-pipe](https://github.com/brianc/node-pg-pipe) which allows me to use libpq to do some nice zero-copy operations in C++.

2) The native bindings will _not support_ multiple statements returning different result sets in the same query. Only the last query in each command will return results. Doing 'pipelining' of multiple select statements is bad practice and not supported by the PostgreSQL backend when using prepared or parameterized queries. If you want to do something like this:
```js
client.query('SELECT * FROM first_table; SELECT * FROM second_table')
```
And you want the results of both queries...use async and send two different queries. Multiple insert commands still work.

3) `singleRowMode` in libpq is not yet supported. It only works on PostgreSQL 9.3 anyways. If you want to stream a large batch of query results without exploding your memory space it is __highly recommended__ you use [pg-cursor](https://github.com/brianc/node-pg-cursor) or [pg-query-stream](https://github.com/brianc/node-pg-query-stream). There is really no good way to support streaming rows from libpq...even `singleRowMode` has no concept of back pressure.

#### future plans:

The documentation is becoming a bit of a mess. I need to sit down and spend some time cleaning it up and modernizing it. Thanks for your patience when you wade through it now. :smile:

I want to break out the JavaScript [connection class](https://github.com/brianc/node-postgres/blob/master/lib/connection.js) into its own module. I want to build a new JavaScript higher level module to consume the connection in the same way node-pg-native consumes node-libpq.

I plan on making the native bindings an _optional_ install instead of installing them by default. Much in the way [node-redis](https://github.com/mranney/node_redis#redis---a-nodejs-redis-client) uses hiredis if it is installed. This will cut down on a lot of support issues I have where someone does not have access to a compiler or PostgreSQL headers and so their installation fails even though they have a perfectly usable, production-grade client installed in pure node.js.

Long term I see node-postgres being sort of a meta-package that glues together a bunch of smaller modules and provides the API it always has -- warts and all -- for maximum backwards compatibility. I know how annoying it is to have a boring, core piece of your infrastructure modules breaking compatibility for less than critical reasons & leaving you faced with the choice of either a painful, error-prone upgrade to get new functionality, or leaving you stuck on an old version for a long time. I have and will always strive to keep breaking changes to an absolute minimum. The smaller modules can be used when only some of the features are required, and their APIs can be simpler to learn and easier to evolve.