Comparing version 5.8.0 to 5.9.0
@@ -1,5 +0,28 @@ | ||
# Change Log | ||
# Changelog | ||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. | ||
## [5.9.0](https://gitlab.com/dmfay/massive-js/compare/v5.8.0...v5.9.0) (2019-05-16) | ||
### Bug Fixes | ||
* always generate function invocation sql to handle overloads properly ([0b60dcd](https://gitlab.com/dmfay/massive-js/commit/0b60dcd)) | ||
* **deps:** update dependency glob to v7.1.4 ([587fcd1](https://gitlab.com/dmfay/massive-js/commit/587fcd1)) | ||
* **deps:** update dependency pg-promise to v8.7.0 ([800c093](https://gitlab.com/dmfay/massive-js/commit/800c093)) | ||
* **deps:** update dependency pg-promise to v8.7.1 ([5d418f1](https://gitlab.com/dmfay/massive-js/commit/5d418f1)) | ||
* **deps:** update dependency pg-promise to v8.7.2 ([3374298](https://gitlab.com/dmfay/massive-js/commit/3374298)) | ||
### Features | ||
* invoke procedures like functions (fixes [#679](https://gitlab.com/dmfay/massive-js/issues/679)) ([aa18183](https://gitlab.com/dmfay/massive-js/commit/aa18183)) | ||
### Tests | ||
* remove superfluous check ([d387aec](https://gitlab.com/dmfay/massive-js/commit/d387aec)) | ||
# [5.8.0](https://gitlab.com/dmfay/massive-js/compare/v5.7.7...v5.8.0) (2019-04-30) | ||
@@ -6,0 +29,0 @@ |
@@ -29,17 +29,17 @@ 'use strict'; | ||
* table, view, and function visible to the connection's user. | ||
* @param {String} loader.scripts - Override the Massive script file location | ||
* @param {String} [loader.scripts] - Override the Massive script file location | ||
* (default ./db). | ||
* @param {String} loader.documentPkType - Override default data type (serial), | ||
* @param {String} [loader.documentPkType] - Override default data type (serial), | ||
* set for DocumentTable primary key 'id', e.g. 'uuid' | ||
* @param {String} loader.uuidVersion - If documentPkType is set to 'uuid', set which UUID version to use, | ||
* @param {String} [loader.uuidVersion] - If documentPkType is set to 'uuid', set which UUID version to use, | ||
* e.g. 'uuid_generate_v1', 'uuid_generate_v4', etc. Default is 'uuid_generate_v4' | ||
* @param {Array|String} loader.allowedSchemas - Table/view schema whitelist. | ||
* @param {Array|String} loader.whitelist - Table/view name whitelist. | ||
* @param {Array|String} loader.blacklist - Table/view name blacklist. | ||
* @param {Array|String} loader.exceptions - Table/view blacklist exceptions. | ||
* @param {Array|String} loader.functionWhitelist - Function name whitelist. | ||
* @param {Array|String} loader.functionBlacklist - Function name blacklist. | ||
* @param {Boolean} loader.enhancedFunctions - Streamline function return values. | ||
* @param {Boolean} loader.excludeFunctions - Ignore functions entirely. | ||
* @param {Boolean} loader.excludeMatViews - Ignore materialized views. | ||
* @param {Array|String} [loader.allowedSchemas] - Table/view schema whitelist. | ||
* @param {Array|String} [loader.whitelist] - Table/view name whitelist. | ||
* @param {Array|String} [loader.blacklist] - Table/view name blacklist. | ||
* @param {Array|String} [loader.exceptions] - Table/view blacklist exceptions. | ||
* @param {Array|String} [loader.functionWhitelist] - Function name whitelist. | ||
* @param {Array|String} [loader.functionBlacklist] - Function name blacklist. | ||
* @param {Boolean} [loader.enhancedFunctions] - Streamline function return values. | ||
* @param {Boolean} [loader.excludeFunctions] - Ignore functions entirely. | ||
* @param {Boolean} [loader.excludeMatViews] - [DEPRECATED] Ignore materialized views. | ||
* @param {Object} [driverConfig] - A pg-promise configuration object. | ||
@@ -218,2 +218,6 @@ */ | ||
this.currentSchema = current_schema; | ||
}), | ||
this.query('SHOW server_version') | ||
.then(([{server_version}]) => { | ||
this.serverVersion = server_version; | ||
}) | ||
@@ -296,2 +300,34 @@ ]; | ||
/** | ||
* Determine whether the connected PostgreSQL server is of at least the | ||
* specified version. Used for automatically enabling features in the loaders, | ||
* notably procedures (in the function loader) and materialized views. | ||
* | ||
* @param {String} target - Target version to match or exceed. | ||
* @return {Boolean} Whether the target version has been matched or exceeded. | ||
*/ | ||
Database.prototype.serverAtLeast = function (target) { | ||
const tokens = target.split('.'); | ||
return this.serverVersion.split('.').reduce((acc, token, i) => { | ||
const c = Number(token); | ||
const t = Number(tokens[i]) || 0; | ||
if (c > t) { | ||
// candidate segment > target segment: if we've already gone negative, | ||
// it's too late (the target version had a higher value in an earlier | ||
// segment, meaning it's higher overall). Otherwise, we're still good. | ||
return acc < 0 ? -1 : 1; | ||
} else if (c < t) { | ||
// candidate segment < target segment: as long as we've gone positive, | ||
// rather than just matched segment for segment, we're still positive; | ||
// otherwise, the target version is higher overall. | ||
return acc > 0 ? 1 : -1; | ||
} | ||
// candidate segment = target segment: nothing changes. | ||
return acc; | ||
}, 0) > -1; // at 0 the target has been met; at 1 it's been exceeded | ||
}; | ||
/** | ||
* List all the tables attached to the connected instance. | ||
@@ -298,0 +334,0 @@ * |
@@ -16,10 +16,12 @@ 'use strict'; | ||
* @param {Object} spec.db - A {@linkcode Database}. | ||
* @param {String} spec.name - The table or view's name. | ||
* @param {String} spec.schema - The name of the schema owning the table or | ||
* @param {String} spec.name - The name of the function or script. | ||
* @param {String} spec.schema - The owning schema or file path of the function | ||
* or script, respectively. | ||
* @param {String|QueryFile} spec.sql - A function invocation statement or a | ||
* pg-promise QueryFile. | ||
* @param {Number} spec.paramCount - Number of parameters the executable | ||
* expects. | ||
* @param {Boolean} spec.isVariadic - Whether a database function accepts | ||
* variable-length argument lists as the last parameter. | ||
* @param {Number} spec.arity - Number of parameters the executable expects, | ||
* only for QueryFiles. | ||
* @param {Boolean} spec.isVariadic - Whether the executable accepts | ||
* variable-length argument lists as the last parameter, only for database | ||
* functions. | ||
* @param {Boolean} spec.enhancedFunctions - True to enable single row/value | ||
@@ -37,4 +39,5 @@ * results processing. | ||
this.isDatabaseFunction = Object.prototype.hasOwnProperty.call(spec, 'isVariadic'); | ||
this.paramCount = spec.paramCount; // this actually only matters for QueryFiles since functions can have overloads | ||
this.arity = spec.arity; // only for scripts | ||
this.isVariadic = !!spec.isVariadic; // only for db functions | ||
this.isProcedure = spec.kind === 'p'; // only for db functions | ||
this.singleRow = spec.enhancedFunctions && spec.singleRow; | ||
@@ -59,6 +62,6 @@ this.singleValue = spec.enhancedFunctions && spec.singleValue; | ||
if (_.isArray(arguments[0]) || (_.isPlainObject(arguments[0]) && !_.isString(this.sql) && !!this.paramCount)) { | ||
// arrays are always a full parameter list | ||
// objects are never parameters for database functions, only QueryFiles | ||
// (and only if it takes parameters) | ||
// arrays as the first argument are always a full parameter list, for | ||
// functions and scripts alike; for scripts with arity > 0, an object as the | ||
// first argument may be a named parameter block | ||
if (_.isArray(arguments[0]) || (!this.isDatabaseFunction && this.arity > 0 && _.isPlainObject(arguments[0]) && !_.isString(this.sql))) { | ||
args = arguments[0]; | ||
@@ -69,18 +72,23 @@ opts = _.defaults(_.last(arguments), opts); | ||
if (_.isString(this.sql) && _.isPlainObject(_.last(args))) { | ||
// function overloads mess with paramCount, but since they can't use | ||
// named parameters we can just check to see if there's an object | ||
// functions don't have an arity to check, but since they can't use named | ||
// parameters we can just check for an object at the end of the params; for | ||
// scripts, options make the arguments array longer than the arity. | ||
if ((this.isDatabaseFunction && _.isPlainObject(_.last(args)) || | ||
(!this.isDatabaseFunction && arguments.length === this.arity + 1))) { | ||
opts = _.defaults(args.pop(), opts); | ||
} else if (arguments.length === this.paramCount + 1) { | ||
opts = _.defaults(args.pop(), opts); | ||
} | ||
} | ||
if (this.isVariadic) { | ||
// for variadic functions we have to build the statement dynamically to | ||
// handle however many arguments we have at call time | ||
if (statement === undefined) { | ||
// functions can be overloaded or variadic, so we have to build the | ||
// statement dynamically to handle however many arguments are present at | ||
// call time | ||
const params = _.times(args.length, i => `$${i + 1}`).join(','); | ||
statement = `SELECT * FROM "${this.schema}"."${this.name}"(${params})`; | ||
if (this.isProcedure) { | ||
statement = `CALL "${this.schema}"."${this.name}"(${params})`; | ||
} else { | ||
statement = `SELECT * FROM "${this.schema}"."${this.name}"(${params})`; | ||
} | ||
} | ||
@@ -87,0 +95,0 @@ |
'use strict'; | ||
const _ = require('lodash'); | ||
exports = module.exports = function (db) { | ||
const file = db.serverAtLeast('11') ? 'functions.sql' : 'functions-legacy.sql'; | ||
exports = module.exports = function (db) { | ||
if (db.loader.excludeFunctions) { return db.$p.resolve([]); } | ||
return db.instance.query(db.loader.queryFiles['functions.sql'], db.loader).then(fns => { | ||
return fns.map(fn => { | ||
const params = _.times(fn.paramCount, i => `$${i + 1}`).join(','); | ||
fn.sql = `SELECT * FROM "${fn.schema}"."${fn.name}"(${params})`; | ||
return fn; | ||
}); | ||
}); | ||
return db.instance.query(db.loader.queryFiles[file], db.loader); | ||
}; |
@@ -35,5 +35,5 @@ 'use strict'; | ||
script.paramCount = (valuesMatch && valuesMatch.length || 0) + (namesMatch && namesMatch.length || 0); | ||
script.arity = (valuesMatch && valuesMatch.length || 0) + (namesMatch && namesMatch.length || 0); | ||
return script; | ||
})); |
'use strict'; | ||
exports = module.exports = function (db) { | ||
const file = db.loader.excludeMatViews ? 'views-legacy.sql' : 'views.sql'; | ||
const file = db.serverAtLeast('9.3') && db.loader.excludeMatViews !== true ? 'views.sql' : 'views-legacy.sql'; | ||
return db.instance.query(db.loader.queryFiles[file], db.loader); | ||
}; |
{ | ||
"name": "massive", | ||
"version": "5.8.0", | ||
"version": "5.9.0", | ||
"description": "A small query tool for Postgres that embraces json and makes life simpler", | ||
@@ -53,5 +53,5 @@ "homepage": "https://massivejs.org", | ||
"commander": "2.20.0", | ||
"glob": "7.1.3", | ||
"glob": "7.1.4", | ||
"lodash": "4.17.11", | ||
"pg-promise": "8.6.5", | ||
"pg-promise": "8.7.2", | ||
"pg-query-stream": "2.0.0" | ||
@@ -66,4 +66,4 @@ }, | ||
"mocha": "6.1.4", | ||
"nyc": "14.0.0", | ||
"standard-version": "5.0.2" | ||
"nyc": "14.1.1", | ||
"standard-version": "6.0.1" | ||
}, | ||
@@ -70,0 +70,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
145695
42
2533
+ Addedglob@7.1.4(transitive)
+ Addedpg@7.11.0(transitive)
+ Addedpg-minify@1.2.0(transitive)
+ Addedpg-promise@8.7.2(transitive)
- Removedglob@7.1.3(transitive)
- Removedpg@7.9.0(transitive)
- Removedpg-minify@1.0.0(transitive)
- Removedpg-promise@8.6.5(transitive)
Updatedglob@7.1.4
Updatedpg-promise@8.7.2