diff --git a/bun.lockb b/bun.lockb old mode 100644 new mode 100755 index 7a988b4..62eaa29 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/dist/package-shared/functions/backend/db/addDbEntry.js b/dist/package-shared/functions/backend/db/addDbEntry.js index a151756..687d844 100644 --- a/dist/package-shared/functions/backend/db/addDbEntry.js +++ b/dist/package-shared/functions/backend/db/addDbEntry.js @@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = addDbEntry; +const sql_formatter_1 = require("sql-formatter"); const updateDbEntry_1 = __importDefault(require("./updateDbEntry")); const lodash_1 = __importDefault(require("lodash")); const conn_db_handler_1 = __importDefault(require("../../../utils/db/conn-db-handler")); @@ -191,7 +192,7 @@ function addDbEntry(_a) { success: Boolean(newInsert === null || newInsert === void 0 ? void 0 : newInsert.insertId), payload: newInsert, queryObject: { - sql: query, + sql: (0, sql_formatter_1.format)(query), params: finalQueryValues, }, }; diff --git a/dist/package-shared/functions/backend/db/updateDbEntry.js b/dist/package-shared/functions/backend/db/updateDbEntry.js index 6c919ae..c2d05fa 100644 --- a/dist/package-shared/functions/backend/db/updateDbEntry.js +++ b/dist/package-shared/functions/backend/db/updateDbEntry.js @@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = updateDbEntry; +const sql_formatter_1 = require("sql-formatter"); const check_if_is_master_1 = __importDefault(require("../../../utils/check-if-is-master")); const conn_db_handler_1 = __importDefault(require("../../../utils/db/conn-db-handler")); const lodash_1 = __importDefault(require("lodash")); @@ -109,7 +110,7 @@ function updateDbEntry(_a) { success: Boolean(updatedEntry === null || updatedEntry === void 0 ? void 0 : updatedEntry.affectedRows), payload: updatedEntry, queryObject: { - sql: query, + sql: (0, sql_formatter_1.format)(query), params: updateValues, }, debug: debug ? { data, newData } : undefined, diff --git a/dist/package-shared/functions/dsql/sql/sql-generator.js b/dist/package-shared/functions/dsql/sql/sql-generator.js index b46430f..619b5c3 100644 --- a/dist/package-shared/functions/dsql/sql/sql-generator.js +++ b/dist/package-shared/functions/dsql/sql/sql-generator.js @@ -77,55 +77,9 @@ function sqlGenerator({ tableName, genObject, dbFullName, count }) { else if (operatorStrParam.str) { str = operatorStrParam.str; } - // if (queryObj.equality == "LIKE") { - // str = `LOWER(${finalFieldName}) LIKE LOWER('%${valueParsed}%')`; - // } else if (queryObj.equality == "LIKE_RAW") { - // str = `LOWER(${finalFieldName}) LIKE LOWER(?)`; - // sqlSearhValues.push(valueParsed); - // } else if (queryObj.equality == "NOT LIKE") { - // str = `LOWER(${finalFieldName}) NOT LIKE LOWER('%${valueParsed}%')`; - // } else if (queryObj.equality == "NOT LIKE_RAW") { - // str = `LOWER(${finalFieldName}) NOT LIKE LOWER(?)`; - // sqlSearhValues.push(valueParsed); - // } else if (queryObj.equality == "REGEXP") { - // str = `LOWER(${finalFieldName}) REGEXP LOWER(?)`; - // sqlSearhValues.push(valueParsed); - // } else if (queryObj.equality == "FULLTEXT") { - // str = `MATCH(${finalFieldName}) AGAINST(? IN BOOLEAN MODE)`; - // sqlSearhValues.push(valueParsed); - // } else if (queryObj.equality == "NOT EQUAL") { - // str = `${finalFieldName} != ?`; - // sqlSearhValues.push(valueParsed); - // } else if (queryObj.equality) { - // str = `${finalFieldName} ${operator} ?`; - // sqlSearhValues.push(valueParsed); - // } else { - // sqlSearhValues.push(valueParsed); - // } } return str; } - const sqlSearhString = queryKeys === null || queryKeys === void 0 ? void 0 : queryKeys.map((field) => { - const queryObj = finalQuery === null || finalQuery === void 0 ? void 0 : finalQuery[field]; - if (!queryObj) - return; - if (queryObj.__query) { - const subQueryGroup = queryObj.__query; - const subSearchKeys = Object.keys(subQueryGroup); - const subSearchString = subSearchKeys.map((_field) => { - const newSubQueryObj = subQueryGroup === null || subQueryGroup === void 0 ? void 0 : subQueryGroup[_field]; - return genSqlSrchStr({ - queryObj: newSubQueryObj, - field: _field, - join: genObject === null || genObject === void 0 ? void 0 : genObject.join, - }); - }); - return ("(" + - subSearchString.join(` ${queryObj.operator || "AND"} `) + - ")"); - } - return genSqlSrchStr({ queryObj, field, join: genObject === null || genObject === void 0 ? void 0 : genObject.join }); - }); function generateJoinStr(mtch, join) { return `${finalDbName}${typeof mtch.source == "object" ? mtch.source.tableName : tableName}.${typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source}=${(() => { if (mtch.targetLiteral) { @@ -173,6 +127,32 @@ function sqlGenerator({ tableName, genObject, dbFullName, count }) { str += " *"; } } + if (genObject === null || genObject === void 0 ? void 0 : genObject.countSubQueries) { + let countSqls = []; + for (let i = 0; i < genObject.countSubQueries.length; i++) { + const countSubQuery = genObject.countSubQueries[i]; + let subQStr = `(SELECT COUNT(*)`; + subQStr += ` FROM ${countSubQuery.table}`; + subQStr += ` WHERE (`; + for (let j = 0; j < countSubQuery.srcTrgMap.length; j++) { + const csqSrc = countSubQuery.srcTrgMap[j]; + subQStr += ` ${countSubQuery.table}.${csqSrc.src}`; + if (typeof csqSrc.trg == "string") { + subQStr += ` = ?`; + sqlSearhValues.push(csqSrc.trg); + } + else if (typeof csqSrc.trg == "object") { + subQStr += ` = ${csqSrc.trg.table}.${csqSrc.trg.field}`; + } + if (j < countSubQuery.srcTrgMap.length - 1) { + subQStr += ` AND `; + } + } + subQStr += ` )) AS ${countSubQuery.alias}`; + countSqls.push(subQStr); + } + str += `, ${countSqls.join(",")}`; + } if ((genObject === null || genObject === void 0 ? void 0 : genObject.join) && !count) { const existingJoinTableNames = [tableName]; str += @@ -242,6 +222,27 @@ function sqlGenerator({ tableName, genObject, dbFullName, count }) { } return str; })(); + const sqlSearhString = queryKeys === null || queryKeys === void 0 ? void 0 : queryKeys.map((field) => { + const queryObj = finalQuery === null || finalQuery === void 0 ? void 0 : finalQuery[field]; + if (!queryObj) + return; + if (queryObj.__query) { + const subQueryGroup = queryObj.__query; + const subSearchKeys = Object.keys(subQueryGroup); + const subSearchString = subSearchKeys.map((_field) => { + const newSubQueryObj = subQueryGroup === null || subQueryGroup === void 0 ? void 0 : subQueryGroup[_field]; + return genSqlSrchStr({ + queryObj: newSubQueryObj, + field: _field, + join: genObject === null || genObject === void 0 ? void 0 : genObject.join, + }); + }); + return ("(" + + subSearchString.join(` ${queryObj.operator || "AND"} `) + + ")"); + } + return genSqlSrchStr({ queryObj, field, join: genObject === null || genObject === void 0 ? void 0 : genObject.join }); + }); if ((sqlSearhString === null || sqlSearhString === void 0 ? void 0 : sqlSearhString[0]) && sqlSearhString.find((str) => str)) { const stringOperator = (genObject === null || genObject === void 0 ? void 0 : genObject.searchOperator) || "AND"; queryString += ` WHERE ${sqlSearhString.join(` ${stringOperator} `)}`; diff --git a/dist/package-shared/types/index.d.ts b/dist/package-shared/types/index.d.ts index 4463f4b..d1c9f33 100644 --- a/dist/package-shared/types/index.d.ts +++ b/dist/package-shared/types/index.d.ts @@ -827,8 +827,21 @@ export type ServerQueryParam[]; group?: (keyof T)[]; + countSubQueries?: ServerQueryParamsCount[]; [key: string]: any; }; +export type ServerQueryParamsCount = { + table: string; + srcTrgMap: { + src: string; + trg: string | ServerQueryParamsCountSrcTrgMap; + }[]; + alias: string; +}; +export type ServerQueryParamsCountSrcTrgMap = { + table: string; + field: string; +}; export type TableSelectFieldsObject { - const queryObj = finalQuery?.[field]; - if (!queryObj) return; - - if (queryObj.__query) { - const subQueryGroup = queryObj.__query; - - const subSearchKeys = Object.keys(subQueryGroup); - const subSearchString = subSearchKeys.map((_field) => { - const newSubQueryObj = subQueryGroup?.[_field]; - - return genSqlSrchStr({ - queryObj: newSubQueryObj, - field: _field, - join: genObject?.join, - }); - }); - - return ( - "(" + - subSearchString.join(` ${queryObj.operator || "AND"} `) + - ")" - ); - } - - return genSqlSrchStr({ queryObj, field, join: genObject?.join }); - }); - function generateJoinStr( mtch: ServerQueryParamsJoinMatchObject, join: ServerQueryParamsJoin @@ -239,6 +185,38 @@ export default function sqlGenerator< } } + if (genObject?.countSubQueries) { + let countSqls: string[] = []; + + for (let i = 0; i < genObject.countSubQueries.length; i++) { + const countSubQuery = genObject.countSubQueries[i]; + let subQStr = `(SELECT COUNT(*)`; + subQStr += ` FROM ${countSubQuery.table}`; + subQStr += ` WHERE (`; + + for (let j = 0; j < countSubQuery.srcTrgMap.length; j++) { + const csqSrc = countSubQuery.srcTrgMap[j]; + subQStr += ` ${countSubQuery.table}.${csqSrc.src}`; + + if (typeof csqSrc.trg == "string") { + subQStr += ` = ?`; + sqlSearhValues.push(csqSrc.trg); + } else if (typeof csqSrc.trg == "object") { + subQStr += ` = ${csqSrc.trg.table}.${csqSrc.trg.field}`; + } + + if (j < countSubQuery.srcTrgMap.length - 1) { + subQStr += ` AND `; + } + } + + subQStr += ` )) AS ${countSubQuery.alias}`; + countSqls.push(subQStr); + } + + str += `, ${countSqls.join(",")}`; + } + if (genObject?.join && !count) { const existingJoinTableNames: string[] = [tableName]; @@ -320,6 +298,34 @@ export default function sqlGenerator< return str; })(); + const sqlSearhString = queryKeys?.map((field) => { + const queryObj = finalQuery?.[field]; + if (!queryObj) return; + + if (queryObj.__query) { + const subQueryGroup = queryObj.__query; + + const subSearchKeys = Object.keys(subQueryGroup); + const subSearchString = subSearchKeys.map((_field) => { + const newSubQueryObj = subQueryGroup?.[_field]; + + return genSqlSrchStr({ + queryObj: newSubQueryObj, + field: _field, + join: genObject?.join, + }); + }); + + return ( + "(" + + subSearchString.join(` ${queryObj.operator || "AND"} `) + + ")" + ); + } + + return genSqlSrchStr({ queryObj, field, join: genObject?.join }); + }); + if (sqlSearhString?.[0] && sqlSearhString.find((str) => str)) { const stringOperator = genObject?.searchOperator || "AND"; queryString += ` WHERE ${sqlSearhString.join(` ${stringOperator} `)}`; diff --git a/package-shared/types/index.ts b/package-shared/types/index.ts index f92cd3b..ffb7530 100644 --- a/package-shared/types/index.ts +++ b/package-shared/types/index.ts @@ -1012,9 +1012,24 @@ export type ServerQueryParam< }; join?: ServerQueryParamsJoin[]; group?: (keyof T)[]; + countSubQueries?: ServerQueryParamsCount[]; [key: string]: any; }; +export type ServerQueryParamsCount = { + table: string; + srcTrgMap: { + src: string; + trg: string | ServerQueryParamsCountSrcTrgMap; + }[]; + alias: string; +}; + +export type ServerQueryParamsCountSrcTrgMap = { + table: string; + field: string; +}; + export type TableSelectFieldsObject< T extends { [k: string]: any } = { [k: string]: any } > = { @@ -1858,7 +1873,11 @@ export const ImageMimeTypes: (keyof sharp.FormatEnum)[] = [ "jpg", ] as const; +export const VideoMimeTypes = ["mp4", "wav"] as const; + export const FileMimeTypes = [ + ...ImageMimeTypes, + ...VideoMimeTypes, "pdf", "csv", "json", @@ -1879,8 +1898,6 @@ export const FileMimeTypes = [ "css", ] as const; -export const VideoMimeTypes = ["mp4", "wav"] as const; - export const CurrentlyEditedFieldActions = [ "edit-field", "edit-index", diff --git a/package-shared/utils/data-fetching/crud-get.ts b/package-shared/utils/data-fetching/crud-get.ts index 432d10e..f13c203 100644 --- a/package-shared/utils/data-fetching/crud-get.ts +++ b/package-shared/utils/data-fetching/crud-get.ts @@ -1,3 +1,4 @@ +import { format } from "sql-formatter"; import sqlGenerator from "../../functions/dsql/sql/sql-generator"; import { APIResponseObject, DsqlCrudParam } from "../../types"; import connDbHandler, { ConnDBHandlerQueryObject } from "../db/conn-db-handler"; @@ -85,11 +86,11 @@ export default async function < : undefined, errors: res?.errors, queryObject: { - sql: queryObject?.string, + sql: format(queryObject?.string || "") || undefined, params: queryObject?.values, }, countQueryObject: { - sql: countQueryObject?.string, + sql: format(countQueryObject?.string || "") || undefined, params: countQueryObject?.values, }, count: isSuccess diff --git a/package-shared/utils/data-fetching/crud.ts b/package-shared/utils/data-fetching/crud.ts index db19fc5..da9492e 100644 --- a/package-shared/utils/data-fetching/crud.ts +++ b/package-shared/utils/data-fetching/crud.ts @@ -1,3 +1,4 @@ +import { format } from "sql-formatter"; import sqlDeleteGenerator from "../../functions/dsql/sql/sql-delete-generator"; import { APIResponseObject, @@ -94,7 +95,7 @@ export default async function dsqlCrud< success: Boolean(res.affectedRows), payload: res, queryObject: { - sql: deleteQuery?.query || "", + sql: format(deleteQuery?.query || ""), params: deleteQuery?.values || [], }, }; diff --git a/package.json b/package.json index b45edf5..22bc50f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@moduletrace/datasquirel", - "version": "5.4.3", + "version": "5.4.4", "description": "Cloud-based SQL data management tool", "main": "dist/index.js", "bin": { @@ -46,6 +46,7 @@ "lodash": "^4.17.21", "mariadb": "^3.4.4", "nodemailer": "^6.9.14", - "sanitize-html": "^2.13.1" + "sanitize-html": "^2.13.1", + "sql-formatter": "^15.6.10" } }