UNPKG

@iamthes/query-builder

Version:
450 lines 16.4 kB
"use strict"; var query_type_enum_1 = require("./query-type.enum"); var lodash_1 = require("lodash"); var isNumber = require("is-number"); var Sql = (function () { function Sql() { this.reset(); } Sql.prototype.reset = function () { this._queryKind = undefined; this._selects = []; this._tables = []; this._wheres = []; this._whereConcat = "and"; this._whereConcatDefault = "and"; this._sets = []; this._limit = undefined; this._offset = undefined; this._orderBys = []; this._joins = []; this._groupBys = []; this._whereGroupCount = 0; this._openWhereGroupCount = 0; this._havings = []; return this; }; Sql.prototype.select = function (field, alias, func) { var _this = this; this._queryKind = query_type_enum_1.QueryKind.SELECT; switch (arguments.length) { case 0: this._selects.push({ "field": "*" }); break; case 1: if (!lodash_1.isArray(field)) field = String(field).split(","); field.map(function (f) { return lodash_1.trim(f); }).filter(Boolean).forEach(function (f) { var _a = f.split(/\s*as\s*/i), field = _a[0], alias = _a[1]; _this._selects.push({ field: field, alias: alias }); }); break; case 2: if (lodash_1.isString(field)) { this._selects.push({ field: field, alias: alias }); } break; default: var args = Array.prototype.slice.call(arguments); func = args.shift(); // First parameter alias = args.pop(); // Last parameter args = args.map(function (f) { return lodash_1.isArray(f) ? f.join(", ") : f; }); // Do flatten array. this._selects.push({ func: func, alias: alias, "field": args.join(", ") }); } return this; }; Sql.prototype.between = function (field, value, otherValue) { if (otherValue === undefined) { var split = value.split(".."); if (split.length > 1) { value = split[0], otherValue = split[1]; } } var sql = field + " between " + this._wrap(value) + " and " + this._wrap(otherValue); this._where(sql); return this; }; Sql.prototype.table = function (table) { var _this = this; if (!lodash_1.isArray(table)) { table = [table]; } table.forEach(function (t) { return _this._tables.push(t); }); return this; }; Sql.prototype.from = function (table) { return this.table(table); }; Sql.prototype.into = function (table) { return this.table(table); }; Sql.prototype._conditionExpr = function (field, value, operator) { // console.log('_conditionExpr', arguments); var wrapValue = true; if (!operator) { operator = lodash_1.find(Sql._operators, function (o) { return lodash_1.endsWith(field, o); }); if (operator) { field = field.slice(0, -operator.length).trim(); } } switch (operator) { case "is null": operator = "is"; value = "@null"; break; case "is not null": operator = "is not"; value = "@null"; break; default: if (!operator) { operator = "="; } } if (value === null) { value = "@null"; } if (lodash_1.isString(value) && value.substr(0, 1) === "@") { wrapValue = false; value = value.substr(1); } if (wrapValue && value !== undefined) { value = this._wrap(value); } return { field: field, operator: operator, value: value }; }; Sql.prototype.where = function (field, operator, value) { if (typeof field === "object") { for (var i in field) { this.where(i, field[i]); } return this; } if (value === undefined) { value = operator; operator = undefined; } // console.log("field, value, operator ", field, value, operator); var expr = this._conditionExpr(field, value, operator); // console.log("expr ", expr); switch (expr.operator) { case "@": return this.whereIn(field.slice(0, -1), value); case "!@": return this.whereNotIn(field.slice(0, -2), value); case "!%": return this.notLike(field.slice(0, -2), value, "both"); case "%": return this.like(field.slice(0, -1), value, "both"); case "^%": return this.like(field.slice(0, -2), value, "right"); case "%$": return this.like(field.slice(0, -2), value, "left"); } this._where(expr.field + " " + expr.operator + " " + expr.value); return this; }; Sql.prototype.whereNotIn = function (field, values) { return this.whereIn(field, values, "not in"); }; Sql.prototype.whereIn = function (field, values, op) { if (op === void 0) { op = "in"; } if (!lodash_1.isArray(values)) values = [String(values)]; values = values.map(this._wrap); var value = "(" + values.join(",") + ")"; var where = field + " " + op + " " + value; this._where(where); return this; }; Sql.prototype.limit = function (limit, offset) { this._limit = limit; if (offset !== undefined) { this._offset = offset; } return this; }; Sql.prototype.top = function (n) { return this.limit(n); }; Sql.prototype.offset = function (offset) { this._offset = offset; return this; }; Sql.prototype.skip = function (n) { return this.offset(n); }; Sql.prototype.notLike = function (field, match, side) { return this.like(field, match, side, "not like"); }; Sql.prototype.like = function (field, match, side, op) { if (match === void 0) { match = ""; } if (side === void 0) { side = "both"; } if (op === void 0) { op = "like"; } field = lodash_1.trim(field); switch (side) { case "left": match = "%" + match; break; case "right": match += "%"; break; case "both": { if (lodash_1.isString(match) && match.length === 0) { match = "%"; } else { match = "%" + match + "%"; } } break; default: throw new Error("Unknown side " + side); } // console.log('field', JSON.stringify(field)); // console.log('op', JSON.stringify(op)); // console.log('match', JSON.stringify(match)); // console.log(JSON.stringify(`${field} ${op} ${this._wrap(match)}`)); this._where(field + " " + op + " " + this._wrap(match)); return this; }; Sql.prototype.groupBy = function (fields) { var _this = this; if (!lodash_1.isArray(fields)) { fields = String(fields).split(","); } fields .map(function (f) { return lodash_1.trim(f); }) .filter(function (f) { return f.length > 0; }) .forEach(function (f) { _this._groupBys.push(f); }); return this; }; Sql.prototype.andOp = function () { this._whereConcat = "and"; return this; }; Sql.prototype.orOp = function () { this._whereConcat = "or"; return this; }; Sql.prototype.beginWhereGroup = function () { this._whereGroupCount++; this._openWhereGroupCount++; return this; }; Sql.prototype.endWhereGroup = function () { if (this._whereGroupCount > 0) { var whereCount = this._wheres.length; if (this._openWhereGroupCount >= this._whereGroupCount) { this._openWhereGroupCount--; } else if (whereCount > 0) { this._wheres[whereCount - 1] += ")"; } this._whereGroupCount--; } return this; }; Sql.prototype._endQuery = function () { while (this._whereGroupCount > 0) { this.endWhereGroup(); } }; Sql.prototype.join = function (table, on, join) { if (!lodash_1.includes(Sql._joinTypes, join)) join = ""; var expr = lodash_1.trim(join + " join " + table + " on " + on); this._joins.push(expr); return this; }; Sql.prototype.leftJoin = function (table, on) { return this.join(table, on, "left"); }; Sql.prototype.having = function (field, value) { var expr = this._conditionExpr(field, value); this._havings.push(expr.field + " " + expr.operator + " " + expr.value); return this; }; Sql.prototype.orderBy = function (field, direction) { if (direction === void 0) { direction = "asc"; } direction = direction.toLowerCase(); if (direction !== "asc") direction = "desc"; var expr = field + " " + direction; this._orderBys.push(expr); return this; }; Sql.prototype.get = function () { switch (this._queryKind) { case query_type_enum_1.QueryKind.SELECT: return this.getSelect(); case query_type_enum_1.QueryKind.DELETE: return this.getDelete(); case query_type_enum_1.QueryKind.INSERT: return this.getInsert(); case query_type_enum_1.QueryKind.UPDATE: return this.getUpdate(); default: throw new TypeError("Unknown kind of query " + this._queryKind); } }; Sql.prototype.getSelect = function () { this._endQuery(); var sql = "select "; var selects = this._selects .map(function (item) { var field = item.field; if (item.func) field = item.func + "(" + field + ")"; if (item.alias) field = field + " as " + item.alias; return field; }) .join(", "); if (selects === "") selects = "*"; sql += selects; if (this._tables.length > 0) sql += " " + "from " + this._tables.join(", "); if (this._joins.length > 0) sql += " " + this._joins.join(" "); if (this._wheres.length > 0) sql += " " + "where " + this._wheres.join(" "); if (this._groupBys.length > 0) sql += " " + "group by " + this._groupBys.join(", "); if (this._havings.length > 0) sql += " " + "having " + this._havings.join(" "); if (this._orderBys.length > 0) sql += " " + "order by " + this._orderBys.join(", "); if (isNumber(this._limit)) { sql += " "; sql = this.getLimit(sql, this._limit, this._offset); } this.reset(); return sql; }; Sql.prototype.delete = function (table) { this._queryKind = query_type_enum_1.QueryKind.DELETE; if (table) { this._tables.push(table); } return this; }; Sql.prototype.getDelete = function () { var table = this._tables[0]; var result = "delete " + table; if (this._wheres.length > 0) { result += " " + "where " + this._wheres.join(" "); } this.reset(); return result; }; Sql.prototype.update = function (table) { this._queryKind = query_type_enum_1.QueryKind.UPDATE; if (table) { this._tables.push(table); } return this; }; Sql.prototype.getUpdate = function () { var _this = this; this._endQuery(); var table = this._tables[0]; var result = "update " + table + " set "; result += this._sets .map(function (item) { var value = item.value; if (item.wrapValue) value = _this._wrap(value); return item.name + " = " + value; }) .join(", "); if (this._wheres.length > 0) { result += " where " + this._wheres.join(" "); } this.reset(); return result; }; Sql.prototype.insert = function () { this._queryKind = query_type_enum_1.QueryKind.INSERT; return this; }; Sql.prototype.set = function (name, value, wrapValue) { if (wrapValue === void 0) { wrapValue = true; } if (arguments.length === 1) { for (var i in name) { this.set(i, name[i], true); } return this; } if (value === null || value === undefined) { value = "null"; wrapValue = false; } this._sets.push({ name: name, value: value, wrapValue: wrapValue }); return this; }; Sql.prototype.getInsert = function () { var _this = this; var table = this._tables[0]; var result = "insert into " + table; var names = this._sets.map(function (item) { return item.name; }); var values = this._sets.map(function (item) { var value = item.value; if (item.wrapValue) value = _this._wrap(value); return value; }); result += "(" + names.join(", ") + ") values(" + values.join(", ") + ")"; this.reset(); return result; }; Sql.prototype.getLimit = function (sql, limit, offset) { throw "getLimit() not supported."; }; Sql.prototype._where = function (sql) { var concat = ""; if (this._wheres.length > 0) { concat = this._whereConcat + " "; } while (this._openWhereGroupCount > 0) { concat += "("; this._openWhereGroupCount--; } // console.log("concat _w ", JSON.stringify(concat)); // console.log("sql _w ", JSON.stringify(sql)); this._whereConcat = this._whereConcatDefault; this._wheres.push(concat + sql); // console.log("this._wheres ", this._wheres); }; Sql.prototype._wrap = function (value) { // console.log("_wrap ", value); if (!isNumber(value)) { value = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') .replace(/'/g, "\\'") .replace(/\\"/g, '"') + '\''; } return value; }; Sql.prototype._quote = function (value, wrapInQuotes) { console.log("_quote ", value); if (isNumber(value)) { return value; } value = value .replace("\\", "\\\\") .replace("\0", "\\0") .replace("\n", "\\n") .replace("\r", "\\r") .replace("'", "\\'") .replace("\"", "\\\"") .replace("\x1a", "\\Z"); if (wrapInQuotes) { value = "'" + value + "'"; } return value; }; Sql._operators = [">=", "<=", "!=", "<>", ">", "<", "!@", "@", "%$", "^%", "%", "like", "not like", "is", "is null", "is not null"]; Sql._joinTypes = ["inner", "outer", "left", "right", "left outer", "right outer"]; return Sql; }()); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Sql; //# sourceMappingURL=sql.js.map