|
| 1 | +import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; |
| 2 | +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; |
| 3 | +import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; |
| 4 | +import AbstractUseCase from '../../../common/abstract-use.case.js'; |
| 5 | +import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; |
| 6 | +import { BaseType } from '../../../common/data-injection.tokens.js'; |
| 7 | +import { ExceptionOperations } from '../../../exceptions/custom-exceptions/exception-operation.js'; |
| 8 | +import { UnknownSQLException } from '../../../exceptions/custom-exceptions/unknown-sql-exception.js'; |
| 9 | +import { Messages } from '../../../exceptions/text/messages.js'; |
| 10 | +import { CedarPermissionsService } from '../../cedar-authorization/cedar-permissions.service.js'; |
| 11 | +import { buildFoundTableWidgetDs } from '../../widget/utils/build-found-table-widget-ds.js'; |
| 12 | +import { GetTableStructureDs } from '../application/data-structures/get-table-structure-ds.js'; |
| 13 | +import { TableStructureDs } from '../table-datastructures.js'; |
| 14 | +import { attachForeignColumnNames } from '../utils/attach-foreign-column-names.util.js'; |
| 15 | +import { extractForeignKeysFromWidgets } from '../utils/extract-foreign-keys-from-widgets.util.js'; |
| 16 | +import { filterForeignKeysByReadPermission } from '../utils/filter-foreign-keys-by-permission.util.js'; |
| 17 | +import { formFullTableStructure } from '../utils/form-full-table-structure.js'; |
| 18 | +import { getUserEmailForAgent, validateConnection } from '../utils/validate-connection.util.js'; |
| 19 | +import { IGetTableStructureWithoutCache } from './table-use-cases.interface.js'; |
| 20 | + |
| 21 | +@Injectable() |
| 22 | +export class GetTableStructureWithoutCacheUseCase |
| 23 | + extends AbstractUseCase<GetTableStructureDs, TableStructureDs> |
| 24 | + implements IGetTableStructureWithoutCache |
| 25 | +{ |
| 26 | + constructor( |
| 27 | + @Inject(BaseType.GLOBAL_DB_CONTEXT) |
| 28 | + protected _dbContext: IGlobalDatabaseContext, |
| 29 | + private readonly cedarPermissions: CedarPermissionsService, |
| 30 | + ) { |
| 31 | + super(); |
| 32 | + } |
| 33 | + |
| 34 | + protected async implementation(inputData: GetTableStructureDs): Promise<TableStructureDs> { |
| 35 | + const { connectionId, masterPwd, tableName, userId } = inputData; |
| 36 | + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( |
| 37 | + connectionId, |
| 38 | + masterPwd, |
| 39 | + ); |
| 40 | + validateConnection(foundConnection); |
| 41 | + |
| 42 | + try { |
| 43 | + const dao = getDataAccessObject(foundConnection); |
| 44 | + const foundTalesInConnection = await dao.getTablesFromDB(); |
| 45 | + if (!foundTalesInConnection.find((el) => el.tableName === tableName)) { |
| 46 | + throw new HttpException( |
| 47 | + { |
| 48 | + message: Messages.TABLE_NOT_FOUND, |
| 49 | + }, |
| 50 | + HttpStatus.BAD_REQUEST, |
| 51 | + ); |
| 52 | + } |
| 53 | + const userEmail = await getUserEmailForAgent(foundConnection, userId, this._dbContext.userRepository); |
| 54 | + |
| 55 | + // eslint-disable-next-line prefer-const |
| 56 | + let [tableSettings, personalTableSettings, tablePrimaryColumns, tableForeignKeys, tableStructure, tableWidgets] = |
| 57 | + await Promise.all([ |
| 58 | + this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), |
| 59 | + this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), |
| 60 | + dao.getTablePrimaryColumns(tableName, userEmail), |
| 61 | + dao.getTableForeignKeys(tableName, userEmail), |
| 62 | + dao.getTableStructureWithoutCache(tableName, userEmail), |
| 63 | + this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName), |
| 64 | + ]); |
| 65 | + const foreignKeysFromWidgets = extractForeignKeysFromWidgets(tableWidgets); |
| 66 | + |
| 67 | + tableForeignKeys = tableForeignKeys.concat(foreignKeysFromWidgets); |
| 68 | + let transformedTableForeignKeys: Array<ForeignKeyWithAutocompleteColumnsDS> = []; |
| 69 | + tableForeignKeys = await filterForeignKeysByReadPermission( |
| 70 | + tableForeignKeys, |
| 71 | + userId, |
| 72 | + connectionId, |
| 73 | + masterPwd, |
| 74 | + this.cedarPermissions, |
| 75 | + ); |
| 76 | + |
| 77 | + if (tableForeignKeys && tableForeignKeys.length > 0) { |
| 78 | + transformedTableForeignKeys = await Promise.all( |
| 79 | + tableForeignKeys.map((el) => |
| 80 | + attachForeignColumnNames( |
| 81 | + el, |
| 82 | + userEmail, |
| 83 | + connectionId, |
| 84 | + dao, |
| 85 | + this._dbContext.tableSettingsRepository.findTableSettings.bind(this._dbContext.tableSettingsRepository), |
| 86 | + ).catch(() => el as ForeignKeyWithAutocompleteColumnsDS), |
| 87 | + ), |
| 88 | + ); |
| 89 | + } |
| 90 | + const readonly_fields = tableSettings?.readonly_fields?.length > 0 ? tableSettings.readonly_fields : []; |
| 91 | + const formedTableStructure = formFullTableStructure(tableStructure, tableSettings); |
| 92 | + return { |
| 93 | + structure: formedTableStructure, |
| 94 | + primaryColumns: tablePrimaryColumns, |
| 95 | + foreignKeys: transformedTableForeignKeys, |
| 96 | + readonly_fields: readonly_fields, |
| 97 | + table_widgets: tableWidgets?.length > 0 ? tableWidgets.map((widget) => buildFoundTableWidgetDs(widget)) : [], |
| 98 | + list_fields: personalTableSettings?.list_fields ? personalTableSettings.list_fields : [], |
| 99 | + display_name: tableSettings?.display_name ? tableSettings.display_name : null, |
| 100 | + excluded_fields: tableSettings?.excluded_fields ? tableSettings.excluded_fields : [], |
| 101 | + }; |
| 102 | + } catch (e) { |
| 103 | + if (e instanceof HttpException) { |
| 104 | + throw e; |
| 105 | + } |
| 106 | + throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_GET_TABLE_STRUCTURE); |
| 107 | + } |
| 108 | + } |
| 109 | +} |
0 commit comments