knex/src/query/string.js

162 lines
4.1 KiB
JavaScript
Raw Normal View History

/*eslint max-len: 0, no-var:0 */
export const charsRegex = /[\0\b\t\n\r\x1a\"\'\\]/g; // eslint-disable-line no-control-regex
export const charsMap = {
'\0': '\\0',
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\r': '\\r',
'\x1a': '\\Z',
'"': '\\"',
'\'': '\\\'',
'\\': '\\\\'
}
function wrapEscape(escapeFn) {
return function finalEscape(val, ctx = {}) {
return escapeFn(val, finalEscape, ctx)
2015-05-09 13:58:18 -04:00
}
}
2015-05-09 13:58:18 -04:00
export function makeEscape(config = {}) {
const finalEscapeDate = config.escapeDate || dateToString
const finalEscapeArray = config.escapeArray || arrayToList
const finalEscapeBuffer = config.escapeBuffer || bufferToString
const finalEscapeString = config.escapeString || escapeString
const finalEscapeObject = config.escapeObject || escapeObject
const finalWrap = config.wrap || wrapEscape
function escapeFn(val, finalEscape, ctx) {
if (val === undefined || val === null) {
return 'NULL';
}
switch (typeof val) {
case 'boolean': return (val) ? 'true' : 'false';
case 'number': return val+'';
case 'object':
if (val instanceof Date) {
val = finalEscapeDate(val, finalEscape, ctx);
} else if (Array.isArray(val)) {
return finalEscapeArray(val, finalEscape, ctx)
} else if (Buffer.isBuffer(val)) {
return finalEscapeBuffer(val, finalEscape, ctx);
} else {
return finalEscapeObject(val, finalEscape, ctx)
}
}
return finalEscapeString(val, finalEscape, ctx)
2015-05-09 13:58:18 -04:00
}
return finalWrap ? finalWrap(escapeFn) : escapeFn
}
2015-05-09 13:58:18 -04:00
export function escapeObject(val, finalEscape, ctx) {
if (typeof val.toSQL === 'function') {
return val.toSQL(ctx)
} else {
return JSON.stringify(val)
2015-05-09 13:58:18 -04:00
}
}
2015-05-09 13:58:18 -04:00
export function arrayToList(array, finalEscape, ctx) {
var sql = '';
for (var i = 0; i < array.length; i++) {
var val = array[i];
if (Array.isArray(val)) {
sql += (i === 0 ? '' : ', ') + '(' + arrayToList(val, finalEscape, ctx) + ')';
} else {
sql += (i === 0 ? '' : ', ') + finalEscape(val, ctx);
}
2015-05-09 13:58:18 -04:00
}
return sql;
}
2015-05-09 13:58:18 -04:00
export function bufferToString(buffer) {
return "X" + escapeString(buffer.toString('hex'));
}
export function escapeString(val, finalEscape, ctx) {
var chunkIndex = charsRegex.lastIndex = 0;
var escapedVal = '';
var match;
while ((match = charsRegex.exec(val))) {
escapedVal += val.slice(chunkIndex, match.index) + charsMap[match[0]];
chunkIndex = charsRegex.lastIndex;
2015-05-09 13:58:18 -04:00
}
if (chunkIndex === 0) {
// Nothing was escaped
return "'" + val + "'";
}
2015-05-09 13:58:18 -04:00
if (chunkIndex < val.length) {
return "'" + escapedVal + val.slice(chunkIndex) + "'";
}
2015-05-09 13:58:18 -04:00
return "'" + escapedVal + "'";
}
2015-05-09 13:58:18 -04:00
export function dateToString(date, finalEscape, ctx) {
const timeZone = ctx.timeZone || 'local'
var dt = new Date(date);
var year;
var month;
var day;
var hour;
var minute;
var second;
var millisecond;
if (timeZone === 'local') {
year = dt.getFullYear();
month = dt.getMonth() + 1;
day = dt.getDate();
hour = dt.getHours();
minute = dt.getMinutes();
second = dt.getSeconds();
millisecond = dt.getMilliseconds();
} else {
var tz = convertTimezone(timeZone);
if (tz !== false && tz !== 0) {
2015-05-09 13:58:18 -04:00
dt.setTime(dt.getTime() + (tz * 60000));
}
year = dt.getUTCFullYear();
month = dt.getUTCMonth() + 1;
day = dt.getUTCDate();
hour = dt.getUTCHours();
minute = dt.getUTCMinutes();
second = dt.getUTCSeconds();
millisecond = dt.getUTCMilliseconds();
2015-05-09 13:58:18 -04:00
}
// YYYY-MM-DD HH:mm:ss.mmm
return zeroPad(year, 4) + '-' + zeroPad(month, 2) + '-' + zeroPad(day, 2) + ' ' +
zeroPad(hour, 2) + ':' + zeroPad(minute, 2) + ':' + zeroPad(second, 2) + '.' +
zeroPad(millisecond, 3);
2015-05-09 13:58:18 -04:00
}
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;
}