@dazejs/framework
Version:
Daze.js - A powerful web framework for Node.js
244 lines • 9.12 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
class Parser {
constructor() {
this.selectComponents = [
'aggregate',
'columns',
'from',
'joins',
'wheres',
'groups',
'havings',
'orders',
'limit',
'offset',
'lock',
];
}
parseSelect(builder) {
if (builder._aggregate && builder._unions.length) {
const _sql = `${this.parseAggregate(builder)}`;
return `${_sql} from (${this.parseSelect(builder.removeAggregate())}) as temp`;
}
const sql = this.parseSelectComponents(builder);
if (builder._unions.length) {
return `(${sql}) ${this.parseUnions(builder)}`;
}
return sql;
}
parseInsert(builder, data) {
builder.alias('');
if (!data || !data.length) {
return `insert into ${this.getTable(builder)} default values`;
}
const columns = Object.keys(data[0]);
const _columns = this.columnDelimite(columns, builder);
const values = data.map(() => `(${this.parameter()})`).join(', ');
return `insert into ${this.getTable(builder)} (${_columns}) values ${values}`;
}
parseUpdate(builder, columns = []) {
const _columns = this.columnDelimiteForUpdate(columns, builder);
const where = this.parseWheres(builder);
if (builder._joins.length > 0) {
const joins = this.parseJoins(builder);
return `update ${this.getTable(builder)} ${joins} set ${_columns} ${where}`;
}
return `update ${this.getTable(builder)} set ${_columns} ${where}`;
}
parseDelete(builder) {
builder.alias('');
const where = this.parseWheres(builder);
if (builder._joins.length > 0) {
const joins = this.parseJoins(builder);
return `delete from ${this.getTable(builder)} ${joins} ${where}`;
}
return `delete from ${this.getTable(builder)} ${where}`;
}
parseSelectComponents(builder) {
const sqls = [];
for (const component of this.selectComponents) {
const sql = this.parseComponent(builder, component);
if (sql) {
sqls.push(sql);
}
}
return sqls.join(' ');
}
parseComponent(builder, part) {
switch (part) {
case 'aggregate':
return this.parseAggregate(builder);
case 'columns':
return this.parseColumns(builder);
case 'from':
return this.parseFrom(builder);
case 'joins':
return this.parseJoins(builder);
case 'wheres':
return this.parseWheres(builder);
case 'groups':
return this.parseGroups(builder);
case 'havings':
return this.parseHavings(builder);
case 'orders':
return this.parseOrders(builder);
case 'limit':
return this.parseLimit(builder);
case 'offset':
return this.parseOffset(builder);
case 'lock':
return this.parseLock(builder);
default:
return '';
}
}
parseAggregate(builder) {
if (!builder._aggregate)
return '';
let { column } = builder._aggregate;
if (builder._distinct === true && column !== '*') {
column = `distinct ${this.wrapColum(column, builder)}`;
}
else if (Array.isArray(builder._distinct)) {
column = `distinct ${this.columnDelimite(builder._distinct, builder)}`;
}
return `select ${builder._aggregate.func}(${column}) as aggregate`;
}
parseColumns(builder) {
if (builder._aggregate)
return '';
const select = builder._distinct ? 'select distinct' : 'select';
if (!builder._columns.length)
return `${select} *`;
const str = builder._columns.map(({ type, column, as }) => {
if (type === 'raw')
return column;
return this.wrapColum(column, builder, as);
}).join(', ');
return `${select} ${str}`;
}
parseFrom(builder) {
return builder._table ? `from ${this.getTable(builder)}` : '';
}
parseGroups(builder) {
return builder._groups.length ? `group by ${this.columnDelimite(builder._groups, builder)}` : '';
}
parseWheres(builder, conjunction = 'where') {
if (!builder._wheres.length)
return '';
const wheres = [];
for (const where of builder._wheres) {
const leadSymlink = where.symlink ? `${where.symlink} ` : '';
if (where.type === 'value') {
wheres.push(`${leadSymlink}${this.wrapColum(where.column, builder)} ${where.operator} ${this.parameter()}`);
}
if (where.type === 'column') {
wheres.push(`${leadSymlink}${this.wrapColum(where.column, builder)} ${where.operator} ${this.wrapColum(where.value, builder)}`);
}
if (where.type === 'sql') {
wheres.push(`${leadSymlink}${where.value}`);
}
if (where.type === 'in') {
wheres.push(`${leadSymlink}${this.wrapColum(where.column, builder)} in (${this.parameterize(where.value)})`);
}
if (where.type === 'notIn') {
wheres.push(`${leadSymlink}${this.wrapColum(where.column, builder)} not in (${this.parameterize(where.value)})`);
}
if (where.type === 'null') {
wheres.push(`${leadSymlink}${this.wrapColum(where.column, builder)} is null`);
}
if (where.type === 'notNull') {
wheres.push(`${leadSymlink}${this.wrapColum(where.column, builder)} is not ull`);
}
}
return `${conjunction} ${wheres.join(' ')}`;
}
parseOrders(builder) {
if (!builder._orders.length || builder._aggregate)
return '';
const flatOrders = builder._orders.map(order => {
if (order.type === 'column') {
return `${order.column} ${order.direction}`;
}
return order.column;
});
return `order by ${flatOrders.join(', ')}`;
}
parseLimit(builder) {
return builder._limit && builder._limit >= 0 ? `limit ${builder._limit}` : '';
}
parseOffset(builder) {
return builder._offset && builder._offset >= 0 ? `offset ${builder._offset}` : '';
}
parseLock(builder) {
if (typeof builder._lock === 'string')
return builder._lock;
return '';
}
parseJoins(builder) {
if (!builder._joins.length)
return '';
const joins = [];
for (const join of builder._joins) {
joins.push(`${join.type} join ${this.getTable(join.builder)} ${this.parseWheres(join.builder, 'on')}`);
}
return joins.join(' ');
}
parseHavings(builder) {
if (!builder._havings.length)
return '';
const havings = [];
for (const having of builder._havings) {
const leadSymlink = having.symlink ? `${having.symlink} ` : '';
havings.push(`${leadSymlink}${having.column} ${having.operator} ${having.value}`);
}
return `having ${havings.join(' ')}`;
}
parseUnions(builder) {
const sqls = [];
if (!builder._unions.length)
return '';
for (const union of builder._unions) {
sqls.push(`${union.isAll ? 'union all' : 'union'} (${union.builder.toSql()})`);
}
return `${sqls.join(' ')}`;
}
parameterize(value) {
return value.map(() => this.parameter());
}
parameter() {
return '?';
}
columnDelimite(columns, builder) {
if (!columns)
return '';
return columns.map(column => this.wrapColum(column, builder)).join(', ');
}
columnDelimiteForUpdate(columns, builder) {
if (!columns)
return '';
return columns.map(column => `${this.wrapColum(column, builder)} = ${this.parameter()}`).join(', ');
}
wrapColum(column, builder, as) {
if (~column.indexOf('.')) {
const [_alias, _column] = column.split('.');
if (_column === '*')
return _column;
return `\`${_alias}\`.\`${_column}\`${as ? ` as ${as}` : ''}`;
}
if (builder._alias) {
return `\`${builder._alias}\`.\`${column}\`${as ? ` as ${as}` : ''}`;
}
return `\`${builder._table}\`.\`${column}\`${as ? ` as ${as}` : ''}`;
}
getTable(builder) {
if (builder._alias) {
return `\`${builder._table}\` as \`${builder._alias}\``;
}
return `\`${builder._table}\``;
}
}
exports.Parser = Parser;
//# sourceMappingURL=parser.js.map