UNPKG

tspace-mysql

Version:

Tspace MySQL is a promise-based ORM for Node.js, designed with modern TypeScript and providing type safety for schema databases.

1,288 lines 156 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Builder = void 0; const AbstractBuilder_1 = require("./Abstracts/AbstractBuilder"); const utils_1 = require("../utils"); const DB_1 = require("./DB"); const State_1 = require("./Handlers/State"); const Join_1 = require("./Join"); const constants_1 = require("../constants"); const Pool_1 = require("./Pool"); class Builder extends AbstractBuilder_1.AbstractBuilder { constructor() { super(); this._initialConnection(); } /** * The 'instance' method is used get instance. * @static * @returns {Builder} instance of the Builder */ static get instance() { return new this(); } /** * The 'unset' method is used to drop a property as desired. * @param {object} options * @property {boolean | undefined} options.select * @property {boolean | undefined} options.where * @property {boolean | undefined} options.join * @property {boolean | undefined} options.limit * @property {boolean | undefined} options.offset * @property {boolean | undefined} options.orderBy * @property {boolean | undefined} options.groupBy * @property {boolean | undefined} options.having * @returns {this} this */ unset(options) { if (options?.select != null && options.select) this.$state.set("SELECT", []); if (options?.join != null && options.join) this.$state.set("JOIN", []); if (options?.where != null && options.where) this.$state.set("WHERE", []); if (options?.groupBy != null && options.groupBy) this.$state.set("GROUP_BY", []); if (options?.having != null && options.having) this.$state.set("HAVING", ""); if (options?.orderBy != null && options.orderBy) this.$state.set("ORDER_BY", []); if (options?.limit != null && options.limit) this.$state.set("LIMIT", ""); if (options?.offset != null && options.offset) this.$state.set("OFFSET", ""); if (options?.alias != null && options.alias) this.$state.set("RAW_ALIAS", ""); return this; } /** * The 'CTEs' method is used to create common table expressions(CTEs). * * @returns {string} return sql query */ CTEs(as, callback) { const query = callback(new DB_1.DB().from(this.getTableName())); this.$state.set("CTE", [ ...this.$state.get("CTE"), `${as} AS (${query})`, ]); return this; } /** * The 'getQueries' method is used to retrieve the raw SQL queries that would be executed. * * @returns {string} return sql query */ getQueries() { return this.$state.get("QUERIES"); } /** * The 'distinct' method is used to apply the DISTINCT keyword to a database query. * * It allows you to retrieve unique values from one or more columns in the result set, eliminating duplicate rows. * @returns {this} this */ distinct() { this.$state.set("DISTINCT", true); return this; } /** * The 'select' method is used to specify which columns you want to retrieve from a database table. * * It allows you to choose the specific columns that should be included in the result set of a database query. * @param {string[]} ...columns * @returns {this} this */ select(...columns) { if (!columns.length) { this.$state.set("SELECT", ["*"]); return this; } let select = columns.map((column) => { if (column.includes(this.$constants("RAW"))) { return column?.replace(this.$constants("RAW"), "").replace(/'/g, ""); } return this.bindColumn(column); }); select = [...this.$state.get("SELECT"), ...select]; if (this.$state.get("DISTINCT") && select.length) { select[0] = String(select[0]).includes(this.$constants("DISTINCT")) ? select[0] : `${this.$constants("DISTINCT")} ${select[0]}`; } this.$state.set("SELECT", select); return this; } /** * The 'selectRaw' method is used to specify which columns you want to retrieve from a database table. * * It allows you to choose the specific columns that should be included in the result set of a database query. * * This method allows you to specify raw-sql parameters for the query. * @param {string[]} ...columns * @returns {this} this */ selectRaw(...columns) { if (!columns.length) return this; let select = columns.map((column) => { if (column === "*") return column; if (column.includes("`*`")) return column.replace("`*`", "*"); if (column.includes(this.$constants("RAW"))) return column?.replace(this.$constants("RAW"), "").replace(/'/g, ""); return column; }); select = [...this.$state.get("SELECT"), ...select]; if (this.$state.get("DISTINCT") && select.length) { select[0] = String(select[0]).includes(this.$constants("DISTINCT")) ? select[0] : `${this.$constants("DISTINCT")} ${select[0]}`; } this.$state.set("SELECT", select); return this; } /** * The 'select1' method is used to select 1 from database table. * * @returns {this} this */ select1() { this.$state.set("SELECT", [..."1"]); return this; } /** * The 'selectObject' method is used to specify which columns you want to retrieve from a database table. * * It allows you to choose the specific columns that should be included in the result set to 'Object' of a database query. * @param {string} object table name * @param {string} alias as name of the column * @returns {this} this */ selectObject(object, alias) { if (!Object.keys(object).length) throw new Error("The method 'selectObject' is not supported for empty object"); let maping = []; for (const [key, value] of Object.entries(object)) { maping = [...maping, `'${key}'`, this.bindColumn(value)]; } const json = [ `${this.$constants("JSON_OBJECT")}(${maping.join(", ")})`, `${this.$constants("AS")} \`${alias}\``, ].join(" "); this.$state.set("SELECT", [...this.$state.get("SELECT"), json]); return this; } /** * The 'selectObject' method is used to specify which columns you want to retrieve from a database table. * * It allows you to choose the specific columns that should be included in the result set to 'Object' of a database query. * @param {string} object table name * @param {string} alias as name of the column * @returns {this} this */ selectArray(object, alias) { if (!Object.keys(object).length) throw new Error("The method 'selectArray' is not supported for empty object"); let maping = []; for (const [key, value] of Object.entries(object)) { if (/\./.test(value)) { const [table, c] = value.split("."); maping = [...maping, `'${key}'`, `\`${table}\`.\`${c}\``]; continue; } maping = [ ...maping, `'${key}'`, `\`${this.getTableName()}\`.\`${value}\``, ]; } const json = ` ${this.$constants("CASE")} ${this.$constants("WHEN")} COUNT(${Object.values(maping)[1]}) = 0 ${this.$constants("THEN")} ${this.$constants("JSON_ARRAY")}() ${this.$constants("ELSE")} ${this.$constants("JSON_ARRAYAGG")}( ${this.$constants("JSON_OBJECT")}(${maping.join(" , ")}) ) ${this.$constants("END")} ${this.$constants("AS")} \`${alias}\` `; this.$state.set("SELECT", [...this.$state.get("SELECT"), json]); return this; } /** * The 'table' method is used to set the table name. * * @param {string} table table name * @returns {this} this */ table(table) { this.$state.set("TABLE_NAME", `\`${table.replace(/`/g, "")}\``); return this; } /** * The 'from' method is used to set the table name. * * @param {string} table table name * @returns {this} this */ from(table) { this.$state.set("TABLE_NAME", `\`${table.replace(/`/g, "")}\``); return this; } /** * The 'fromRaw' method is used to set the table name. * * @param {string} alias alias name * @param {string} from from sql raw sql from make a new alias for this table * @returns {this} this */ fromRaw(alias, from) { this.$state.set("ALIAS", alias); if (from) { this.$state.set("RAW_ALIAS", from); } return this; } /** * The 'alias' method is used to set the table name. * * @param {string} alias alias name * @param {string} from from sql raw sql from make a new alias for this table * @returns {this} this */ alias(alias, from) { this.$state.set("ALIAS", alias); if (from) { this.$state.set("RAW_ALIAS", from); } return this; } /** * The 'as' method is used to set the table name. * * @param {string} alias alias name * @param {string} from from sql raw sql from make a new alias for this table * @returns {this} this */ as(alias, from) { this.$state.set("ALIAS", alias); if (from) { this.$state.set("RAW_ALIAS", from); } return this; } /** * The 'sleep' method is used to delay the query. * * @param {number} second - The number of seconds to sleep * @returns {this} this */ sleep(second) { const sql = `(SELECT SLEEP(${second}) as sleep)`; this.$state.set("JOIN", [ ...this.$state.get("JOIN"), [ `${this.$constants("INNER_JOIN")}`, `${sql} ${this.$constants("AS")} temp`, `${this.$constants("ON")}`, `1=1`, ].join(" "), ]); return this; } /** * The 'returnType' method is used covert the results to type 'object' or 'array'. * * @param {string} type - The types 'object' | 'array' * @returns {this} this */ returnType(type) { this.$state.set("RETURN_TYPE", type); return this; } /** * The 'pluck' method is used to retrieve the value of a single column from the first result of a query. * * It is often used when you need to retrieve a single value, * such as an ID or a specific attribute, from a query result. * @param {string} column * @returns {this} */ pluck(column) { this.$state.set("PLUCK", column); return this; } /** * The 'except' method is used to specify which columns you don't want to retrieve from a database table. * * It allows you to choose the specific columns that should be not included in the result set of a database query. * @param {...string} columns * @returns {this} this */ except(...columns) { if (!columns.length) return this; const exceptColumns = this.$state.get("EXCEPTS"); this.$state.set("EXCEPTS", [...columns, ...exceptColumns]); return this; } /** * The 'exceptTimestamp' method is used to timestamp columns (created_at , updated_at) you don't want to retrieve from a database table. * * @returns {this} this */ exceptTimestamp() { this.$state.set("EXCEPTS", ["created_at", "updated_at"]); return this; } /** * The 'void' method is used to specify which you don't want to return a result from database table. * * @returns {this} this */ void() { this.$state.set("VOID", true); return this; } /** * The 'only' method is used to specify which columns you don't want to retrieve from a result. * * It allows you to choose the specific columns that should be not included in the result. * * @param {...string} columns show only colums selected * @returns {this} this */ only(...columns) { this.$state.set("ONLY", columns); return this; } /** * The 'chunk' method is used to process a large result set from a database query in smaller, manageable "chunks" or segments. * * It's particularly useful when you need to iterate over a large number of database records without loading all of them into memory at once. * * This helps prevent memory exhaustion and improves the performance of your application when dealing with large datasets. * @param {number} chunk * @returns {this} this */ chunk(chunk) { this.$state.set("CHUNK", chunk); return this; } /** * The 'when' method is used to specify if condition should be true will be next to the actions * @param {string | number | undefined | null | Boolean} condition when condition true will return query callback * @returns {this} this */ when(condition, callback) { if (!condition) return this; const cb = callback(this); if (cb instanceof Promise) throw new Error("'when' is not supported a Promise"); return this; } /** * The 'where' method is used to add conditions to a database query. * * It allows you to specify conditions that records in the database must meet in order to be included in the result set. * * If has only 2 arguments default operator '=' * @param {string} column if arguments is object * @param {string?} operator ['=', '<', '>' ,'!=', '!<', '!>' ,'LIKE'] * @param {any?} value * @returns {this} */ where(column, operator, value) { if (typeof column === "object") { return this.whereObject(column); } [value, operator] = this.$utils.valueAndOperator(value, operator, arguments.length === 2); value = this.$utils.escape(value); value = this.$utils.covertBooleanToNumber(value); if (value === null) { return this.whereNull(column); } if (Array.isArray(value)) { return this.whereIn(column, value); } this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(String(column))}`, `${operator}`, `${this.$utils.checkValueHasRaw(value)}`, ].join(" "), ]); return this; } /** * The 'orWhere' method is used to add conditions to a database query. * * It allows you to specify conditions that records in the database must meet in order to be included in the result set. * * If has only 2 arguments default operator '=' * @param {string} column * @param {string?} operator ['=', '<', '>' ,'!=', '!<', '!>' ,'LIKE'] * @param {any?} value * @returns {this} */ orWhere(column, operator, value) { [value, operator] = this.$utils.valueAndOperator(value, operator, arguments.length === 2); value = this.$utils.escape(value); value = this.$utils.covertBooleanToNumber(value); if (value === null) { return this.orWhereNull(column); } if (Array.isArray(value)) { return this.orWhereIn(column, value); } this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(String(column))}`, `${operator}`, `${this.$utils.checkValueHasRaw(value)}`, ].join(" "), ]); return this; } /** * The 'whereDay' method is used to add a "where" clause that filters results based on the day part of a date column. * * It is especially useful for querying records that fall within a specific day. * @param {string} column * @param {number} day * @returns {this} */ whereDay(column, day) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `DAY(${this.bindColumn(String(column))})`, `=`, `'${`00${this.$utils.escape(day)}`.slice(-2)}'`, ].join(" "), ]); return this; } /** * The 'whereMonth' method is used to add a "where" clause that filters results based on the month part of a date column. * * It is especially useful for querying records that fall within a specific month. * @param {string} column * @param {number} month * @returns {this} */ whereMonth(column, month) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `MONTH(${this.bindColumn(String(column))})`, `=`, `'${`00${this.$utils.escape(month)}`.slice(-2)}'`, ].join(" "), ]); return this; } /** * The 'whereYear' method is used to add a "where" clause that filters results based on the year part of a date column. * * It is especially useful for querying records that fall within a specific year. * @param {string} column * @param {number} year * @returns {this} */ whereYear(column, year) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `YEAR(${this.bindColumn(String(column))})`, `=`, `'${`0000${this.$utils.escape(year)}`.slice(-4)}'`, ].join(" "), ]); return this; } /** * The 'whereRaw' method is used to add a raw SQL condition to a database query. * * It allows you to include custom SQL expressions as conditions in your query, * which can be useful for situations where you need to perform complex or custom filtering that cannot be achieved using Laravel's standard query builder methods. * @param {string} sql where column with raw sql * @returns {this} this */ whereRaw(sql) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${sql}`, ].join(" "), ]); return this; } /** * The 'orWhereRaw' method is used to add a raw SQL condition to a database query. * * It allows you to include custom SQL expressions as conditions in your query, * which can be useful for situations where you need to perform complex or custom filtering that cannot be achieved using Laravel's standard query builder methods. * @param {string} sql where column with raw sql * @returns {this} this */ orWhereRaw(sql) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${sql}`, ].join(" "), ]); return this; } /** * The 'whereObject' method is used to add conditions to a database query. * * It allows you to specify conditions in object that records in the database must meet in order to be included in the result set. * * This method is defalut operator '=' only * @param {Object} columns * @returns {this} */ whereObject(columns) { for (const column in columns) { const operator = "="; const value = this.$utils.escape(columns[column]); const useOp = this.$utils.checkValueHasOp(value); if (useOp == null) { this.where(column, operator, value); continue; } switch (useOp.op) { case "IN": { this.whereIn(column, Array.isArray(useOp.value) ? useOp.value : useOp.value.split(",")); break; } case "|IN": { this.orWhereIn(column, Array.isArray(useOp.value) ? useOp.value : useOp.value.split(",")); break; } case "QUERY": { this.whereSubQuery(column, useOp.value); break; } case "!QUERY": { this.orWhereSubQuery(column, useOp.value); break; } case "NOT IN": { this.whereNotIn(column, Array.isArray(useOp.value) ? useOp.value : useOp.value.split(",")); break; } case "|NOT IN": { this.orWhereNotIn(column, Array.isArray(useOp.value) ? useOp.value : useOp.value.split(",")); break; } case "IS NULL": { this.whereNull(column); break; } case "|IS NULL": { this.orWhereNull(column); break; } case "IS NOT NULL": { this.whereNotNull(column); break; } case "|IS NOT NULL": { this.orWhereNotNull(column); break; } default: { if (useOp.op.includes("|")) { this.orWhere(column, useOp.op.replace("|", ""), useOp.value); break; } this.where(column, useOp.op, useOp.value); } } } return this; } /** * The 'whereJSON' method is used to add conditions to a database query. * * It allows you to specify conditions in that records json in the database must meet in order to be included in the result set. * @param {string} column * @param {object} property object { key , value , operator } * @property {string} property.key * @property {string} property.value * @property {string?} property.operator * @returns {this} */ whereJSON(column, { key, value, operator }) { value = this.$utils.escape(value); value = this.$utils.covertBooleanToNumber(value); this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}->>'$.${key}'`, `${operator == null ? "=" : operator.toLocaleUpperCase()}`, `${this.$utils.checkValueHasRaw(value)}`, ].join(" "), ]); return this; } /** * The 'whereJSON' method is used to add conditions to a database query. * * It allows you to specify conditions in that records json in the database must meet in order to be included in the result set. * @param {string} column * @param {object} property object { key , value , operator } * @property {string} property.key * @property {string} property.value * @property {string?} property.operator * @returns {this} */ whereJson(column, { key, value, operator }) { return this.whereJSON(column, { key, value, operator }); } /** * * The 'whereExists' method is used to add a conditional clause to a database query that checks for the existence of related records in a subquery or another table. * * It allows you to filter records based on whether a specified condition is true for related records. * @param {string} sql * @returns {this} */ whereExists(sql) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.$constants("EXISTS")}`, `(${sql})`, ].join(" "), ]); return this; } /** * * The 'whereExists' method is used to add a conditional clause to a database query that checks for the existence of related records in a subquery or another table. * * It allows you to filter records based on whether a specified condition is true for related records. * @param {string} sql * @returns {this} */ whereNotExists(sql) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.$constants("NOT")} ${this.$constants("EXISTS")}`, `(${sql})`, ].join(" "), ]); return this; } /** * * @param {number} id * @returns {this} this */ whereId(id, column = "id") { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)} = ${this.$utils.escape(id)}`, ].join(" "), ]); return this; } /** * * @param {string} email where using email * @returns {this} */ whereEmail(email) { const column = "email"; this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)} = ${this.$utils.escape(email)}`, ].join(" "), ]); return this; } /** * * @param {number} userId * @param {string?} column custom it *if column is not user_id * @returns {this} */ whereUser(userId, column = "user_id") { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)} = ${this.$utils.escape(userId)}`, ].join(" "), ]); return this; } /** * The 'whereIn' method is used to add a conditional clause to a database query that checks if a specified column's value is included in a given array of values. * * This method is useful when you want to filter records based on a column matching any of the values provided in an array. * @param {string} column * @param {array} array * @returns {this} */ whereIn(column, array) { if (!Array.isArray(array)) array = [array]; const values = array.length ? `${array .map((value) => this.$utils.checkValueHasRaw(this.$utils.escape(value))) .join(",")}` : this.$constants(this.$constants("NULL")); this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("IN")}`, `(${values})`, ].join(" "), ]); return this; } /** * The 'orWhereIn' method is used to add a conditional clause to a database query that checks if a specified column's value is included in a given array of values. * * This method is useful when you want to filter records based on a column matching any of the values provided in an array. * @param {string} column * @param {array} array * @returns {this} */ orWhereIn(column, array) { if (!Array.isArray(array)) array = [array]; const values = array.length ? `${array .map((value) => this.$utils.checkValueHasRaw(this.$utils.escape(value))) .join(",")}` : this.$constants(this.$constants("NULL")); this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("IN")}`, `(${values})`, ].join(" "), ]); return this; } /** * The 'whereNotIn' method is used to add a conditional clause to a database query that checks if a specified column's value is not included in a given array of values. * * This method is the opposite of whereIn and is useful when you want to filter records based on a column not matching any of the values provided in an array. * @param {string} column * @param {array} array * @returns {this} */ whereNotIn(column, array) { if (!Array.isArray(array)) array = [array]; if (!array.length) return this; const values = `${array .map((value) => this.$utils.checkValueHasRaw(this.$utils.escape(value))) .join(",")}`; this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("NOT_IN")}`, `(${values})`, ].join(" "), ]); return this; } /** * The 'orWhereNotIn' method is used to add a conditional clause to a database query that checks if a specified column's value is not included in a given array of values. * * This method is the opposite of whereIn and is useful when you want to filter records based on a column not matching any of the values provided in an array. * @param {string} column * @param {array} array * @returns {this} */ orWhereNotIn(column, array) { if (!Array.isArray(array)) array = [array]; if (!array.length) return this; const values = `${array .map((value) => this.$utils.checkValueHasRaw(this.$utils.escape(value))) .join(",")}`; this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("NOT_IN")}`, `(${values})`, ].join(" "), ]); return this; } /** * The 'whereSubQuery' method is used to add a conditional clause to a database query that involves a subquery. * * Subqueries also known as nested queries, are queries that are embedded within the main query. * * They are often used when you need to perform a query to retrieve some values and then use those values as part of the condition in the main query. * @param {string} column * @param {string} subQuery * @returns {this} */ whereSubQuery(column, subQuery, options = { operator: constants_1.CONSTANTS["IN"] }) { if (subQuery instanceof Builder && !subQuery.$state.get('SELECT').length) { subQuery.select('id'); } this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, options.operator, `(${subQuery})`, ].join(" "), ]); return this; } /** * The 'whereNotSubQuery' method is used to add a conditional clause to a database query that involves a subquery. * * Subqueries also known as nested queries, are queries that are embedded within the main query. * * They are often used when you need to perform a query to retrieve not some values and then use those values as part of the condition in the main query. * @param {string} column * @param {string} subQuery * @returns {this} */ whereNotSubQuery(column, subQuery, options = { operator: constants_1.CONSTANTS["NOT_IN"] }) { if (subQuery instanceof Builder && !subQuery.$state.get('SELECT').length) { subQuery.select('id'); } this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, options.operator, , `(${subQuery})`, ].join(" "), ]); return this; } /** * The 'orWhereSubQuery' method is used to add a conditional clause to a database query that involves a subquery. * * Subqueries also known as nested queries, are queries that are embedded within the main query. * * They are often used when you need to perform a query to retrieve some values and then use those values as part of the condition in the main query. * @param {string} column * @param {string} subQuery * @returns {this} */ orWhereSubQuery(column, subQuery, options = { operator: constants_1.CONSTANTS["IN"] }) { if (subQuery instanceof Builder && !subQuery.$state.get('SELECT').length) { subQuery.select('id'); } this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, options.operator, `(${subQuery})`, ].join(" "), ]); return this; } /** * The 'orWhereNotSubQuery' method is used to add a conditional clause to a database query that involves a subquery. * * Subqueries also known as nested queries, are queries that are embedded within the main query. * * They are often used when you need to perform a query to retrieve not some values and then use those values as part of the condition in the main query. * @param {string} column * @param {string} subQuery * @returns {this} */ orWhereNotSubQuery(column, subQuery, options = { operator: constants_1.CONSTANTS["NOT_IN"] }) { if (subQuery instanceof Builder && !subQuery.$state.get('SELECT').length) { subQuery.select('id'); } this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, options.operator, `(${subQuery})`, ].join(" "), ]); return this; } /** * The 'whereBetween' method is used to add a conditional clause to a database query that checks if a specified column's value falls within a specified range of values. * * This method is useful when you want to filter records based on a column's value being within a certain numeric or date range. * @param {string} column * @param {array} array * @returns {this} */ whereBetween(column, array) { if (!Array.isArray(array)) throw new Error("Value is't array"); if (!array.length) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("BETWEEN")}`, `${this.$constants(this.$constants("NULL"))}`, `${this.$constants("AND")}`, `${this.$constants(this.$constants("NULL"))}`, ].join(" "), ]); return this; } const [value1, value2] = array; this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("BETWEEN")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value1))}`, `${this.$constants("AND")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value2))}`, ].join(" "), ]); return this; } /** * The 'orWhereBetween' method is used to add a conditional clause to a database query that checks if a specified column's value falls within a specified range of values. * * This method is useful when you want to filter records based on a column's value being within a certain numeric or date range. * @param {string} column * @param {array} array * @returns {this} */ orWhereBetween(column, array) { if (!Array.isArray(array)) throw new Error("Value is't array"); if (!array.length) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("BETWEEN")}`, `${this.$constants(this.$constants("NULL"))}`, `${this.$constants("AND")}`, `${this.$constants(this.$constants("NULL"))}`, ].join(" "), ]); return this; } const [value1, value2] = array; this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("BETWEEN")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value1))}`, `${this.$constants("AND")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value2))}`, ].join(" "), ]); return this; } /** * The 'whereNotBetween' method is used to add a conditional clause to a database query that checks if a specified column's value falls within a specified range of values. * * This method is useful when you want to filter records based on a column's value does not fall within a specified range of values. * @param {string} column * @param {array} array * @returns {this} */ whereNotBetween(column, array) { if (!Array.isArray(array)) throw new Error("Value is't array"); if (!array.length) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("NOT_BETWEEN")}`, `${this.$constants(this.$constants("NULL"))}`, `${this.$constants("AND")}`, `${this.$constants(this.$constants("NULL"))}`, ].join(" "), ]); return this; } const [value1, value2] = array; this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("NOT_BETWEEN")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value1))}`, `${this.$constants("AND")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value2))}`, ].join(" "), ]); return this; } /** * The 'orWhereNotBetween' method is used to add a conditional clause to a database query that checks if a specified column's value falls within a specified range of values. * * This method is useful when you want to filter records based on a column's value does not fall within a specified range of values. * @param {string} column * @param {array} array * @returns {this} */ orWhereNotBetween(column, array) { if (!Array.isArray(array)) throw new Error("Value is't array"); if (!array.length) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("NOT_BETWEEN")}`, `${this.$constants(this.$constants("NULL"))}`, `${this.$constants("AND")}`, `${this.$constants(this.$constants("NULL"))}`, ].join(" "), ]); return this; } const [value1, value2] = array; this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("NOT_BETWEEN")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value1))}`, `${this.$constants("AND")}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value2))}`, ].join(" "), ]); return this; } /** * The 'whereNull' method is used to add a conditional clause to a database query that checks if a specified column's value is NULL. * * This method is helpful when you want to filter records based on whether a particular column has a NULL value. * @param {string} column * @returns {this} */ whereNull(column) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("IS_NULL")}`, ].join(" "), ]); return this; } /** * The 'orWhereNull' method is used to add a conditional clause to a database query that checks if a specified column's value is NULL. * * This method is helpful when you want to filter records based on whether a particular column has a NULL value. * @param {string} column * @returns {this} */ orWhereNull(column) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("IS_NULL")}`, ].join(" "), ]); return this; } /** * The 'whereNotNull' method is used to add a conditional clause to a database query that checks if a specified column's value is not NULL. * * This method is useful when you want to filter records based on whether a particular column has a non-null value. * @param {string} column * @returns {this} */ whereNotNull(column) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.bindColumn(column)}`, `${this.$constants("IS_NOT_NULL")}`, ].join(" "), ]); return this; } /** * The 'orWhereNotNull' method is used to add a conditional clause to a database query that checks if a specified column's value is not NULL. * * This method is useful when you want to filter records based on whether a particular column has a non-null value. * @param {string} column * @returns {this} */ orWhereNotNull(column) { this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.bindColumn(column)}`, `${this.$constants("IS_NOT_NULL")}`, ].join(" "), ]); return this; } /** * The 'whereSensitive' method is used to add conditions to a database query. * * It allows you to specify conditions that records in the database must meet in order to be included in the result set. * * The where method is need to perform a case-sensitive comparison in a query. * @param {string} column * @param {string?} operator = < > != !< !> * @param {any?} value * @returns {this} */ whereSensitive(column, operator, value) { [value, operator] = this.$utils.valueAndOperator(value, operator, arguments.length === 2); value = this.$utils.escape(value); value = this.$utils.covertBooleanToNumber(value); this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `${this.$constants("BINARY")}`, `${this.bindColumn(column)}`, `${operator}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value))}`, ].join(" "), ]); return this; } /** * The 'whereStrict' method is used to add conditions to a database query. * * It allows you to specify conditions that records in the database must meet in order to be included in the result set. * * The where method is need to perform a case-sensitive comparison in a query. * @param {string} column * @param {string?} operator = < > != !< !> * @param {any?} value * @returns {this} */ whereStrict(column, operator, value) { return this.whereSensitive(column, operator, value); } /** * The 'orWhereSensitive' method is used to add conditions to a database query. * * It allows you to specify conditions that records in the database must meet in order to be included in the result set. * * The where method is need to perform a case-sensitive comparison in a query. * @param {string} column * @param {string?} operator = < > != !< !> * @param {any?} value * @returns {this} */ orWhereSensitive(column, operator, value) { [value, operator] = this.$utils.valueAndOperator(value, operator, arguments.length === 2); value = this.$utils.escape(value); value = this.$utils.covertBooleanToNumber(value); this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("OR")}` : "", `${this.$constants("BINARY")}`, `${this.bindColumn(column)}`, `${operator}`, `${this.$utils.checkValueHasRaw(this.$utils.escape(value))}`, ].join(" "), ]); return this; } /** * The 'whereQuery' method is used to add conditions to a database query to create a grouped condition. * * It allows you to specify conditions that records in the database must meet in order to be included in the result set. * @param {Function} callback callback query * @returns {this} */ whereQuery(callback) { const db = new DB_1.DB(this.$state.get("TABLE_NAME")?.replace(/`/g, "")); const repository = callback(db); if (repository instanceof Promise) throw new Error('"whereQuery" is not supported a Promise'); if (!(repository instanceof DB_1.DB)) throw new Error(`Unknown callback query: '${repository}'`); const where = repository?.$state.get("WHERE") || []; if (!where.length) return this; const query = where.join(" "); this.$state.set("WHERE", [ ...this.$state.get("WHERE"), [ this.$state.get("WHERE").length ? `${this.$constants("AND")}` : "", `(${query})`, ].join(" "), ]); return this; } /** * The 'whereGroup' method is used to add conditions to a database query to create a grouped condition. * * It allows you to specify conditions that records in the database must meet in order to be included in the result set. * @param {function} callback callback query * @returns {this} */ whereGroup(callback) { return this.whereQuery(callback); } /** * The 'orWhereQuery' method is used to add conditions to a database query to create a grouped condition. * * It allows you to specify conditions that records in the database must meet in order to be included in the re