node-postgres/README.md

156 lines
5.2 KiB
Markdown
Raw Normal View History

2010-10-25 13:14:48 +08:00
#node-postgres
100% javascript. 100% async. 100% would love your contributions.
## Why?
As soon as I saw node.js for the first time I knew I had found
something lovely and simple and _just what I always wanted!_. So...I
2010-10-25 13:45:41 +08:00
poked around for a while. I was excited. I told my friend "ah man
the only thing holding node back is a really solid data access story."
I mean...let's put the NoSQL debate aside. Let's say for arguments
sake you have to run a query from node.js on PostgreSQL before the
last petal falls off the rose and you are stuck as a beast forever?
What if your entire production site depends on it? Well, fret no
more. And let [GastonDB](http://www.snipetts.com/ashley/mymusicals/disney/beauty-an-beast/images/gaston.gif) be vanquished.
2010-10-25 13:14:48 +08:00
I drew major inspiration from
[postgres-js](http://github.com/creationix/postgres-js). I didn't
just fork and contribute because it has
__0__ tests included with it and doesn't seem to be actively developed
anymore. I am not comfortable forking & playing with a project
2010-10-25 13:45:41 +08:00
without having a way to run a test suite, let alone using it in
production.
2010-10-25 13:14:48 +08:00
2010-10-25 13:45:41 +08:00
So...__boom__. I set out to write my own. I'm not working on anything
2010-10-25 13:14:48 +08:00
else in my spare time other than this. It's a labor of love. I'd
2010-10-25 13:45:41 +08:00
love for you to love it as well. Contribute. Fork, patch, and send
2010-10-25 13:14:48 +08:00
me a pull request. All I ask is everything you add you have complete
2010-10-25 13:52:46 +08:00
and possibly obsessive test coverage to back up.
2010-10-16 07:21:24 +08:00
2010-10-17 08:45:05 +08:00
## ALPHA version
2010-10-16 07:21:24 +08:00
2010-10-25 13:14:48 +08:00
Implemented in a fully TDD fashion. I'm aiming for
2010-10-23 07:26:18 +08:00
extremely high quality code, but first doing the implementation and
only refactoring after tests are in place.
2010-10-24 11:19:30 +08:00
### Connection
2010-10-17 08:45:05 +08:00
2010-10-25 13:52:46 +08:00
The connection object is a 1 to 1 mapping to the [postgres
client/server messaging protocol](http://developer.postgresql.org/pgdocs/postgres/protocol.html).
The __Connection_ object is mostly used by the Client object (which...I haven't yet
2010-10-25 13:36:35 +08:00
finished implementing) but you can do anything you want with PostgreSQL using
2010-10-24 11:19:30 +08:00
the connection object if you're really into that. I studied the
protocol for a while implementing this and the documentation is pretty
2010-10-25 13:52:46 +08:00
solid. If you're already familiar you should be right at home. Have
fun looking up the [oids for the datatypes in your bound queries](http://github.com/brianc/node-postgres/blob/master/script/list-db-types.js)
2010-10-25 13:14:48 +08:00
There are a few minor variations from the protocol:
2010-10-25 13:36:35 +08:00
- The connection only supports 'text' mode right now.
- Renamed 'passwordMessage' to 'password'
- Renamed 'startupMessage' to 'startup'
- Renamed 'errorResposne' to 'error'
- Renamed 'noticeResponce' to 'notice'
2010-10-25 13:14:48 +08:00
The reason for the renamings is 90% of the message names in the
protocol do no contain "message" "request" "response" or anything
similar, and I feel it's a bit redundant to send a "passwordMessage
2010-10-25 13:45:41 +08:00
message." But then again...[I do say ATM machine](http://en.wikipedia.org/wiki/RAS_syndrome).
2010-10-25 13:14:48 +08:00
Anyways...using a connection directly is a pretty verbose and
cumbersom affair. Here's an example of executing a prepared query
using the directly __Connection__ api in compliance with
PostgreSQL.
_note: this works and is taken directly from an integration test;
however, it doesn't even include error handling_
var con = new Connection({stream: new net.Stream()});
con.connect('5432','localhost');
con.once('connect', function() {
con.startup({
user: username,
database: database
});
con.once('readyForQuery', function() {
con.query('create temp table ids(id integer)');
con.once('readyForQuery', function() {
con.query('insert into ids(id) values(1); insert into ids(id) values(2);');
con.once('readyForQuery', function() {
con.parse({
text: 'select * from ids'
});
con.flush();
con.once('parseComplete', function() {
con.bind();
con.flush();
});
con.once('bindComplete', function() {
con.execute();
con.flush();
});
con.once('commandComplete', function() {
con.sync();
});
con.once('readyForQuery', function() {
con.end();
});
});
});
});
});
2010-09-29 11:09:21 +08:00
2010-10-24 11:19:30 +08:00
### Client
2010-10-23 07:26:18 +08:00
2010-10-25 13:14:48 +08:00
Basically a facade on top of the connection to provide a _much_ more
2010-10-24 11:19:30 +08:00
user friendly, "node style" interface for doing all the lovely things
you like with PostgreSQL.
2010-10-23 07:26:18 +08:00
2010-10-25 13:14:48 +08:00
Now that I've got the __Connection__ api in place, the bulk and meat of
the work is being done on the __Client__ to provide the best possible
API. Help? Yes please!
What I'd like is to simplify the above low level use with something
like this:
_note: this doesn't even __exist__ yet_
var client = new Client({
user: 'brian',
database: 'postgres',
});
client.query("create temp table ids(id integer)");
client.query("insert into ids(id) values(1)");
client.query("insert into ids(id) values(2)");
var query = client.query("select * from ids", function(row) {
row.fields[0] // <- that equals 1 the first time. 2 the second time.
});
query.on('end', function() {
client.end();
});
2010-10-23 07:26:18 +08:00
## TODO
2010-10-25 12:18:43 +08:00
- Error handling
2010-10-23 07:26:18 +08:00
- integration testing
2010-10-25 13:14:48 +08:00
- notificationp
2010-10-23 07:26:18 +08:00
- setting parameters
- connection pooling
- copy data
- connection pooling
2010-10-25 13:45:41 +08:00
- kiss the sky