Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add end-point to test connection #66

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions electron/main/features/database/database.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { IdNameViewModel } from '../../shared/view-model/id-name.view-model';

import { DatabaseService } from './database.service';
import { AddDto } from './dto/add.dto';
import { ConnectionStatusDto } from './dto/connection-status.dto';
import { GetAllSummaryDto } from './dto/get-all-summary.dto';
import { GetAllDto } from './dto/get-all.dto';
import { GetSummaryDto } from './dto/get-summary.dto';
import { DatabaseAllSummaryViewModel } from './view-model/database-all-summary.view-model';
import { DatabaseConnectionStatusViewModel } from './view-model/database-connection-status.view-model';
import { DatabaseSummaryViewModel } from './view-model/database-summary.view-model';
import { DatabaseViewModel } from './view-model/database.view-model';

Expand Down Expand Up @@ -40,4 +42,9 @@ export class DatabaseController {
async add(@Data() dto: AddDto): Promise<DatabaseViewModel> {
return this.databaseService.add(dto);
}

@Method('connection-status')
async connectionStatus(@Data() dto: ConnectionStatusDto): Promise<DatabaseConnectionStatusViewModel> {
return this.databaseService.getConnectionStatus(dto);
}
}
24 changes: 22 additions & 2 deletions electron/main/features/database/database.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { Prisma } from '@prisma/client';

import { Injectable } from '../../di/injectable';
import { fromEnumToIdName } from '../../shared/from-enum-to-id-name';
import { IdNameViewModel } from '../../shared/view-model/id-name.view-model';
import { QueryHistoryService } from '../query-history/query-history.service';
import { ScheduleService } from '../schedule/schedule.service';
import { SchedulersService } from '../scheduler/schedulers.service';

import { DatabaseTypeEnum } from './database-type.enum';
import { DatabaseRepository } from './database.repository';
import { AddDto } from './dto/add.dto';
import { ConnectionStatusDto } from './dto/connection-status.dto';
import { GetAllSummaryDto } from './dto/get-all-summary.dto';
import { GetAllDto } from './dto/get-all.dto';
import { GetSummaryDto } from './dto/get-summary.dto';
import { generateMetricsQueriesHistory } from './generate-metrics-queries-history';
import { DatabaseAllSummaryViewModel } from './view-model/database-all-summary.view-model';
import { DatabaseConnectionStatusEnum } from './view-model/database-connection-status.enum';
import { DatabaseConnectionStatusViewModel } from './view-model/database-connection-status.view-model';
import { DatabaseSummaryViewModel } from './view-model/database-summary.view-model';
import { DatabaseViewModel } from './view-model/database.view-model';

Expand All @@ -20,13 +26,18 @@ export class DatabaseService {
constructor(
private readonly databaseRepository: DatabaseRepository,
private readonly queryHistoryService: QueryHistoryService,
private readonly scheduleService: ScheduleService
private readonly scheduleService: ScheduleService,
private readonly schedulersServices: SchedulersService
) {}

async getAll(dto: GetAllDto): Promise<DatabaseViewModel[]> {
const where: Prisma.DatabaseWhereInput = {};
if (dto.active) {
where.inactiveAt = null;
}
const databases = await this.databaseRepository.findMany({
include: { _count: { select: { schedule: true } } },
where: { inactiveAt: dto.active ? null : { not: null } },
where,
orderBy: { createdAt: 'asc' },
});
return databases.map(database => ({
Expand Down Expand Up @@ -95,4 +106,13 @@ export class DatabaseService {
scheduleCount: 0,
};
}

async getConnectionStatus(dto: ConnectionStatusDto): Promise<DatabaseConnectionStatusViewModel> {
const database = await this.databaseRepository.findFirstOrThrow({ where: { id: dto.idDatabase } });
const { canConnect, message } = await this.schedulersServices.getConnectionStatus(database);
return {
status: canConnect ? DatabaseConnectionStatusEnum.OK : DatabaseConnectionStatusEnum.Error,
message,
};
}
}
7 changes: 7 additions & 0 deletions electron/main/features/database/dto/connection-status.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { IsDefined, IsUUID } from 'class-validator';

export class ConnectionStatusDto {
@IsUUID()
@IsDefined()
idDatabase!: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum DatabaseConnectionStatusEnum {
OK = 'OK',
Error = 'Error',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { DatabaseConnectionStatusEnum } from './database-connection-status.enum';

export class DatabaseConnectionStatusViewModel {
status!: DatabaseConnectionStatusEnum;
message?: string;
}
3 changes: 2 additions & 1 deletion electron/main/features/scheduler/database-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Class } from 'type-fest';
import { DatabaseTypeEnum } from '../database/database-type.enum';

import { QueryDriver } from './query-driver';
import { QueryDriverCanConnectResponse } from './query-driver-can-connect-response';
import { QueryDriverMSSQL } from './query-driver-mssql';
import { QueryDriverMySQL } from './query-driver-mysql';
import { QueryOptions } from './query-options';
Expand All @@ -23,7 +24,7 @@ export class DatabaseDriver {
return new queryDriver(this.database);
}

canConnect(): Promise<boolean> {
canConnect(): Promise<QueryDriverCanConnectResponse> {
return this._queryDriver.canConnect();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface QueryDriverCanConnectResponse {
canConnect: boolean;
message: string;
}
15 changes: 11 additions & 4 deletions electron/main/features/scheduler/query-driver-mssql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TIME_CONSTANTS } from '../../util/time-constants';
import { DatabaseTypeEnum } from '../database/database-type.enum';

import { QueryDriver } from './query-driver';
import { QueryDriverCanConnectResponse } from './query-driver-can-connect-response';
import { QueryError } from './query-error';
import { QueryErrorEnum } from './query-error.enum';
import { QueryOptions } from './query-options';
Expand Down Expand Up @@ -52,13 +53,19 @@ export class QueryDriverMSSQL extends QueryDriver {
}
}

async canConnect(): Promise<boolean> {
async canConnect(): Promise<QueryDriverCanConnectResponse> {
try {
const connection = await this._getConnection({ timeout: TIME_CONSTANTS['15_SECONDS_IN_MS'] });
await connection.query('select 1');
return true;
} catch {
return false;
return {
canConnect: true,
message: 'Connection OK',
};
} catch (error) {
return {
message: error.message ?? 'Unknown error',
canConnect: false,
};
}
}

Expand Down
15 changes: 11 additions & 4 deletions electron/main/features/scheduler/query-driver-mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MysqlErrorCodes } from 'mysql-error-codes';
import { DatabaseTypeEnum } from '../database/database-type.enum';

import { QueryDriver } from './query-driver';
import { QueryDriverCanConnectResponse } from './query-driver-can-connect-response';
import { QueryError } from './query-error';
import { QueryErrorEnum } from './query-error.enum';
import { QueryOptions } from './query-options';
Expand Down Expand Up @@ -67,7 +68,7 @@ export class QueryDriverMySQL extends QueryDriver {
});
}

async canConnect(): Promise<boolean> {
async canConnect(): Promise<QueryDriverCanConnectResponse> {
try {
const connection = await this._createConnection();
return await new Promise((resolve, reject) => {
Expand All @@ -77,11 +78,17 @@ export class QueryDriverMySQL extends QueryDriver {
reject(error);
return;
}
resolve(true);
resolve({
canConnect: true,
message: 'Connection OK',
});
});
});
} catch {
return false;
} catch (error) {
return {
canConnect: false,
message: error.message ?? 'Unknown error',
};
}
}

Expand Down
3 changes: 2 additions & 1 deletion electron/main/features/scheduler/query-driver.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { DatabaseTypeEnum } from '../database/database-type.enum';

import { QueryDriverCanConnectResponse } from './query-driver-can-connect-response';
import { QueryOptions } from './query-options';

export abstract class QueryDriver {
abstract readonly type: DatabaseTypeEnum;
abstract query<T = any>(query: string, options: QueryOptions): Promise<T[]>;
abstract canConnect(): Promise<boolean>;
abstract canConnect(): Promise<QueryDriverCanConnectResponse>;
}
2 changes: 1 addition & 1 deletion electron/main/features/scheduler/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export class Scheduler {
}

private async _assertConnection(): Promise<void> {
const canConnect = await this.databaseDriver.canConnect();
const { canConnect } = await this.databaseDriver.canConnect();
if (canConnect) {
return;
}
Expand Down
6 changes: 6 additions & 0 deletions electron/main/features/scheduler/schedulers.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Logger } from '../../logger/logger';
import { QueryHistoryModeEnum } from '../query-history/query-history-mode.enum';

import { DatabaseDriver } from './database-driver';
import { QueryDriverCanConnectResponse } from './query-driver-can-connect-response';
import { Scheduler } from './scheduler';

export type ScheduleWithDatabase = Schedule & { database: Database };
Expand Down Expand Up @@ -72,4 +73,9 @@ export class SchedulersService {
}
await scheduler.execute(QueryHistoryModeEnum.Manual);
}

async getConnectionStatus(database: Database): Promise<QueryDriverCanConnectResponse> {
const driver = await this._getOrCreateDatabaseDriver(database);
return driver.canConnect();
}
}