Skip to content

Commit

Permalink
fix(odbc): Fix ODBC connection lost
Browse files Browse the repository at this point in the history
  • Loading branch information
burgerni10 committed Jun 21, 2023
1 parent d5ba373 commit 6c405a3
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 37 deletions.
5 changes: 3 additions & 2 deletions backend/src/south/south-mssql/south-mssql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ export default class SouthMSSQL extends SouthConnector implements QueriesHistory
if (!datetimeField) {
formattedEntry[key] = value;
} else {
const entryDate = convertDateTimeToInstant(entry[datetimeField.field], datetimeField.datetimeFormat);
const entryDate = convertDateTimeToInstant(value, datetimeField.datetimeFormat);

if (datetimeField.useAsReference) {
if (entryDate > updatedStartTime) {
updatedStartTime = entryDate;
Expand Down Expand Up @@ -136,7 +137,7 @@ export default class SouthMSSQL extends SouthConnector implements QueriesHistory
config.domain = this.configuration.settings.domain;
}

const referenceTimestampField = item.settings.dateTimeFields.find(
const referenceTimestampField: DateTimeSerialization = item.settings.dateTimeFields.find(
(serialization: DateTimeSerialization) => serialization.useAsReference
);
const mssqlStartTime = this.formatDatetimeVariables(startTime, referenceTimestampField.datetimeFormat);
Expand Down
9 changes: 9 additions & 0 deletions backend/src/south/south-odbc/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ const manifest: SouthConnectorManifest = {
validators: [{ key: 'required' }, { key: 'min', params: { min: 100 } }, { key: 'max', params: { max: 30000 } }],
readDisplay: false
},
{
key: 'requestTimeout',
type: 'OibNumber',
label: 'Request timeout (ms)',
defaultValue: 1000,
class: 'col-4',
validators: [{ key: 'required' }, { key: 'min', params: { min: 100 } }, { key: 'max', params: { max: 30000 } }],
readDisplay: false
},
{
key: 'trustServerCertificate',
type: 'OibCheckbox',
Expand Down
21 changes: 2 additions & 19 deletions backend/src/south/south-odbc/south-odbc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import path from 'node:path';

import SouthODBC from './south-odbc';
import * as utils from '../../service/utils';
import { generateReplacementParameters } from '../../service/utils';
import DatabaseMock from '../../tests/__mocks__/database.mock';
import pino from 'pino';
// eslint-disable-next-line import/no-unresolved
Expand Down Expand Up @@ -161,8 +160,6 @@ describe('SouthODBC with authentication', () => {
jest.clearAllMocks();
jest.useFakeTimers().setSystemTime(new Date(nowDateString));

(utils.generateReplacementParameters as jest.Mock).mockReturnValue([new Date(nowDateString), new Date(nowDateString)]);

south = new SouthODBC(
configuration,
items,
Expand Down Expand Up @@ -219,7 +216,6 @@ describe('SouthODBC with authentication', () => {
const startTime = '2020-01-01T00:00:00.000Z';
const endTime = '2022-01-01T00:00:00.000Z';

(generateReplacementParameters as jest.Mock).mockReturnValue({ startTime, endTime });
const odbcConnection = {
close: jest.fn(),
query: jest.fn().mockReturnValue([{ timestamp: '2020-02-01T00:00:00.000Z' }, { timestamp: '2020-03-01T00:00:00.000Z' }])
Expand All @@ -245,15 +241,7 @@ describe('SouthODBC with authentication', () => {
connectionTimeout: configuration.settings.connectionTimeout
});
expect(logger.debug).toHaveBeenCalledWith(`Connecting with connection string ${expectedConnectionString}PWD=<secret>;`);
expect(generateReplacementParameters).toHaveBeenCalledWith(
items[0].settings.query,
DateTime.fromISO(startTime).toFormat('yyyy-MM-dd HH:mm:ss.SSS'),
DateTime.fromISO(endTime).toFormat('yyyy-MM-dd HH:mm:ss.SSS')
);
expect(odbcConnection.query).toHaveBeenCalledWith(items[0].settings.query.replace(/@StartTime/g, '?').replace(/@EndTime/g, '?'), {
startTime,
endTime
});
expect(odbcConnection.query).toHaveBeenCalledWith(items[0].settings.query);
expect(odbcConnection.close).toHaveBeenCalledTimes(1);

expect(result).toEqual([{ timestamp: '2020-02-01T00:00:00.000Z' }, { timestamp: '2020-03-01T00:00:00.000Z' }]);
Expand All @@ -263,7 +251,6 @@ describe('SouthODBC with authentication', () => {
const startTime = '2020-01-01T00:00:00.000Z';
const endTime = '2022-01-01T00:00:00.000Z';

(generateReplacementParameters as jest.Mock).mockReturnValue({ startTime, endTime });
const odbcConnection = {
close: jest.fn(),
query: jest
Expand All @@ -286,10 +273,7 @@ describe('SouthODBC with authentication', () => {
error = err;
}

expect(odbcConnection.query).toHaveBeenCalledWith(items[0].settings.query.replace(/@StartTime/g, '?').replace(/@EndTime/g, '?'), {
startTime,
endTime
});
expect(odbcConnection.query).toHaveBeenCalledWith(items[0].settings.query);
expect(error).toEqual(new Error('query error'));
expect(odbcConnection.close).toHaveBeenCalledTimes(1);

Expand Down Expand Up @@ -352,7 +336,6 @@ describe('SouthODBC without authentication', () => {
const startTime = '2020-01-01T00:00:00.000Z';
const endTime = '2022-01-01T00:00:00.000Z';

(generateReplacementParameters as jest.Mock).mockReturnValue({ startTime, endTime });
const odbcConnection = {
close: jest.fn(),
query: jest.fn().mockReturnValue([{ timestamp: '2020-02-01T00:00:00.000Z' }, { timestamp: '2020-03-01T00:00:00.000Z' }])
Expand Down
25 changes: 9 additions & 16 deletions backend/src/south/south-odbc/south-odbc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@ import path from 'node:path';

import SouthConnector from '../south-connector';
import manifest from './manifest';
import {
convertDateTimeFromInstant,
convertDateTimeToInstant,
createFolder,
generateReplacementParameters,
logQuery,
persistResults
} from '../../service/utils';
import { convertDateTimeFromInstant, convertDateTimeToInstant, createFolder, logQuery, persistResults } from '../../service/utils';
import { OibusItemDTO, SouthConnectorDTO } from '../../../../shared/model/south-connector.model';
import EncryptionService from '../../service/encryption.service';
import ProxyService from '../../service/proxy.service';
Expand Down Expand Up @@ -157,12 +150,6 @@ export default class SouthODBC extends SouthConnector implements QueriesHistory,
this.logger.debug(`Connecting with connection string ${connectionString}`);
}

const datetimeSerialization = item.settings.dateTimeFields.find((serialization: DateTimeSerialization) => serialization.useAsReference);
const odbcStartTime = convertDateTimeFromInstant(startTime, datetimeSerialization.datetimeFormat);
const odbcEndTime = convertDateTimeFromInstant(endTime, datetimeSerialization.datetimeFormat);

logQuery(item.settings.query, odbcStartTime, odbcEndTime, this.logger);

let connection;
try {
const connectionConfig = {
Expand All @@ -171,8 +158,14 @@ export default class SouthODBC extends SouthConnector implements QueriesHistory,
};
connection = await odbc.connect(connectionConfig);

const params = generateReplacementParameters(item.settings.query, odbcStartTime, odbcEndTime);
const data = await connection.query(item.settings.query.replace(/@StartTime/g, '?').replace(/@EndTime/g, '?'), params);
const datetimeSerialization = item.settings.dateTimeFields.find(
(serialization: DateTimeSerialization) => serialization.useAsReference
);
const odbcStartTime = convertDateTimeFromInstant(startTime, datetimeSerialization.datetimeFormat);
const odbcEndTime = convertDateTimeFromInstant(endTime, datetimeSerialization.datetimeFormat);
const adaptedQuery = item.settings.query.replace(/@StartTime/g, odbcStartTime).replace(/@EndTime/g, odbcEndTime);
logQuery(adaptedQuery, odbcStartTime, odbcEndTime, this.logger);
const data = await connection.query(adaptedQuery);
await connection.close();
return data;
} catch (error: any) {
Expand Down

0 comments on commit 6c405a3

Please sign in to comment.