diff --git a/.travis.yml b/.travis.yml index b13a0fe..e72031f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: - 0.8 + - 0.9 before_script: - node script/create-test-tables.js pg://postgres@127.0.0.1:5432/postgres diff --git a/lib/client.js b/lib/client.js index bd03425..75c5035 100644 --- a/lib/client.js +++ b/lib/client.js @@ -10,6 +10,8 @@ var Connection = require(__dirname + '/connection'); var CopyFromStream = require(__dirname + '/copystream').CopyFromStream; var CopyToStream = require(__dirname + '/copystream').CopyToStream; +var deprecate = require('deprecate'); + var Client = function(config) { EventEmitter.call(this); @@ -256,11 +258,23 @@ Client.prototype.query = function(config, values, callback) { //prevents client from otherwise emitting 'drain' event until 'resumeDrain' is //called Client.prototype.pauseDrain = function() { + deprecate('Client.prototype.pauseDrain is deprecated and will be removed it v1.0.0 (very soon)', + 'please see the following for more details:', + 'https://github.com/brianc/node-postgres/wiki/pg', + 'https://github.com/brianc/node-postgres/issues/227', + 'https://github.com/brianc/node-postgres/pull/274', + 'feel free to get in touch via github if you have questions'); this._drainPaused = 1; }; //resume raising 'drain' event Client.prototype.resumeDrain = function() { + deprecate('Client.prototype.resumeDrain is deprecated and will be removed it v1.0.0 (very soon)', + 'please see the following for more details:', + 'https://github.com/brianc/node-postgres/wiki/pg', + 'https://github.com/brianc/node-postgres/issues/227', + 'https://github.com/brianc/node-postgres/pull/274', + 'feel free to get in touch via github if you have questions'); if(this._drainPaused > 1) { this.emit('drain'); } diff --git a/lib/defaults.js b/lib/defaults.js index 738908e..9f3cbb9 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -33,3 +33,12 @@ module.exports = { //pool log function / boolean poolLog: false }; + +var deprecate = require('deprecate'); +//getter/setter to disable deprecation warnings +module.exports.__defineGetter__("hideDeprecationWarnings", function() { + return deprecate.silent; +}); +module.exports.__defineSetter__("hideDeprecationWarnings", function(val) { + deprecate.silence = val; +}); diff --git a/lib/deprecate.js b/lib/deprecate.js new file mode 100644 index 0000000..c587623 --- /dev/null +++ b/lib/deprecate.js @@ -0,0 +1,25 @@ +var os = require('os'); +var defaults = require(__dirname + '/defaults'); + +var hits = { +}; +var deprecate = module.exports = function(methodName, message) { + if(defaults.hideDeprecationWarnings) return; + if(hits[deprecate.caller]) return; + hits[deprecate.caller] = true; + process.stderr.write(os.EOL); + process.stderr.write('\x1b[31;1m'); + process.stderr.write('WARNING!!'); + process.stderr.write(os.EOL); + process.stderr.write(methodName); + process.stderr.write(os.EOL); + for(var i = 1; i < arguments.length; i++) { + process.stderr.write(arguments[i]); + process.stderr.write(os.EOL); + } + process.stderr.write('\x1b[0m'); + process.stderr.write(os.EOL); + process.stderr.write("You can silence these warnings with `require('pg').defaults.hideDeprecationWarnings = true`"); + process.stderr.write(os.EOL); + process.stderr.write(os.EOL); +}; diff --git a/lib/pool.js b/lib/pool.js index 15cf77e..cd53820 100644 --- a/lib/pool.js +++ b/lib/pool.js @@ -3,6 +3,8 @@ var EventEmitter = require('events').EventEmitter; var defaults = require(__dirname + '/defaults'); var genericPool = require('generic-pool'); +var deprecate = require('deprecate'); + var pools = { //dictionary of all key:pool pairs all: {}, @@ -77,6 +79,14 @@ var errorMessage = [ ].join(require('os').EOL); var oldConnect = function(pool, client, cb) { + deprecate('pg.connect(function(err, client) { ...}) is deprecated and will be removed it v1.0.0 (very soon)', + 'instead, use pg.connect(function(err, client, done) { ... })', + 'automatic releasing of clients back to the pool was a mistake and will be removed', + 'please see the following for more details:', + 'https://github.com/brianc/node-postgres/wiki/pg', + 'https://github.com/brianc/node-postgres/issues/227', + 'https://github.com/brianc/node-postgres/pull/274', + 'feel free to get in touch via github if you have questions'); var tid = setTimeout(function() { console.error(errorMessage); }, alarmDuration); diff --git a/lib/types/binaryParsers.js b/lib/types/binaryParsers.js index 7f0a89c..b1bfdd3 100644 --- a/lib/types/binaryParsers.js +++ b/lib/types/binaryParsers.js @@ -1,3 +1,5 @@ +var deprecate = require('deprecate'); + var parseBits = function(data, bits, offset, invert, callback) { offset = offset || 0; invert = invert || false; @@ -45,6 +47,12 @@ var parseBits = function(data, bits, offset, invert, callback) { }; var parseFloatFromBits = function(data, precisionBits, exponentBits) { + deprecate('parsing and returning floats from PostgreSQL server is deprecated', + 'JavaScript has a hard time with floats and there is precision loss which can cause', + 'unexpected, hard to trace, potentially bad bugs in your program', + 'for more information see the following:', + 'https://github.com/brianc/node-postgres/pull/271', + 'in node-postgres v1.0.0 all floats & decimals will be returned as strings'); var bias = Math.pow(2, exponentBits - 1) - 1; var sign = parseBits(data, 1); var exponent = parseBits(data, exponentBits, 1); diff --git a/lib/types/textParsers.js b/lib/types/textParsers.js index e5d2a74..77d2a48 100644 --- a/lib/types/textParsers.js +++ b/lib/types/textParsers.js @@ -1,3 +1,5 @@ +var deprecate = require('deprecate'); + var arrayParser = require(__dirname + "/arrayParser.js"); //parses PostgreSQL server formatted date strings into javascript date objects @@ -76,6 +78,13 @@ var parseIntegerArray = function(val) { }; var parseFloatArray = function(val) { + deprecate('parsing and returning floats from PostgreSQL server is deprecated', + 'JavaScript has a hard time with floats and there is precision loss which can cause', + 'unexpected, hard to trace, potentially bad bugs in your program', + 'for more information see the following:', + 'https://github.com/brianc/node-postgres/pull/271', + 'in node-postgres v1.0.0 all floats & decimals will be returned as strings', + 'feel free to get in touch via a github issue if you have any questions'); if(!val) { return null; } var p = arrayParser.create(val, function(entry){ if(entry !== null) { @@ -162,24 +171,27 @@ var parseInteger = function(val) { return parseInt(val, 10); }; +var parseFloatAndWarn = function(val) { + deprecate('parsing and returning floats from PostgreSQL server is deprecated', + 'JavaScript has a hard time with floats and there is precision loss which can cause', + 'unexpected, hard to trace, potentially bad bugs in your program', + 'for more information see the following:', + 'https://github.com/brianc/node-postgres/pull/271', + 'in node-postgres v1.0.0 all floats & decimals will be returned as strings'); + return parseFloat(val); +}; + var init = function(register) { register(20, parseInteger); register(21, parseInteger); register(23, parseInteger); register(26, parseInteger); //TODO remove for v1.0 - register(1700, function(val){ - if(val.length > maxLen) { - console.warn( - 'WARNING: value %s is longer than max supported numeric value in ' + - 'javascript. Possible data loss', val); - } - return parseFloat(val); - }); + register(1700, parseFloatAndWarn); //TODO remove for v1.0 - register(700, parseFloat); + register(700, parseFloatAndWarn); //TODO remove for v1.0 - register(701, parseFloat); + register(701, parseFloatAndWarn); register(16, parseBool); register(1082, parseDate); // date register(1114, parseDate); // timestamp without timezone diff --git a/package.json b/package.json index bb347f1..cd6d8f5 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,35 @@ -{ "name": "pg", +{ + "name": "pg", "version": "0.13.3", "description": "PostgreSQL client - pure javascript & libpq with the same API", - "keywords" : ["postgres", "pg", "libpq", "postgre", "database", "rdbms"], + "keywords": [ + "postgres", + "pg", + "libpq", + "postgre", + "database", + "rdbms" + ], "homepage": "http://github.com/brianc/node-postgres", - "repository" : { - "type" : "git", - "url" : "git://github.com/brianc/node-postgres.git" + "repository": { + "type": "git", + "url": "git://github.com/brianc/node-postgres.git" }, - "author" : "Brian Carlson ", - "main" : "./lib", - "dependencies" : { - "generic-pool" : "2.0.2" + "author": "Brian Carlson ", + "main": "./lib", + "dependencies": { + "generic-pool": "2.0.2", + "deprecate": "~0.1.0" }, - "devDependencies" : { - "jshint" : "git://github.com/jshint/jshint.git" + "devDependencies": { + "jshint": "git://github.com/jshint/jshint.git" }, - "scripts" : { - "test" : "make test-all connectionString=pg://postgres@localhost:5432/postgres", + "scripts": { + "test": "make test-all connectionString=pg://postgres@localhost:5432/postgres", "prepublish": "rm -r build || (exit 0)", - "install" : "node-gyp rebuild || (exit 0)" + "install": "node-gyp rebuild || (exit 0)" }, - "engines" : { "node": ">= 0.8.0" } + "engines": { + "node": ">= 0.8.0" + } } diff --git a/src/binding.cc b/src/binding.cc index 5d17d8d..a2d2d27 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -249,6 +249,8 @@ public: bool ioInitialized_; bool copyOutMode_; bool copyInMode_; + bool reading_; + bool writing_; Connection () : ObjectWrap () { connection_ = NULL; @@ -256,6 +258,8 @@ public: ioInitialized_ = false; copyOutMode_ = false; copyInMode_ = false; + reading_ = false; + writing_ = false; TRACE("Initializing ev watchers"); read_watcher_.data = this; write_watcher_.data = this; @@ -304,6 +308,7 @@ protected: int Send(const char *queryText) { + TRACE("js::Send") int rv = PQsendQuery(connection_, queryText); StartWrite(); return rv; @@ -311,6 +316,7 @@ protected: int SendQueryParams(const char *command, const int nParams, const char * const *paramValues) { + TRACE("js::SendQueryParams") int rv = PQsendQueryParams(connection_, command, nParams, NULL, paramValues, NULL, NULL, 0); StartWrite(); return rv; @@ -318,6 +324,7 @@ protected: int SendPrepare(const char *name, const char *command, const int nParams) { + TRACE("js::SendPrepare") int rv = PQsendPrepare(connection_, name, command, nParams, NULL); StartWrite(); return rv; @@ -430,7 +437,7 @@ protected: if(PQconsumeInput(connection_) == 0) { End(); EmitLastError(); - LOG("Something happened, consume input is 0"); + //LOG("Something happened, consume input is 0"); return; } @@ -476,7 +483,8 @@ protected: if(revents & UV_WRITABLE) { TRACE("revents & UV_WRITABLE"); if (PQflush(connection_) == 0) { - StopWrite(); + //nothing left to write, poll the socket for more to read + StartRead(); } } } @@ -669,12 +677,10 @@ private: switch(status) { case PGRES_POLLING_READING: TRACE("Polled: PGRES_POLLING_READING"); - StopWrite(); StartRead(); break; case PGRES_POLLING_WRITING: TRACE("Polled: PGRES_POLLING_WRITING"); - StopRead(); StartWrite(); break; case PGRES_POLLING_FAILED: @@ -712,30 +718,42 @@ private: void StopWrite() { - TRACE("Stoping write watcher"); + TRACE("write STOP"); if(ioInitialized_) { uv_poll_stop(&write_watcher_); + writing_ = false; } } void StartWrite() { - TRACE("Starting write watcher"); + TRACE("write START"); + if(reading_) { + TRACE("stop READ to start WRITE"); + StopRead(); + } uv_poll_start(&write_watcher_, UV_WRITABLE, io_event); + writing_ = true; } void StopRead() { - TRACE("Stoping read watcher"); + TRACE("read STOP"); if(ioInitialized_) { uv_poll_stop(&read_watcher_); + reading_ = false; } } void StartRead() { - TRACE("Starting read watcher"); + TRACE("read START"); + if(writing_) { + TRACE("stop WRITE to start READ"); + StopWrite(); + } uv_poll_start(&read_watcher_, UV_READABLE, io_event); + reading_ = true; } //Converts a v8 array to an array of cstrings //the result char** array must be free() when it is no longer needed diff --git a/test/test-helper.js b/test/test-helper.js index 4ad7b7b..398bc86 100644 --- a/test/test-helper.js +++ b/test/test-helper.js @@ -7,6 +7,8 @@ var BufferList = require(__dirname+'/buffer-list') var Connection = require(__dirname + '/../lib/connection'); +require(__dirname + '/../lib').defaults.hideDeprecationWarnings = true; + Client = require(__dirname + '/../lib').Client; process.on('uncaughtException', function(d) {