Comparing version 2.4.0 to 2.5.0
@@ -10,3 +10,4 @@ ## Connecting | ||
poolSize: 20 | ||
} | ||
}, | ||
enhancedFunctions: true | ||
}, function (err, db) { | ||
@@ -25,1 +26,5 @@ // db contains your tables, views, and functions | ||
documentation. | ||
`enhancedFunctions` is an experimental setting that allows functions to return | ||
a value matching their return type rather than a set of rows, see | ||
[Function Invocation](functions.md#function-invocation). |
@@ -50,2 +50,35 @@ ## Function Loading | ||
### Experimental: Enhanced Functions | ||
Massive can interpret the return types of functions, however this breaks backwards compatibility and thus must be opted into with setting `enhancedFunctions: true`. | ||
For example, if you have this [getRandomNumber function](https://xkcd.com/221/): | ||
```sql | ||
create function myschema."getRandomNumber"() | ||
returns integer as $$ | ||
select 4; -- chosen by fair dice roll. | ||
-- guaranteed to be random. | ||
$$ language sql; | ||
``` | ||
Without `enhancedFunctions` you'd get the same results as a regular table fetch - a set of rows: `[{"getRandomNumber": 4}]`. | ||
With `enhancedFunctions: true`, you'd get simply the result of the function: `4`. | ||
```js | ||
var massive = require("massive"); | ||
massive.connect({ | ||
connectionString: "postgres://localhost/massive", | ||
enhancedFunctions: true // Enable return type honoring | ||
}, function(err, db) { | ||
db.getRandomNumber(function(err, randomNumber) { | ||
//randomNumber is the integer 4 | ||
}); | ||
}); | ||
``` | ||
This also works for text, arrays, JSON, text domains and some other types. If it doesn't work for your use case, please raise an issue (or a PR!); we're aware of some restrictions due to [how the pg module currently handles types](https://github.com/brianc/node-postgres/issues/986). | ||
## Parameters | ||
@@ -52,0 +85,0 @@ Many, if not most, functions will expect some sort of input. |
@@ -17,2 +17,3 @@ var Runner = require("./lib/runner"); | ||
this.scriptsDir = args.scripts || process.cwd() + "/db"; | ||
this.enhancedFunctions = args.enhancedFunctions || false; | ||
@@ -444,3 +445,5 @@ var runner = new Runner(args.connectionString, args.defaults); | ||
name : fn.name, | ||
db : self | ||
db : self, | ||
singleRow: self.enhancedFunctions && fn.return_single_row, | ||
singleValue: self.enhancedFunctions && fn.return_single_value | ||
}); | ||
@@ -447,0 +450,0 @@ |
var _ = require("underscore")._; | ||
var util = require('util'); | ||
var Entity = require('./entity'); | ||
var Transform = require('stream').Transform; | ||
var inherits = require('util').inherits; | ||
// Takes a single-key object like {"foo": 27} and just returns the 27 part | ||
function _processSingleValue(data) { | ||
if (!_.isNull(data)) { | ||
var keys = Object.keys(data); | ||
if (keys.length != 1) { | ||
throw new Error("Was expecting just one value"); | ||
} | ||
data = data[keys[0]]; | ||
} | ||
return data; | ||
} | ||
function SingleValueStream(options) { | ||
if (!(this instanceof SingleValueStream)) { | ||
return new SingleValueStream(options); | ||
} | ||
if (!options) { | ||
options = {}; | ||
} | ||
options.objectMode = true; | ||
Transform.call(this, options); | ||
} | ||
inherits(SingleValueStream, Transform); | ||
SingleValueStream.prototype._transform = function _transform(obj, encoding, callback) { | ||
try { | ||
obj = _processSingleValue(obj); | ||
} catch(err) { | ||
return callback(err); | ||
} | ||
this.push(obj); | ||
callback(); | ||
}; | ||
/** | ||
@@ -13,2 +50,4 @@ * An executable function or script. | ||
this.filePath = args.filePath; | ||
this.singleRow = args.singleRow; | ||
this.singleValue = args.singleValue; | ||
}; | ||
@@ -52,6 +91,38 @@ | ||
var singleRow = this.singleRow && !opts.stream; | ||
var singleValue = this.singleValue; | ||
if (opts.stream) { | ||
this.db.stream(this.sql, params, null, next); | ||
this.db.stream(this.sql, params, null, function (err, stream) { | ||
if (err) return next(err); | ||
if (singleValue) { | ||
var singleValueTransform = SingleValueStream(); | ||
return next(null, stream.pipe(singleValueTransform)); | ||
} else { | ||
return next(null, stream); | ||
} | ||
}); | ||
} else { | ||
this.db.query(this.sql, params, null, next); | ||
this.db.query(this.sql, params, null, function (err, rawData) { | ||
var data = rawData; | ||
if (err) return next(err); | ||
try { | ||
if (singleRow) { | ||
if (!Array.isArray(data)) { | ||
return next(new Error("Was expecting an array")); | ||
} | ||
data = data[0] || null; | ||
if (singleValue) { | ||
data = _processSingleValue(data); | ||
} | ||
} else { | ||
if (singleValue) { | ||
data = data.map(_processSingleValue); | ||
} | ||
} | ||
} catch (e) { | ||
err = e; | ||
} | ||
return next(err, data); | ||
}); | ||
} | ||
@@ -58,0 +129,0 @@ }; |
{ | ||
"name": "massive", | ||
"version": "2.4.0", | ||
"version": "2.5.0", | ||
"description": "A small query tool for Postgres that embraces json and makes life simpler", | ||
@@ -36,3 +36,3 @@ "main": "index.js", | ||
"deasync": "^0.1.1", | ||
"glob": "^4.4.1", | ||
"glob": "^7.0.5", | ||
"pg": "^4.5.5", | ||
@@ -46,3 +46,3 @@ "pg-query-stream": "^0.7.0", | ||
"istanbul": "^0.4.2", | ||
"mocha": "^2.1.0", | ||
"mocha": "^2.5.3", | ||
"sinon": "^1.12.2" | ||
@@ -49,0 +49,0 @@ }, |
Sorry, the diff of this file is not supported yet
115124
1581
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
- Removedglob@4.5.3(transitive)
- Removedminimatch@2.0.10(transitive)
Updatedglob@^7.0.5