knex/src/query/string.js

135 lines
3.2 KiB
JavaScript
Raw Normal View History

import * as helpers from '../helpers';
2015-05-09 13:58:18 -04:00
const SqlString = {};
export { SqlString as default };
2015-05-09 13:58:18 -04:00
SqlString.escape = function(val, timeZone) {
// Can't do require on top of file because Raw has not yet been initialized
// when this file is executed for the first time.
const Raw = require('../raw')
if (val === null || val === undefined) {
2015-05-09 13:58:18 -04:00
return 'NULL';
}
switch (typeof val) {
case 'boolean': return (val) ? 'true' : 'false';
case 'number': return val+'';
}
if (val instanceof Date) {
val = SqlString.dateToString(val, timeZone || 'local');
}
if (Buffer.isBuffer(val)) {
return SqlString.bufferToString(val);
}
if (Array.isArray(val)) {
return SqlString.arrayToList(val, timeZone);
}
if (val instanceof Raw) {
return val;
}
2015-05-09 13:58:18 -04:00
if (typeof val === 'object') {
try {
val = JSON.stringify(val)
} catch (e) {
helpers.warn(e)
val = val + ''
}
}
val = val.replace(/(\\\?)|[\0\n\r\b\t\\\'\x1a]/g, function(s) {
2015-05-09 13:58:18 -04:00
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";
case "\\?": return "?";
case "\'": return "''";
default: return `\\${s}`;
2015-05-09 13:58:18 -04:00
}
});
return `'${val}'`;
2015-05-09 13:58:18 -04:00
};
SqlString.arrayToList = function(array, timeZone) {
const self = this;
2015-05-09 13:58:18 -04:00
return array.map(function(v) {
if (Array.isArray(v)) return `(${SqlString.arrayToList(v, timeZone)})`;
return self.escape(v, timeZone);
2015-05-09 13:58:18 -04:00
}).join(', ');
};
SqlString.format = function(sql, values, timeZone) {
const self = this;
2015-05-09 13:58:18 -04:00
values = values == null ? [] : [].concat(values);
let index = 0;
return sql.replace(/\\?\?/g, function(match) {
if (match === '\\?') return match;
2015-05-09 13:58:18 -04:00
if (index === values.length) {
return match;
}
const value = values[index++];
return self.escape(value, timeZone)
}).replace('\\?', '?');
2015-05-09 13:58:18 -04:00
};
SqlString.dateToString = function(date, timeZone) {
const dt = new Date(date);
2015-05-09 13:58:18 -04:00
if (timeZone !== 'local') {
const tz = convertTimezone(timeZone);
2015-05-09 13:58:18 -04:00
dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000));
if (tz !== false) {
dt.setTime(dt.getTime() + (tz * 60000));
}
}
const year = dt.getFullYear();
const month = zeroPad(dt.getMonth() + 1, 2);
const day = zeroPad(dt.getDate(), 2);
const hour = zeroPad(dt.getHours(), 2);
const minute = zeroPad(dt.getMinutes(), 2);
const second = zeroPad(dt.getSeconds(), 2);
const millisecond = zeroPad(dt.getMilliseconds(), 3);
return (
year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' +
second + '.' + millisecond
);
2015-05-09 13:58:18 -04:00
};
SqlString.bufferToString = function bufferToString(buffer) {
return `X'${buffer.toString('hex')}'`;
2015-05-09 13:58:18 -04:00
}
function zeroPad(number, length) {
number = number.toString();
while (number.length < length) {
number = `0${number}`;
2015-05-09 13:58:18 -04:00
}
return number;
}
function convertTimezone(tz) {
if (tz === "Z") return 0;
const m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);
2015-05-09 13:58:18 -04:00
if (m) {
return (
(m[1] === '-' ? -1 : 1) *
(parseInt(m[2], 10) +
((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60
);
2015-05-09 13:58:18 -04:00
}
return false;
}