@sqb/builder
Version:
Extensible multi-dialect SQL query builder written with TypeScript
194 lines (193 loc) • 5.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SerializeContext = void 0;
const enums_js_1 = require("./enums.js");
const extensions_js_1 = require("./extensions.js");
const serializable_js_1 = require("./serializable.js");
const typeguards_js_1 = require("./typeguards.js");
class SerializeContext {
constructor(opts) {
this.reservedWords = [
'schema',
'table',
'field',
'index',
'foreign',
'key',
'select',
'insert',
'update',
'delete',
'with',
'merge',
'join',
'inner',
'outer',
'left',
'right',
'full',
'from',
'where',
'order',
'by',
'group',
'having',
'acs',
'ascending',
'dsc',
'descending',
'distinct',
'and',
'or',
'not',
'between',
'null',
'like',
'ilike',
'count',
'sum',
'average',
'avg',
'cascade',
'authorization',
'create',
'add',
'drop',
'alter',
'index',
'private',
'sequence',
'default',
'constraint',
'references',
'primary',
'foreign',
'user',
'password',
];
if (opts)
Object.assign(this, opts);
}
/**
* Performs a fallback mechanism, tries hook functions, extensions than default function to serialize
*/
serialize(type, o, fallback) {
if (this.serializeHooks) {
for (const hook of this.serializeHooks) {
const s = hook(this, type, o, fallback);
if (s != null)
return s;
}
}
for (const ext of extensions_js_1.SerializerRegistry.items()) {
if (ext.dialect === this.dialect && ext.serialize) {
const s = ext.serialize(this, type, o, fallback);
if (s != null)
return s;
}
}
return fallback(this, o);
}
/**
* Serializes object
*/
anyToSQL(v) {
if (v == null)
return 'null';
if (Array.isArray(v)) {
const vv = v.map(x => this.anyToSQL(x));
return (this.serialize(enums_js_1.SerializationType.ARRAY, vv, () => '(' + vv.join(',')) +
')');
}
if (typeof v === 'object') {
if ((0, typeguards_js_1.isSerializable)(v)) {
const s = v._serialize(this);
return s
? (0, typeguards_js_1.isQuery)(v) || (0, typeguards_js_1.isLogicalOperator)(v)
? '(' + s + ')'
: s
: /* istanbul ignore next */ '';
}
if (v instanceof Date) {
return this.serialize(enums_js_1.SerializationType.DATE_VALUE, v, () => this.dateToSQL(v));
}
return this.stringToSQL(JSON.stringify(v));
}
if (typeof v === 'string') {
return this.serialize(enums_js_1.SerializationType.STRING_VALUE, v, () => this.stringToSQL(v));
}
if (typeof v === 'boolean') {
return this.serialize(enums_js_1.SerializationType.BOOLEAN_VALUE, v, () => this.booleanToSQL(v));
}
if (typeof v === 'number') {
return this.serialize(enums_js_1.SerializationType.NUMBER_VALUE, v, () => this.numberToSQL(v));
}
if (v instanceof serializable_js_1.Serializable)
return v._serialize(this);
return v;
}
/**
*
*/
stringToSQL(val) {
return "'" + String(val).replace(/'/g, "''") + "'";
}
/**
*
*/
booleanToSQL(val) {
return val ? 'true' : 'false';
}
/**
*
*/
numberToSQL(val) {
return '' + val;
}
/**
*
*/
dateToSQL(date) {
const d = date.getUTCDate();
const m = date.getUTCMonth() + 1;
const y = date.getUTCFullYear();
const h = date.getUTCHours();
const n = date.getUTCMinutes();
const s = date.getUTCSeconds();
let str = y + '-' + (m <= 9 ? '0' + m : m) + '-' + (d <= 9 ? '0' + d : d);
/* istanbul ignore else */
if (h + n + s)
str +=
' ' +
(h <= 9 ? '0' + h : h) +
':' +
(n <= 9 ? '0' + n : n) +
':' +
(s <= 9 ? '0' + s : s);
return "'" + str + "'";
}
/**
* Check if a string value is a reserved word
*/
isReservedWord(s) {
if (!s)
return false;
if (this.reservedWords.includes(s.toLowerCase()))
return true;
for (const ext of extensions_js_1.SerializerRegistry.items()) {
if (ext.dialect === this.dialect && ext.isReservedWord) {
if (ext.isReservedWord(this, s))
return true;
}
}
return false;
}
escapeReserved(s) {
if (!s)
return '';
if (this.isReservedWord(s))
return '"' + s + '"';
return s;
}
}
exports.SerializeContext = SerializeContext;