2014-09-18 15:35:58 -04:00
|
|
|
var SqlString = exports;
|
|
|
|
|
|
|
|
SqlString.escapeId = function (val, forbidQualified) {
|
|
|
|
if (forbidQualified) {
|
|
|
|
return '`' + val.replace(/`/g, '``') + '`';
|
|
|
|
}
|
|
|
|
return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`';
|
|
|
|
};
|
|
|
|
|
|
|
|
SqlString.escape = function(val, stringifyObjects, timeZone) {
|
|
|
|
if (val === undefined || val === null) {
|
|
|
|
return 'NULL';
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (typeof val) {
|
|
|
|
case 'boolean': return (val) ? 'true' : 'false';
|
|
|
|
case 'number': return val+'';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val instanceof Date) {
|
2014-09-24 17:56:53 -04:00
|
|
|
val = SqlString.dateToString(val, timeZone || "Z");
|
2014-09-18 15:35:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Buffer.isBuffer(val)) {
|
|
|
|
return SqlString.bufferToString(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
return SqlString.arrayToList(val, timeZone);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof val === 'object') {
|
|
|
|
if (stringifyObjects) {
|
|
|
|
val = val.toString();
|
|
|
|
} else {
|
|
|
|
return SqlString.objectToValues(val, timeZone);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
|
|
|
|
switch(s) {
|
|
|
|
case "\0": return "\\0";
|
|
|
|
case "\n": return "\\n";
|
|
|
|
case "\r": return "\\r";
|
|
|
|
case "\b": return "\\b";
|
|
|
|
case "\t": return "\\t";
|
|
|
|
case "\x1a": return "\\Z";
|
|
|
|
default: return "\\"+s;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return "'"+val+"'";
|
|
|
|
};
|
|
|
|
|
|
|
|
SqlString.arrayToList = function(array, timeZone) {
|
|
|
|
return array.map(function(v) {
|
2014-09-24 17:56:53 -04:00
|
|
|
if (Array.isArray(v)) return '(' + SqlString.arrayToList(v) + ')';
|
2014-09-18 15:35:58 -04:00
|
|
|
return SqlString.escape(v, true, timeZone);
|
|
|
|
}).join(', ');
|
|
|
|
};
|
|
|
|
|
2014-09-24 17:56:53 -04:00
|
|
|
SqlString.format = function(sql, values, timeZone) {
|
|
|
|
values = [].concat(values);
|
2014-09-18 15:35:58 -04:00
|
|
|
|
|
|
|
return sql.replace(/\?\??/g, function(match) {
|
|
|
|
if (!values.length) {
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (match == "??") {
|
|
|
|
return SqlString.escapeId(values.shift());
|
|
|
|
}
|
2014-09-24 17:56:53 -04:00
|
|
|
return SqlString.escape(values.shift(), false, timeZone);
|
2014-09-18 15:35:58 -04:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
SqlString.dateToString = function(date, timeZone) {
|
|
|
|
var dt = new Date(date);
|
|
|
|
|
|
|
|
if (timeZone != 'local') {
|
|
|
|
var tz = convertTimezone(timeZone);
|
|
|
|
|
|
|
|
dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000));
|
|
|
|
if (tz !== false) {
|
|
|
|
dt.setTime(dt.getTime() + (tz * 60000));
|
|
|
|
}
|
|
|
|
}
|
2014-09-24 17:56:53 -04:00
|
|
|
|
2014-09-18 15:35:58 -04:00
|
|
|
var year = dt.getFullYear();
|
|
|
|
var month = zeroPad(dt.getMonth() + 1, 2);
|
|
|
|
var day = zeroPad(dt.getDate(), 2);
|
|
|
|
var hour = zeroPad(dt.getHours(), 2);
|
|
|
|
var minute = zeroPad(dt.getMinutes(), 2);
|
|
|
|
var second = zeroPad(dt.getSeconds(), 2);
|
|
|
|
var millisecond = zeroPad(dt.getMilliseconds(), 3);
|
|
|
|
|
|
|
|
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + millisecond;
|
|
|
|
};
|
|
|
|
|
2014-09-24 17:56:53 -04:00
|
|
|
SqlString.bufferToString = function(buffer) {
|
|
|
|
var hex = '';
|
|
|
|
try {
|
|
|
|
hex = buffer.toString('hex');
|
|
|
|
} catch (err) {
|
|
|
|
// node v0.4.x does not support hex / throws unknown encoding error
|
|
|
|
for (var i = 0; i < buffer.length; i++) {
|
|
|
|
var byte = buffer[i];
|
|
|
|
hex += zeroPad(byte.toString(16));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "X'" + hex+ "'";
|
2014-09-18 15:35:58 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
SqlString.objectToValues = function(object, timeZone) {
|
|
|
|
var values = [];
|
|
|
|
for (var key in object) {
|
|
|
|
var value = object[key];
|
|
|
|
if(typeof value === 'function') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone));
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.join(', ');
|
|
|
|
};
|
|
|
|
|
|
|
|
function zeroPad(number, length) {
|
|
|
|
number = number.toString();
|
|
|
|
while (number.length < length) {
|
|
|
|
number = '0' + number;
|
|
|
|
}
|
|
|
|
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
|
|
|
|
function convertTimezone(tz) {
|
|
|
|
if (tz == "Z") return 0;
|
|
|
|
|
|
|
|
var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);
|
|
|
|
if (m) {
|
|
|
|
return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|