Permalink
Browse files

initial real commit

  • Loading branch information...
1 parent 7e12540 commit 75d6650e12284e917c7a6b6123683fb90b60a01a @sitepodmatt committed Jul 7, 2012
Showing with 204 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +84 −0 README
  3. +24 −0 exp/test.js
  4. +31 −0 index.js
  5. +23 −0 package.json
  6. +41 −0 test/simple.js
View
@@ -0,0 +1 @@
+node_modules/
View
84 README
@@ -0,0 +1,84 @@
+node-postgres-hstore
+======
+
+Provides basic hstore parsing and stringify methods (stringify / parse) for
+use with hstore datatype in postgres 9.0+. Intended to be used with
+node-postgres
+
+integration
+=======
+
+parser:
+there doesnt seem to be a clean hook point, the FAQ refers to a test that
+includes the pgtypes file via a relative path, I couldnt see anything on the
+primary pg object that we could use, so path hacking it is.
+
+A simple example of what you may have to do (see exp/test.js):
+
+``
+var pg = require('pg');
+var hstore = require('../index'); //your code = require('node-postgres-hstore')
+var path = require('path');
+
+var conString = "tcp://" + process.env.PGUSER + ":" +
+ process.env.PGPASSWORD + "@localhost/deroku";
+
+// SELECT oid FROM pg_type WHERE typname = 'hstore'
+
+var hstoreOid = 74144; // different for every db
+
+var pgTypes = require(path.join(path.dirname(require.resolve('pg')),'types'));
+pgTypes.setTypeParser(hstoreOid, hstore.parse)
+
+pg.connect(conString, function(err, client) {
+ var query = client.query("SELECT 'a => b'::hstore As test");
+ query.on('row', function(row) {
+ console.dir(row);
+ });
+ query.on('end', function(row) {
+ client.end();
+ process.exit();
+ })
+});
+``
+
+serialization:
+node-postgres doesnt have any extensions point for serialization, so you have to
+do this in your own layers, although it looks like it may come soon [query.js#L130](https://github.com/brianc/node-postgres/blob/master/lib/query.js#L130)
+
+``
+var hstore = require('node-postgres-hstore');
+var strOutput = hstore.stringify(payload);
+``
+
+future
+=======
+
+As of accb94b (07/07/12) the unit tests are failing, I suspect this is part of an
+overhaul as they target node v0.8.x. I will revisit once things have stablized
+again and attempt to expose a clean way to register parser, a way to register
+serializers, and possibly an explicit method to collect up the metadata for
+custom types (needs some though as we dont want to invisibly be hitting the db).
+
+install
+=======
+
+cd projectdir
+npm install --save node-postgres-hstore
+
+tests
+=======
+See test/simple.js
+git clone repo
+npm install --dev .
+npm test
+
+license
+=======
+The MIT License
+
+author
+=======
+[Twitter - @nonuby](http://www.twitter.com/nonuby)
+[Nonuby Blog](http://blog.nonuby.com/)
+
View
@@ -0,0 +1,24 @@
+var pg = require('pg');
+var hstore = require('../index'); //your code = require('node-postgres-hstore')
+var path = require('path');
+
+var conString = "tcp://" + process.env.PGUSER + ":" +
+ process.env.PGPASSWORD + "@localhost/deroku";
+
+// SELECT oid FROM pg_type WHERE typname = 'hstore'
+
+var hstoreOid = 74144; // different for every db
+
+var pgTypes = require(path.join(path.dirname(require.resolve('pg')),'types'));
+pgTypes.setTypeParser(hstoreOid, hstore.parse)
+
+pg.connect(conString, function(err, client) {
+ var query = client.query("SELECT 'a => b'::hstore As test");
+ query.on('row', function(row) {
+ console.dir(row);
+ });
+ query.on('end', function(row) {
+ client.end();
+ process.exit();
+ })
+});
View
@@ -0,0 +1,31 @@
+module.exports.parse = function(val) {
+
+ var pattern, re, result, match, key, value;
+
+ pattern = '("(?:\\\\\"|[^"])*?")\\s*=>\\s*((?:"(?:\\\\\"|[^"])*?")|NULL)';
+ re = new RegExp(pattern,'gi');
+
+ result = {};
+ match = null;
+
+ while((match = re.exec(val)) != null) {
+ key = JSON.parse(match[1]);
+ value = match[2] == "NULL" ? null : JSON.parse(match[2]);
+ result[key] = value;
+ }
+
+ return result;
+
+}
+
+module.exports.stringify = function(val) {
+
+ var result = Object.keys(val).map(function(key) {
+ var value = val[key];
+ value = value === null ? 'NULL' : JSON.stringify(value.toString());
+ return '"' + key + '" => ' + value;
+ }).join(', ');
+
+ return result;
+
+}
View
@@ -0,0 +1,23 @@
+{
+ "author": "Matt Freeman <matt@nonuby.com> (http://blog.nonuby.com)",
+ "name": "node-postgres-hstore",
+ "description": "hstore stringify and parse functions for node-postgres parser/serializing",
+ "version": "0.0.1",
+ "homepage": "http://www.github.com/nonuby/node-postgres-hstore",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/nonuby/node-postgres-hstore.git"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "underscore": "~1.3.3",
+ "mocha": "~1.3.0"
+ },
+ "scripts": {
+ "test": "node_modules/.bin/mocha --reporter spec test/simple.js"
+ },
+ "optionalDependencies": {},
+ "engines": {
+ "node": ">0.6.0"
+ }
+}
View
@@ -0,0 +1,41 @@
+var hstore = require('../index');
+var assert = require('assert');
+var deepEquals = require('underscore').isEqual;
+
+describe('hstore parsing and serialization', function() {
+
+ it('should stringify and parse correctly', function() {
+
+ var payload = {
+ name: 'Matt Freeman',
+ age: 29,
+ bio: "With a nested double quote \"",
+ bio2: "With two \" nested double quote \"",
+ isSane: true,
+ isMental: false,
+ job: null
+ };
+
+ // Pre-emption: WTF? expected is different?
+ // See readme.md, hstore is for storing string-string values with exception
+ // of null value. Unless you start creating your own serialization format
+ // for booleans/numbers/etc you dont know at output weather 'true' is
+ // 'true' string or true boolean. So we dont complicate things here, if your
+ // running into this look at JSON type in postgres 9.2 instead.
+ var expected = {
+ name: 'Matt Freeman',
+ age: '29',
+ bio: "With a nested double quote \"",
+ bio2: "With two \" nested double quote \"",
+ isSane: 'true',
+ isMental: 'false',
+ job: null
+ };
+
+ var strPayload = hstore.stringify(payload);
+ var deserializedPayload = hstore.parse(strPayload);
+
+ assert.ok(deepEquals(deserializedPayload, expected))
+ });
+
+});

0 comments on commit 75d6650

Please sign in to comment.