Ajuste conexao oracle & postgres

This commit is contained in:
unknown
2025-03-28 17:03:25 -03:00
parent d2ffb266db
commit b98b219e52
28 changed files with 916 additions and 1383 deletions

View File

@@ -1,22 +1,16 @@
/* eslint-disable prettier/prettier */
import { DataSourceOptions } from 'typeorm/data-source';
import { registerAs } from '@nestjs/config';
export const typeOrmConfig: DataSourceOptions = {
type: 'oracle',
connectString: '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.1.241)(PORT = 1521)))(CONNECT_DATA = (SERVICE_NAME = WINT)))',
username: 'SEVEN',
password: 'USR54SEV',
synchronize: false,
logging: false,
entities: [__dirname + '/../**/*.entity.{js,ts}'],
};
export const typeOrmPgConfig: DataSourceOptions = {
type: 'postgres',
host: '10.1.1.222',
port: 5432,
username: 'ti',
password: 'ti',
database: 'ksdb',
synchronize: true,
}
export const databaseConfig = registerAs('database', () => ({
oracle: {
connectString: `(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = ${process.env.ORACLE_HOST})(PORT = ${process.env.ORACLE_PORT})))(CONNECT_DATA = (SERVICE_NAME = ${process.env.ORACLE_SERVICE})))`,
username: process.env.ORACLE_USER,
password: process.env.ORACLE_PASSWORD,
},
postgres: {
host: process.env.POSTGRES_HOST,
port: parseInt(process.env.POSTGRES_PORT || '5432', 10),
username: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DB,
},
}));

View File

@@ -0,0 +1,14 @@
import { DataSourceOptions } from 'typeorm';
import { ConfigService } from '@nestjs/config';
export function createOracleConfig(config: ConfigService): DataSourceOptions {
return {
type: 'oracle',
connectString: config.get('ORACLE_CONNECT_STRING'),
username: config.get('ORACLE_USER'),
password: config.get('ORACLE_PASSWORD'),
synchronize: false,
logging: false,
entities: [__dirname + '/../**/*.entity.{ts,js}'],
};
}

View File

@@ -0,0 +1,15 @@
import { DataSourceOptions } from 'typeorm';
import { ConfigService } from '@nestjs/config';
export function createPostgresConfig(config: ConfigService): DataSourceOptions {
return {
type: 'postgres',
host: config.get('POSTGRES_HOST'),
port: config.get('POSTGRES_PORT'),
username: config.get('POSTGRES_USER'),
password: config.get('POSTGRES_PASSWORD'),
database: config.get('POSTGRES_DB'),
synchronize: true,
entities: [__dirname + '/../**/*.entity.{ts,js}'],
};
}

View File

@@ -1,101 +0,0 @@
import { DropAction } from './../../../node_modules/aws-sdk/clients/mailmanager.d';
/*
https://docs.nestjs.com/controllers#controllers
*/
import {
Body,
Controller,
Get,
HttpException,
HttpStatus,
Post,
Query,
Req,
UseInterceptors,
UploadedFile,
} from '@nestjs/common';
import { BaseService } from './base.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';
import * as fs from 'fs';
@Controller('api/v1/base')
export class BaseController {
constructor(public readonly baseService: BaseService) {}
// @UseGuards(JwtAuthGuard)
@Get('execute-view')
/* @ApiOperation({
summary: 'Executa uma view com ou sem parâmetros',
})
@ApiResponse({
status: 200,
description: 'Dados retornados com sucesso.',
})
@ApiResponse({
status: 400,
description: 'O nome da view é obrigatório.',
})
@ApiResponse({
status: 500,
description: 'Erro ao executar a view.',
})*/
async executeView(
@Query('viewName') viewName: string,
@Query() params: Record<string, any>,
) {
if (!viewName) {
throw new HttpException(
'O nome da view é obrigatório.',
HttpStatus.BAD_REQUEST,
);
}
try {
return await this.baseService.executeView(viewName, params);
} catch (error) {
throw new HttpException(
`Erro ao executar a view: ${error.message}`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
@Post('send-image')
@UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
// Pasta onde os arquivos serão salvos; certifique-se que essa pasta exista ou crie-a automaticamente
destination: './uploads',
filename: (req, file, callback) => {
// Gera um nome único para o arquivo
const uniqueSuffix =
Date.now() + '-' + Math.round(Math.random() * 1e9);
const fileExtName = extname(file.originalname);
callback(null, `${file.fieldname}-${uniqueSuffix}${fileExtName}`);
},
}),
// Opcional: definir limites (ex.: tamanho máximo do arquivo)
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
}),
)
async sendImage(
@UploadedFile() file: Express.Multer.File,
@Body('licensePlate') licensePlate: string,
) {
if (!file) {
throw new HttpException('Nenhum arquivo enviado', HttpStatus.BAD_REQUEST);
}
// Aqui você pode processar o arquivo (ex.: enviar para o S3) ou armazená-lo no disco mesmo.
// Neste exemplo, retornamos a URL do arquivo salvo localmente.
this.baseService.sendImages('./uploads/' + file.filename);
fs.unlink('./uploads/' + file.filename, () => {});
return {
success: true,
message: 'Upload realizado com sucesso',
url: `https://jur-saidaretornoveiculo.s3.sa-east-1.amazonaws.com/${file.filename}`,
licensePlate,
};
}
}

View File

@@ -1,14 +0,0 @@
import { BaseController } from './base.controller';
/*
https://docs.nestjs.com/modules
*/
import { Module } from '@nestjs/common';
import { BaseService } from './base.service';
@Module({
imports: [],
controllers: [BaseController],
providers: [BaseService],
})
export class BaseModule {}

View File

@@ -1,331 +0,0 @@
import {
Inject,
Injectable,
InternalServerErrorException,
} from '@nestjs/common';
import { DataSource } from 'typeorm';
import { typeOrmConfig } from '../configs/typeorm.config';
import { S3 } from 'aws-sdk';
import * as fs from 'fs';
@Injectable()
export class BaseService {
constructor() {}
async findAll(table: string) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [rows] = await queryRunner.query(`SELECT * FROM ${table}`);
return rows;
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao buscar todos os registros da tabela ${table}`,
);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async findOne(table: string, id: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [rows] = await queryRunner.query(
`SELECT * FROM ${table} WHERE id = '${id}'`,
);
return rows[0];
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao buscar o registro com ID ${id} na tabela ${table}`,
);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async create(table: string, data: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const columns = Object.keys(data)
.map((key) => `${key}`)
.join(', ');
const values = Object.values(data);
const placeholders = values.map(() => '?').join(', ');
const query = `INSERT INTO ${table} (${columns}) VALUES (${placeholders})`;
const [result] = await queryRunner.query(query, values);
return result;
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao criar um registro na tabela ${table}`,
);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async update(table: string, where: any, data: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [result] = await queryRunner.query(
`UPDATE ${table} SET ${data} WHERE ${where}`,
);
return result;
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao atualizar o registro com ${where} na tabela ${table}`,
);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async delete(table: string, where: any) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [result] = await queryRunner.query(
`DELETE FROM ${table} WHERE ${where}`,
);
return result;
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao deletar o registro com ID ${where} na tabela ${table}`,
);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async query(queryString: string, params: any[]): Promise<any[]> {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const [rows] = await queryRunner.query(queryString, params);
return rows as any[];
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao executar a consulta SQL personalizada`,
);
} finally {
queryRunner.release();
dataSource.destroy();
}
}
async executeView(viewName: string, params: Record<string, any>) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
// Valida se o nome da view foi fornecido
if (!viewName) {
throw new Error('O nome da view é obrigatório.');
}
console.log(`Iniciando execução da view: ${viewName}`);
console.log('Parâmetros recebidos:', params);
const conditions: string[] = [];
const values: any[] = [];
// Remove o parâmetro viewName dos parâmetros antes de processar
const filteredParams = { ...params };
delete filteredParams.viewName;
// Adiciona as condições baseadas nos parâmetros fornecidos
if (filteredParams && Object.keys(filteredParams).length > 0) {
console.log('Adicionando condições para os parâmetros fornecidos...');
for (const [key, value] of Object.entries(filteredParams)) {
// Verifica se a chave e o valor são válidos
if (value !== undefined && value !== null && value !== '') {
console.log(`Parâmetro válido: ${key} = '${value}'`);
conditions.push(`${key} = '${value}'`); // Adiciona aspas para evitar problemas de SQL injection
values.push(value);
} else {
console.warn(`Parâmetro ignorado: ${key} = '${value}'`);
}
}
} else {
console.log('Nenhum parâmetro válido foi fornecido.');
}
// Monta a cláusula WHERE somente se houver condições
const whereClause =
conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
const query = `SELECT * FROM ${viewName} ${whereClause}`;
console.log(`Consulta SQL montada: ${query}`);
console.log(`{Valores para a consulta:, ${values}`);
// Executa a consulta
const rows = await queryRunner.query(query);
console.log(
`Consulta executada com sucesso.Linhas retornadas: ${JSON.stringify(
rows,
)}`,
);
return rows;
} catch (error) {
console.error(`Erro ao executar a view ${viewName}: `, error.message);
this.handleDatabaseError(
error,
`Erro ao executar a view ${viewName} com parâmetros.`,
);
} finally {
await queryRunner.release();
await dataSource.destroy();
}
}
async executeProcedure(procedureName: string, params: Record<string, any>) {
const dataSource = new DataSource(typeOrmConfig);
await dataSource.initialize();
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
const placeholders = Object.keys(params)
.map(() => '?')
.join(', ');
const values = Object.values(params);
const query = `EXECUTE IMMEDIATE ${procedureName}(${placeholders})`;
// Log da query e dos valores
console.log('Query executada:', query);
console.log('Valores:', values);
const [result] = await queryRunner.query(query, values);
// Verifica e converte campos que contenham JSON strings para objetos
const parsedResult = Array.isArray(result)
? result.map((row) => {
const parsedRow = { ...row };
for (const [key, value] of Object.entries(parsedRow)) {
try {
// Tenta converter strings JSON para objetos
if (
typeof value === 'string' &&
value.trim().startsWith('{') &&
value.trim().endsWith('}')
) {
parsedRow[key] = JSON.parse(value);
}
} catch (error) {
// Ignora se a conversão falhar
console.warn(
`Campo ${key} não é um JSON válido.Mantendo como string.`,
);
}
}
return parsedRow;
})
: result;
// Retorna os valores e o resultado
return {
message: 'Procedure executada com sucesso.',
executedQuery: query,
values: values,
result: parsedResult,
};
} catch (error) {
this.handleDatabaseError(
error,
`Erro ao executar a procedure ${procedureName} com parâmetros.`,
);
}
}
private handleDatabaseError(error: any, message: string): never {
console.error(message, error); // Log detalhado do erro
throw new InternalServerErrorException({
message,
sqlMessage: error.sqlMessage || error.message,
sqlState: error.sqlState,
});
}
async sendImages(file: string) {
// for (const file of files) {
// const file = 'C:\\Temp\\brasil_2.jpg'
if (file.endsWith('.jpg')) {
const fileName = file; //directoryImages + '\\' + file;
fs.readFile(fileName, (err, data) => {
if (err) throw err;
if (err) {
console.log(`WRITE ERROR: ${err}`);
} else {
this.uploadS3(
data,
'jur-saidaretornoveiculo',
file.replace('./uploads/', ''),
);
}
});
}
//}
}
async uploadS3(file, bucket, name) {
const s3 = this.getS3();
const params = {
Bucket: bucket,
Key: String(name),
Body: file,
};
return new Promise((resolve, reject) => {
s3.upload(params, (err, data) => {
if (err) {
console.log(JSON.stringify(err));
reject(err.message);
}
resolve(data);
});
});
}
getS3() {
return new S3({
accessKeyId: 'AKIAVHJOO6W765ZT2PNI', //process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: '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', // process.env.AWS_SECRET_ACCESS_KEY,
});
}
}