sedk-mysql
Version:
Simple SQL builder and validator for MySQL
151 lines • 6.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseStep = exports.Parenthesis = void 0;
const binder_1 = require("../binder");
const ItemInfo_1 = require("../ItemInfo");
const models_1 = require("../models");
const errors_1 = require("../errors");
const database_1 = require("../database");
const util_1 = require("../util");
var Parenthesis;
(function (Parenthesis) {
Parenthesis["Open"] = "(";
Parenthesis["Close"] = ")";
})(Parenthesis || (exports.Parenthesis = Parenthesis = {}));
class BaseStep extends Function {
constructor(prevStep) {
var _a;
super();
this.prevStep = prevStep;
this.prefixSeparator = ' ';
this.getStepStatementCalled = false;
this.rootStep = prevStep === null ? this : prevStep.rootStep;
this.data = this.rootStep.data;
this.binderStore = new binder_1.BinderStore((_a = prevStep === null || prevStep === void 0 ? void 0 : prevStep.getBindValues().length) !== null && _a !== void 0 ? _a : 0);
}
getSQL() {
let result = this.getFullStatement({ tables: new Set(), columns: new Set() });
if (this.data.option.throwErrorIfDeleteHasNoCondition) {
//look if the path is DELETE and there is no WHERE step
let foundDELETE = false;
let foundWHERE = false;
let step = this;
do {
if ((0, util_1.isDeleteStep)(step))
foundDELETE = true;
if ((0, util_1.isDeleteWhereStep)(step))
foundWHERE = true;
step = step.prevStep;
} while (step !== null);
if (foundDELETE && !foundWHERE) {
throw new errors_1.DeleteWithoutConditionError();
}
}
if (this.data.option.useSemicolonAtTheEnd)
result += ';';
return result;
}
getFullStatement(nextArtifacts) {
let result = '';
const artifacts = this.mergeArtifacts(this.getFullArtifacts(), nextArtifacts);
if (this.prevStep !== null) {
const stmt = this.prevStep.getFullStatement(artifacts).trimEnd();
if (stmt !== '') {
result += `${stmt}${this.prefixSeparator}`;
}
}
result += this.getStepStatement(artifacts);
return result;
}
getFullArtifacts() {
var _a;
if (this.prevStep !== null) {
return this.mergeArtifacts(this.getStepArtifacts(), (_a = this.prevStep) === null || _a === void 0 ? void 0 : _a.getFullArtifacts());
}
return this.getStepArtifacts();
}
mergeArtifacts(ud1, ud2) {
const tables = new Set([...ud1.tables, ...ud2.tables]);
const columns = new Set([...ud1.columns, ...ud2.columns]);
return { tables, columns };
}
getBindValues() {
// TODO: change the way we fill and call BinderStore
/** call getStepStmt one time before getBindValues, so binderStore filled with binders */
if (!this.getStepStatementCalled) {
this.getStepStatement({ tables: new Set(), columns: new Set() });
this.getStepStatementCalled = true;
}
if (this.prevStep !== null) {
return [...this.prevStep.getBindValues(), ...this.binderStore.getValues()];
}
return [...this.binderStore.getValues()];
}
static getTable(item) {
if (item instanceof database_1.Table)
return item;
else
return item.table;
}
throwIfTableNotInDb(table) {
if (!this.data.database.hasTable(table))
throw new errors_1.TableNotFoundError(`Table: "${table.name}" not found`);
}
// TODO: refactor this call the way it been call or itself
throwIfColumnsNotInDb(columns) {
for (const item of columns) {
if (item instanceof models_1.Expression
|| item instanceof ItemInfo_1.ItemInfo) {
this.throwIfColumnsNotInDb(item.getColumns());
continue;
}
// after this, item is type Column
if (!this.data.database.hasColumn(item)) {
throw new errors_1.ColumnNotFoundError(item.name);
}
}
}
static addConditionParts(conditionArray, cond1, op1, cond2, op2, cond3) {
if (op1 === undefined && cond2 === undefined) {
conditionArray.push(cond1);
}
else if (op1 !== undefined && cond2 !== undefined) {
conditionArray.push(Parenthesis.Open);
conditionArray.push(cond1);
conditionArray.push(op1);
conditionArray.push(cond2);
if (op2 !== undefined && cond3 !== undefined) {
conditionArray.push(op2);
conditionArray.push(cond3);
}
conditionArray.push(Parenthesis.Close);
}
}
/**
* This function throws error if WhereParts Array where invalid
* it check the number of open and close parentheses in the conditions
*/
static throwIfConditionPartsInvalid(conditionsArray) {
let pCounter = 0;
for (let i = 0; i < conditionsArray.length; i++) {
if (conditionsArray[i] === Parenthesis.Open) {
pCounter++;
if (i < conditionsArray.length - 1)
if (conditionsArray[i + 1] === Parenthesis.Close) {
throw new Error('Invalid conditions build, empty parentheses are not allowed');
}
}
if (conditionsArray[i] === Parenthesis.Close)
pCounter--;
if (pCounter < 0) { // Close comes before Open
throw new Error('Invalid conditions build, closing parenthesis must occur after Opening one');
}
}
if (pCounter > 0) // Opening more than closing
throw new Error('Invalid conditions build, opening parentheses are more than closing ones');
if (pCounter < 0) // Closing more than opening
throw new Error('Invalid conditions build, closing parentheses are more than opening ones');
}
}
exports.BaseStep = BaseStep;
//# sourceMappingURL=BaseStep.js.map