From e0b1bd716ecfcd279aa3a672f18ddf0fe2217391 Mon Sep 17 00:00:00 2001 From: Marcel Kloubert Date: Wed, 21 Feb 2024 08:35:53 +0100 Subject: [PATCH] feat: updateComments() function --- CHANGELOG.md | 6 +++ package-lock.json | 38 ++++++++--------- package.json | 12 +++--- src/utils/index.ts | 1 + src/utils/internal.ts | 5 +++ src/utils/updateComments.ts | 81 +++++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 25 deletions(-) create mode 100644 src/utils/updateComments.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ea6a35..6c04a6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log (@egomobile/orm-pg) +## 0.22.0 + +- add `updateComments()` function +- update to version `^0.15.0` of [node-orm](https://github.com/egomobile/node-orm) +- `npm update`(s) + ## 0.21.0 - add `chunkSize` to [IWithPostgresOptions interface](https://egomobile.github.io/node-orm-pg/interfaces/IWithPostgresOptions.html) diff --git a/package-lock.json b/package-lock.json index 8ee5108..5eff44f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,38 +1,38 @@ { "name": "@egomobile/orm-pg", - "version": "0.21.0", + "version": "0.22.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@egomobile/orm-pg", - "version": "0.21.0", + "version": "0.22.0", "license": "LGPL-3.0", "dependencies": { "change-case": "4.1.2", "sanitize-filename": "1.6.3" }, "devDependencies": { - "@egomobile/orm": "^0.14.0", + "@egomobile/orm": "^0.15.0", "@egomobile/tsconfig": "^5.0.0", "@types/node": "18.17.6", - "@types/pg": "8.10.9", + "@types/pg": "8.11.0", "@types/pg-cursor": "2.7.2", "del-cli": "5.1.0", "eslint": "8.56.0", "eslint-config-ego": "^0.19.0", - "nodemon": "3.0.2", + "nodemon": "3.0.3", "pg": "8.11.3", "pg-cursor": "2.10.3", "ts-node": "10.9.2", - "typedoc": "0.25.6", + "typedoc": "0.25.8", "typescript": "4.7.4" }, "engines": { "node": ">=18.0.0" }, "peerDependencies": { - "@egomobile/orm": ">= 0.14.0", + "@egomobile/orm": ">= 0.15.0", "pg": ">= 8.11.3" } }, @@ -236,9 +236,9 @@ } }, "node_modules/@egomobile/orm": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@egomobile/orm/-/orm-0.14.0.tgz", - "integrity": "sha512-mLjUQxD9AhgAnu4kWbfxnclBxHSFnauJbNFrwy6411ki/YdLt2QK0OfTEkr8IPAtryhnQDD39lCk7cIF0v5VWw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@egomobile/orm/-/orm-0.15.0.tgz", + "integrity": "sha512-lDTKMeJv5BCGaJgj+wTGjzkyDHKTiADuR0iXCE1O5w+gZXhML4HwvOMWQ0NlRR7KDcJ3RW60+GOR7oXRnGHGbw==", "dev": true, "dependencies": { "@types/node": "18.17.6" @@ -474,9 +474,9 @@ "dev": true }, "node_modules/@types/pg": { - "version": "8.10.9", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz", - "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.0.tgz", + "integrity": "sha512-sDAlRiBNthGjNFfvt0k6mtotoVYVQ63pA8R4EMWka7crawSR60waVYR0HAgmPRs/e2YaeJTD/43OoZ3PFw80pw==", "dev": true, "dependencies": { "@types/node": "*", @@ -3285,9 +3285,9 @@ } }, "node_modules/nodemon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.2.tgz", - "integrity": "sha512-9qIN2LNTrEzpOPBaWHTm4Asy1LxXLSickZStAQ4IZe7zsoIpD/A7LWxhZV3t4Zu352uBcqVnRsDXSMR2Sc3lTA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.3.tgz", + "integrity": "sha512-7jH/NXbFPxVaMwmBCC2B9F/V6X1VkEdNgx3iu9jji8WxWcvhMWkmhNWhI5077zknOnZnBzba9hZP6bCPJLSReQ==", "dev": true, "dependencies": { "chokidar": "^3.5.2", @@ -4967,9 +4967,9 @@ } }, "node_modules/typedoc": { - "version": "0.25.6", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.6.tgz", - "integrity": "sha512-1rdionQMpOkpA58qfym1J+YD+ukyA1IEIa4VZahQI2ZORez7dhOvEyUotQL/8rSoMBopdzOS+vAIsORpQO4cTA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.8.tgz", + "integrity": "sha512-mh8oLW66nwmeB9uTa0Bdcjfis+48bAjSH3uqdzSuSawfduROQLlXw//WSNZLYDdhmMVB7YcYZicq6e8T0d271A==", "dev": true, "dependencies": { "lunr": "^2.3.9", diff --git a/package.json b/package.json index d81e1b6..df37842 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@egomobile/orm-pg", - "version": "0.21.0", + "version": "0.22.0", "description": "A PostgreSQL data adapter and other utilities for @egomobile/orm module.", "main": "lib/index.js", "engines": { @@ -49,23 +49,23 @@ "sanitize-filename": "1.6.3" }, "devDependencies": { - "@egomobile/orm": "^0.14.0", + "@egomobile/orm": "^0.15.0", "@egomobile/tsconfig": "^5.0.0", "@types/node": "18.17.6", - "@types/pg": "8.10.9", + "@types/pg": "8.11.0", "@types/pg-cursor": "2.7.2", "del-cli": "5.1.0", "eslint": "8.56.0", "eslint-config-ego": "^0.19.0", - "nodemon": "3.0.2", + "nodemon": "3.0.3", "pg": "8.11.3", "pg-cursor": "2.10.3", "ts-node": "10.9.2", - "typedoc": "0.25.6", + "typedoc": "0.25.8", "typescript": "4.7.4" }, "peerDependencies": { - "@egomobile/orm": ">= 0.14.0", + "@egomobile/orm": ">= 0.15.0", "pg": ">= 8.11.3" } } \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts index ad35de0..3d60d32 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -369,4 +369,5 @@ export function registerBigIntAsNumber(options?: Nilable( return [itemOrList]; } +export function escapeStringForQuery(val: any): string { + return String(val ?? "") + .replace(/'/g, "''"); +} + export function isIterable(obj: any): obj is List { if (obj) { return typeof obj[Symbol.iterator] === "function"; diff --git a/src/utils/updateComments.ts b/src/utils/updateComments.ts new file mode 100644 index 0000000..f93046a --- /dev/null +++ b/src/utils/updateComments.ts @@ -0,0 +1,81 @@ +// This file is part of the @egomobile/orm-pg distribution. +// Copyright (c) Next.e.GO Mobile SE, Aachen, Germany (https://e-go-mobile.com/) +// +// @egomobile/orm-pg is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3. +// +// @egomobile/orm-pg is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +import type { EntityConfigurations, IDataContext } from "@egomobile/orm"; +import { escapeStringForQuery } from "./internal"; + +/** + * Options for `updateComments()` function. + */ +export interface IUpdateCommentsOptions { + /** + * The configurations from where to get the documentation/comments from. + */ + configurations: EntityConfigurations; + /** + * The underlying database connection / context. + */ + context: IDataContext; +} + +/** + * Updates the COMMENT attributes of documented tables and columns. + * + * @param {IUpdateCommentsOptions} options The options. + */ +export async function updateComments(options: IUpdateCommentsOptions) { + const { + configurations, + context + } = options; + + const entityConfigEntries = Object.entries(configurations); + for (const [tableName, tableConfig] of entityConfigEntries) { + const tableComment = tableConfig?.comment?.trim(); + if (typeof tableComment === "string") { + let updateTableCommentQuery: string; + if (tableComment !== "") { + const escapedTableComment = escapeStringForQuery(tableComment); + + updateTableCommentQuery = `COMMENT ON TABLE ${tableName} IS '${escapedTableComment}';`; + } + else { + updateTableCommentQuery = `COMMENT ON TABLE ${tableName} IS NULL;`; + } + + await context.query(updateTableCommentQuery); + } + + const tableColumnConfigEntries = Object.entries(tableConfig.fields ?? {}); + for (const [columnName, columnConfig] of tableColumnConfigEntries) { + const fullColumnName = `${tableName}.${columnName}`; + + const tableColumnComment = columnConfig?.comment?.trim(); + if (typeof tableColumnComment === "string") { + let updateTableColumnCommentQuery: string; + if (tableColumnComment !== "") { + const escapedTableColumnComment = escapeStringForQuery(tableColumnComment); + + updateTableColumnCommentQuery = `COMMENT ON TABLE ${fullColumnName} IS '${escapedTableColumnComment}';`; + } + else { + updateTableColumnCommentQuery = `COMMENT ON TABLE ${fullColumnName} IS NULL;`; + } + + await context.query(updateTableColumnCommentQuery); + } + } + } +}