Using prepared statements in runSql fails
See original GitHub issueMaybe the problem is there isn’t an example in the documentation for runSql, so maybe I just dont know how to call it using the ? replacement parameters mentioned.
Incidentally, the docs seems to be missing a comma for both runSql() and all(): i.e. runSql(sql, [params,] callback) and all(sql, [params,] callback) after the params]
I am trying to add a user and grant permissions, and since I dont want to do this for every db OUTSIDE of db-migrate (I just want it to happen magically), I’m putting it in db-migrate. (but whether or not that belongs in db-migrate is not the issue I need to discuss here).
Trying to use ? replacement params, seems to give an error:
The Error:
[ERROR] Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('readonly') IDENTIFIED BY ('specialpassword')' at line 1
The Migration script:
'use strict';
require('dotenv').config({silent: true, path: '.env'});
var async = require('async');
var dbm;
var type;
var seed;
/**
* We receive the dbmigrate dependency from dbmigrate initially.
* This enables us to not have to rely on NODE_PATH.
*/
exports.setup = function(options, seedLink) {
dbm = options.dbmigrate;
type = dbm.dataType;
seed = seedLink;
};
exports.up = function(db, callback) {
async.series([
db.runSql.bind(db, "CREATE USER '?' IDENTIFIED BY '?'", [process.env["MYSQL_USERNAME_READONLY"], process.env["MYSQL_PASSWORD_READONLY"]], callback),
db.runSql.bind(db, "GRANT SELECT ON * . * TO '?'", [process.env["MYSQL_USERNAME_READONLY"]], callback)
], callback);
};
exports.down = function(db, callback) {
async.series([
db.runSql.bind(db, "DROP USER '?'", [process.env["MYSQL_USERNAME_READONLY"]], callback)
], callback);
};
exports._meta = {
"version": 4
};
Dry Run:
db-migrate --dry-run up
[INFO] dry run
CREATE TABLE IF NOT EXISTS `migrations` (`id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, `name` VARCHAR (255) NOT NULL, `run_on` DATETIME NOT NULL);
SELECT * FROM `migrations` ORDER BY run_on DESC, name DESC;
SET AUTOCOMMIT=0;;
START TRANSACTION;;
CREATE USER '?' IDENTIFIED BY '?' [ [ 'readonly', 'specialpassword' ], [Function: r] ]
GRANT SELECT ON * . * TO '?' [ [ 'readonly' ], [Function: r] ]
INSERT INTO `migrations` (`name`, `run_on`) VALUES (?, ?) [ [ '/20161027150636-readonlyuser', '2016-10-27 11:07:05' ] ]
[INFO] Processed migration 20161027150636-readonlyuser
COMMIT;;
[INFO] Done
And in mysql:
mysql> CREATE USER '?' IDENTIFIED BY '?' [ [ 'readonly', 'specialpassword' ] ];
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[ [ 'readonly', 'specialpassword' ] ]' at line 1
Issue Analytics
- State:
- Created 7 years ago
- Comments:15 (9 by maintainers)
Top GitHub Comments
More straight forward solution would be to add null as last parameter
And as a last node:
db-migrate
always uses the prepared statement like queries (so “replacement characters”). It is on the driver beneath what it does with that. Some use the escaping capabilities directly. Others automatically use prep statements by default.What you do with
runSql
is completely on to you though. And it is just a direct pass through to the default query method of the concerned driver.