Skip to content

Commit

Permalink
Merge pull request #36 from boostcampwm-2024/feature-be-#32
Browse files Browse the repository at this point in the history
[#32] Api-server Admin connection 제거 & db-manager DB 생성 삭제 로직  구현
  • Loading branch information
mintaek22 authored Jan 16, 2025
2 parents be1d8e9 + 4e38183 commit f6ba1ec
Show file tree
Hide file tree
Showing 36 changed files with 533 additions and 404 deletions.
71 changes: 0 additions & 71 deletions BE/src/config/query-database/admin-db-manager.service.ts

This file was deleted.

9 changes: 0 additions & 9 deletions BE/src/config/query-database/query-db.moudle.ts

This file was deleted.

7 changes: 2 additions & 5 deletions BE/src/config/query-database/user-db-manager.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { Injectable } from '@nestjs/common';
import { QueryResult } from 'mysql2/promise';
import { ConfigService } from '@nestjs/config';
import { Connection, QueryResult } from 'mysql2/promise';

@Injectable()
export class UserDBManager {
constructor(private readonly configService: ConfigService) {}
async run(req: any, query: string): Promise<QueryResult> {
const connection = await req.dbConnection;
async run(connection: Connection, query: string): Promise<QueryResult> {
const [result] = await connection.query(query);
return result;
}
Expand Down
8 changes: 8 additions & 0 deletions BE/src/config/query-database/user-db.moudle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Module } from '@nestjs/common';
import { UserDBManager } from './user-db-manager.service';

@Module({
providers: [UserDBManager],
exports: [UserDBManager],
})
export class UserDBModule {}
4 changes: 2 additions & 2 deletions BE/src/config/redis/redis.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { RedisService } from './redis.service';
import { QueryDBModule } from '../query-database/query-db.moudle';
import { UserDBModule } from '../query-database/user-db.moudle';

@Module({
imports: [QueryDBModule],
imports: [UserDBModule],
providers: [RedisService],
exports: [RedisService],
})
Expand Down
28 changes: 1 addition & 27 deletions BE/src/config/redis/redis.service.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import Redis from 'ioredis';
import { Injectable } from '@nestjs/common';
import { AdminDBManager } from '../query-database/admin-db-manager.service';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class RedisService {
private sessionConnection: Redis;
private eventConnection: Redis;
private activeUserConnection: Redis;

private readonly SESSION_TTL = 60 * 30;
private readonly ACTIVE_USER_TTL = 60 * 5;

constructor(
private readonly adminDBManager: AdminDBManager,
private readonly configService: ConfigService,
) {
constructor(private readonly configService: ConfigService) {
this.setSessionConnection();
this.setEventConnection();
this.setActiveUserConnection();
}

Expand All @@ -41,17 +35,6 @@ export class RedisService {
});
}

private setEventConnection() {
this.eventConnection = new Redis({
host: this.configService.get<string>('REDIS_HOST'),
port: this.configService.get<number>('REDIS_PORT'),
});

this.eventConnection.on('ready', () => {
this.subscribeToExpiredEvents();
});
}

public async getSession(key: string) {
if (!key) {
return null;
Expand All @@ -67,7 +50,6 @@ export class RedisService {
const session = await this.existSession(key);
if (!session) {
await this.sessionConnection.hset(key, 'rowCount', 0);
await this.adminDBManager.initUserDatabase(key);
}
await this.sessionConnection.expire(key, this.SESSION_TTL);
}
Expand All @@ -76,14 +58,6 @@ export class RedisService {
await this.sessionConnection.del(key);
}

private subscribeToExpiredEvents() {
this.eventConnection.subscribe('__keyevent@0__:expired');

this.eventConnection.on('message', (event, session) => {
this.adminDBManager.removeDatabaseInfo(session);
});
}

public async getRowCount(key: string) {
return this.sessionConnection.hget(key, 'rowCount');
}
Expand Down
10 changes: 7 additions & 3 deletions BE/src/query/query.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { ResponseDto } from '../common/response/response.dto';
import { ApiExtraModels, ApiTags } from '@nestjs/swagger';
import { ResQueryDto } from './dto/res-query.dto';
import { ExecuteQuerySwagger } from '../config/swagger/query-swagger.decorator';
import { Request } from 'express';
import { Serialize } from '../interceptors/serialize.interceptor';
import { ShellGuard } from '../guard/shell.guard';
import { UserDBConnectionInterceptor } from '../interceptors/user-db-connection.interceptor';
Expand All @@ -30,10 +29,15 @@ export class QueryController {
@Post('/:shellId/execute')
@UseGuards(ShellGuard)
async executeQuery(
@Req() req: Request,
@Req() req: any,
@Param('shellId') shellId: number,
@Body() queryDto: QueryDto,
) {
return await this.queryService.execute(req, shellId, queryDto);
return await this.queryService.execute(
req.dbConnection,
req.sessionID,
shellId,
queryDto,
);
}
}
14 changes: 10 additions & 4 deletions BE/src/query/query.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ import { QueryService } from './query.service';
import { QueryController } from './query.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Shell } from '../shell/shell.entity';
import { ShellService } from '../shell/shell.service';
import { UserDBManager } from '../config/query-database/user-db-manager.service';
import { UsageModule } from '../usage/usage.module';
import { RedisModule } from '../config/redis/redis.module';
import { UserDBModule } from '../config/query-database/user-db.moudle';
import { ShellModule } from '../shell/shell.module';

@Module({
imports: [TypeOrmModule.forFeature([Shell]), UsageModule, RedisModule],
imports: [
TypeOrmModule.forFeature([Shell]),
UsageModule,
RedisModule,
UserDBModule,
ShellModule,
],
controllers: [QueryController],
providers: [QueryService, ShellService, UserDBManager],
providers: [QueryService],
})
export class QueryModule {}
36 changes: 22 additions & 14 deletions BE/src/query/query.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { QueryDto } from './dto/query.dto';
import { QueryType } from '../common/enums/query-type.enum';
import { ShellService } from '../shell/shell.service';
import { ResultSetHeader, RowDataPacket } from 'mysql2/promise';
import { Connection, ResultSetHeader, RowDataPacket } from 'mysql2/promise';
import { Shell } from '../shell/shell.entity';
import { UserDBManager } from '../config/query-database/user-db-manager.service';
import { UsageService } from 'src/usage/usage.service';
Expand All @@ -17,12 +17,17 @@ export class QueryService {
private readonly redisService: RedisService,
) {}

async execute(req: any, shellId: number, queryDto: QueryDto) {
this.redisService.setActiveUser(req.sessionID);
async execute(
connection: Connection,
sessionId: string,
shellId: number,
queryDto: QueryDto,
) {
this.redisService.setActiveUser(sessionId);
await this.shellService.findShellOrThrow(shellId);

const baseUpdateData = {
sessionId: req.sessionID,
sessionId: sessionId,
query: queryDto.query,
queryType: this.detectQueryType(queryDto.query),
};
Expand All @@ -35,7 +40,11 @@ export class QueryService {
text: '지원하지 않는 쿼리입니다.',
});
}
updateData = await this.processQuery(req, baseUpdateData, queryDto.query);
updateData = await this.processQuery(
connection,
baseUpdateData,
queryDto.query,
);
} catch (e) {
const text = `ERROR ${e.errno || ''} (${e.sqlState || ''}): ${e.sqlMessage || ''}`;

Expand All @@ -47,21 +56,19 @@ export class QueryService {
};
return await this.shellService.replace(shellId, updateData);
}
await this.usageService.updateRowCount(req);
await this.usageService.updateRowCount(connection, sessionId);
return await this.shellService.replace(shellId, updateData);
}

private async processQuery(
req: any,
connection: Connection,
baseUpdateData: any,
query: string,
): Promise<Partial<Shell>> {
const isResultTable = this.existResultTable(baseUpdateData.queryType);

const rows = await this.userDBManager.run(req, query);
const runTime = await this.measureQueryRunTime(req);

// Update usage
const rows = await this.userDBManager.run(connection, query);
const runTime = await this.measureQueryRunTime(connection);

let text: string;
let resultTable: RowDataPacket[];
Expand Down Expand Up @@ -100,11 +107,12 @@ export class QueryService {
return validTypes.includes(type);
}

async measureQueryRunTime(req: any): Promise<string> {
async measureQueryRunTime(connection: Connection): Promise<string> {
try {
const query = `SHOW PROFILES`;
const rows = (await this.userDBManager.run(
req,
'show profiles;',
connection,
query,
)) as RowDataPacket[];
let lastQueryRunTime = rows[rows.length - 1]?.Duration;
lastQueryRunTime = Math.round(lastQueryRunTime * 1000) / 1000 || 0;
Expand Down
6 changes: 3 additions & 3 deletions BE/src/record/file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { UserDBManager } from '../config/query-database/user-db-manager.service';
import { RandomColumnModel } from './random-column.entity';
import * as path from 'node:path';
import { ResultSetHeader } from 'mysql2/promise';
import { Connection, ResultSetHeader } from 'mysql2/promise';
import * as crypto from 'node:crypto';
@Injectable()
export class FileService implements OnModuleInit {
Expand Down Expand Up @@ -55,7 +55,7 @@ export class FileService implements OnModuleInit {
}

async loadCsvToDB(
req: any,
connection: Connection,
csvFilePath: string,
tableName: string,
columnNames: string[],
Expand All @@ -71,7 +71,7 @@ export class FileService implements OnModuleInit {

try {
queryResult = (await this.userDBManager.run(
req,
connection,
query,
)) as ResultSetHeader;
return queryResult.affectedRows;
Expand Down
11 changes: 7 additions & 4 deletions BE/src/record/record.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { ResRecordDto } from './dto/res-record.dto';
import { ExecuteRecordSwagger } from '../config/swagger/record-swagger.decorator';
import { Serialize } from '../interceptors/serialize.interceptor';
import { UserDBConnectionInterceptor } from '../interceptors/user-db-connection.interceptor';
import { Request } from 'express';

@UseInterceptors(UserDBConnectionInterceptor)
@ApiExtraModels(ResponseDto, ResRecordDto)
@ApiTags('랜덤 데이터 생성 API')
@Controller('api/record')
Expand All @@ -20,10 +20,13 @@ export class RecordController {
@Serialize(ResRecordDto)
@Post()
async insertRandomRecord(
@Req() req: Request,
@Req() req: any,
@Body() randomRecordInsertDto: CreateRandomRecordDto,
) {
await this.recordService.validateDto(randomRecordInsertDto, req.sessionID);
return this.recordService.insertRandomRecord(req, randomRecordInsertDto);
return this.recordService.insertRandomRecord(
req.dbConnection,
req.sessionID,
randomRecordInsertDto,
);
}
}
4 changes: 2 additions & 2 deletions BE/src/record/record.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { Module } from '@nestjs/common';
import { RecordController } from './record.controller';
import { RecordService } from './record.service';
import { RedisModule } from '../config/redis/redis.module';
import { QueryDBModule } from '../config/query-database/query-db.moudle';
import { UserDBModule } from '../config/query-database/user-db.moudle';
import { UsageModule } from '../usage/usage.module';
import { TableModule } from 'src/table/table.module';
import { FileService } from './file.service';

@Module({
imports: [RedisModule, QueryDBModule, UsageModule, TableModule],
imports: [RedisModule, UserDBModule, UsageModule, TableModule],
controllers: [RecordController],
providers: [RecordService, FileService],
})
Expand Down
Loading

0 comments on commit f6ba1ec

Please sign in to comment.