不要怂,就是干,撸起袖子干!

Commit 6f46f980 by Mick Hansen

Merge pull request #3120 from tadman/master

Improvements to Postgres function escaping, use dynamic delimiter to avoid conflict with data
2 parents a12e9d74 e95823bf
......@@ -210,9 +210,11 @@ module.exports = (function() {
//options.exception = 'WHEN unique_violation THEN NULL;';
//valueQuery = 'CREATE OR REPLACE FUNCTION pg_temp.testfunc() RETURNS SETOF <%= table %> AS $body$ BEGIN RETURN QUERY ' + valueQuery + '; EXCEPTION ' + options.exception + ' END; $body$ LANGUAGE plpgsql; SELECT * FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();';
// >= 9.2
// >= 9.2 - Use a UUID but prefix with 'func_' (numbers first not allowed)
var delimiter = '$func_' + Utils.generateUUID().replace(/-/g, '') + '$';
options.exception = 'WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL;';
valueQuery = 'CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response <%= table %>, OUT sequelize_caught_exception text) RETURNS RECORD AS $$ BEGIN ' + valueQuery + ' INTO response; EXCEPTION ' + options.exception + ' END $$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc()';
valueQuery = 'CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response <%= table %>, OUT sequelize_caught_exception text) RETURNS RECORD AS ' + delimiter + ' BEGIN ' + valueQuery + ' INTO response; EXCEPTION ' + options.exception + ' END ' + delimiter + ' LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc()';
}
if (this._dialect.supports['ON DUPLICATE KEY'] && options.onDuplicate) {
......@@ -241,12 +243,7 @@ module.exports = (function() {
identityWrapperRequired = true;
}
value = this.escape(value, (modelAttributeMap && modelAttributeMap[key]) || undefined);
if (options.exception) {
// $ inside value strings are illegal when using $$ as literal strings/delimiters for function bodys
value = value.toString().replace(/\$/g, '\\$');
}
values.push(value);
values.push(this.escape(value, (modelAttributeMap && modelAttributeMap[key]) || undefined));
}
}
}
......
......@@ -227,7 +227,7 @@ if (dialect.match(/^postgres/)) {
});
});
it('should be ablo to query using dot syntax', function() {
it('should be able to query using dot syntax', function() {
var self = this;
return this.sequelize.Promise.all([
......@@ -240,6 +240,44 @@ if (dialect.match(/^postgres/)) {
expect(user.emergency_contact.name).to.equal('joe');
});
});
it('should be able to store values that require JSON escaping', function() {
var self = this;
var text = "Multi-line '$string' needing \"escaping\" for $$ and $1 type values";
return this.User.create({ username: 'swen', emergency_contact: { value: text } })
.then(function(user) {
expect(user.isNewRecord).to.equal(false);
})
.then(function() {
return self.User.find({ where: { username: 'swen' } });
})
.then(function() {
return self.User.find({ where: sequelize.json('emergency_contact.value', text) });
})
.then(function(user) {
expect(user.username).to.equal('swen');
});
});
it('should be able to findOrCreate with values that require JSON escaping', function() {
var self = this;
var text = "Multi-line '$string' needing \"escaping\" for $$ and $1 type values";
return this.User.findOrCreate({ where: { username: 'swen' }, defaults: { emergency_contact: { value: text } } })
.then(function(user) {
expect(!user.isNewRecord).to.equal(true);
})
.then(function() {
return self.User.find({ where: { username: 'swen' } });
})
.then(function() {
return self.User.find({ where: sequelize.json('emergency_contact.value', text) });
})
.then(function(user) {
expect(user.username).to.equal('swen');
});
});
});
describe('hstore', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!