badmfck-api-server 2.1.3 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -83,7 +83,7 @@ async function Initializer(services) {
83
83
  exports.Initializer = Initializer;
84
84
  class APIService extends BaseService_1.BaseService {
85
85
  static nextLogID = 0;
86
- version = "2.1.3";
86
+ version = "2.1.4";
87
87
  options;
88
88
  monitor;
89
89
  monitorIndexFile;
@@ -1,6 +1,6 @@
1
- import { FieldInfo, MysqlError, Pool, PoolConnection } from "mysql";
2
1
  import { BaseService } from "./BaseService";
3
2
  import Signal, { Req } from "badmfck-signal";
3
+ import * as mysql from "mysql2/promise";
4
4
  export declare const S_MYSQL_STARTED: Signal<void>;
5
5
  export declare const REQ_MYSQL_QUERY: Req<MySqlQuery | MySqlQuery[], MysqlResult[]>;
6
6
  export declare const executeQuery: (query: MySqlQuery | MySqlQuery[]) => Promise<MysqlResult[]>;
@@ -11,16 +11,24 @@ export interface MysqlServiceOptions {
11
11
  password: string;
12
12
  port: number;
13
13
  database: string;
14
+ queueLimit?: number;
14
15
  migrations?: {
15
16
  dir: string;
16
17
  callback: () => void;
17
18
  } | null;
18
19
  }
20
+ export interface MysqlError {
21
+ code: string;
22
+ errno: number;
23
+ sql: string;
24
+ name: string;
25
+ message: string;
26
+ fatal?: boolean;
27
+ }
19
28
  export interface MysqlResult {
20
29
  error?: MysqlError | null;
21
30
  rollbackError?: MysqlError | null;
22
31
  isDuplicateError?: boolean;
23
- fields?: FieldInfo[] | null;
24
32
  data: any;
25
33
  }
26
34
  export interface MySqlQuery {
@@ -48,7 +56,7 @@ export interface MysqlQueryFieldObject extends Record<string, string | number |
48
56
  export declare class MysqlService extends BaseService {
49
57
  reconnectionTimeout: number;
50
58
  reconnecting: boolean;
51
- pool: Pool | null;
59
+ pool: mysql.Pool | null;
52
60
  options: MysqlServiceOptions;
53
61
  serviceStarted: boolean;
54
62
  timeoutID: any;
@@ -56,19 +64,17 @@ export declare class MysqlService extends BaseService {
56
64
  constructor(options: MysqlServiceOptions);
57
65
  static executeQuery(query: MySqlQuery | MySqlQuery[]): Promise<MysqlResult[]>;
58
66
  init(): Promise<void>;
59
- recreatePool(): Promise<void>;
67
+ recreatePool(): Promise<boolean>;
60
68
  onApplicationReady(): Promise<void>;
61
69
  static fieldsToObject(fields: MysqlQueryField[] | MysqlQueryFieldObject, ignoreSystemParameters?: boolean): MysqlQueryFieldObject;
62
70
  static objectToFields(obj: MysqlQueryFieldObject | MysqlQueryField[]): MysqlQueryField[];
63
71
  static prepareQuery(query: string, fields: MysqlQueryField[] | MysqlQueryFieldObject): string;
64
72
  static prepareQueryFieldValue(value: string | number | boolean | null | undefined, system?: boolean): string | number | boolean | null | undefined;
65
73
  execute(query: string, rollbackQuery: string | null): Promise<MysqlResult>;
66
- sendQuery(conn: PoolConnection, query: string, resolve: (data: MysqlResult) => void, rollback: string | null): Promise<void>;
67
- queryAsync(conn: PoolConnection, query: string): Promise<{
74
+ sendQuery(conn: mysql.PoolConnection, query: string, resolve: (data: MysqlResult) => void, rollback: string | null): Promise<void>;
75
+ queryAsync(conn: mysql.PoolConnection, query: string): Promise<{
68
76
  err: MysqlError | null;
69
77
  results?: any;
70
- fields?: FieldInfo[];
71
78
  }>;
72
- createPool(): Promise<boolean>;
73
79
  }
74
80
  export default MysqlService;
@@ -22,16 +22,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  exports.MysqlService = exports.executeQuery = exports.REQ_MYSQL_QUERY = exports.S_MYSQL_STARTED = void 0;
30
- const mysql_1 = __importDefault(require("mysql"));
31
27
  const BaseService_1 = require("./BaseService");
32
28
  const badmfck_signal_1 = __importStar(require("badmfck-signal"));
33
29
  const crypto_1 = require("crypto");
34
30
  const LogService_1 = require("./LogService");
31
+ const mysql = __importStar(require("mysql2/promise"));
35
32
  exports.S_MYSQL_STARTED = new badmfck_signal_1.default();
36
33
  exports.REQ_MYSQL_QUERY = new badmfck_signal_1.Req(undefined, "REQ_MYSQL_QUERY");
37
34
  const executeQuery = async (query) => { return await exports.REQ_MYSQL_QUERY.request(query); };
@@ -58,8 +55,33 @@ class MysqlService extends BaseService_1.BaseService {
58
55
  }
59
56
  static async executeQuery(query) { return await exports.REQ_MYSQL_QUERY.request(query); }
60
57
  async init() {
58
+ super.init();
59
+ process.on('SIGINT', async () => {
60
+ console.log('1. Received SIGINT. Performing cleanup...');
61
+ if (this.pool) {
62
+ try {
63
+ await this.pool.end();
64
+ }
65
+ catch (e) {
66
+ (0, LogService_1.logCrit)("${MysqlService.js}", "Can't close MYSQL pool!");
67
+ }
68
+ }
69
+ process.exit(0);
70
+ });
71
+ process.on('SIGTERM', () => {
72
+ console.log('2. Received SIGTERM. Performing cleanup...');
73
+ process.exit(0);
74
+ });
61
75
  this.serviceStarted = false;
62
- await this.recreatePool();
76
+ let poolCreated = false;
77
+ while (!poolCreated) {
78
+ (0, LogService_1.logInfo)("${MysqlService.js}", "Connecting to MYSQL!");
79
+ poolCreated = await this.recreatePool();
80
+ if (!poolCreated) {
81
+ (0, LogService_1.logCrit)("${MysqlService.js}", "Can't connect to MYSQL! Retrying in 3 seconds...");
82
+ await new Promise((resolve) => setTimeout(resolve, 3000));
83
+ }
84
+ }
63
85
  exports.REQ_MYSQL_QUERY.listener = async (data) => {
64
86
  if (!Array.isArray(data))
65
87
  data = [data];
@@ -72,20 +94,59 @@ class MysqlService extends BaseService_1.BaseService {
72
94
  };
73
95
  }
74
96
  async recreatePool() {
75
- (0, LogService_1.logInfo)("${MysqlService.js}", "Mysql server trying to create pool");
76
- this.serviceStarted = false;
77
- const ok = await this.createPool();
78
- if (!ok) {
79
- (0, LogService_1.logWarn)("${MysqlService.js}", "Mysql server not connected, retrying in 3 sec");
80
- if (this.timeoutID)
81
- clearTimeout(this.timeoutID);
82
- this.timeoutID = setTimeout(() => { this.recreatePool(); }, 3000);
97
+ (0, LogService_1.logInfo)("${MysqlService.js}", "Connecting to mysql: \n HOST: " + this.options.host + '\n PORT:' + this.options.port);
98
+ if (this.pool) {
99
+ this.pool.removeAllListeners();
100
+ try {
101
+ await this.pool.end();
102
+ }
103
+ catch (e) {
104
+ (0, LogService_1.logCrit)("${MysqlService.js}", "Can't close MYSQL pool!");
105
+ }
106
+ this.pool = null;
83
107
  }
84
- else {
85
- this.serviceStarted = true;
86
- (0, LogService_1.logInfo)("${MysqlService.js}", "Mysql Service started!");
87
- exports.S_MYSQL_STARTED.invoke();
108
+ try {
109
+ this.pool = mysql.createPool({
110
+ host: this.options.host,
111
+ user: this.options.user,
112
+ password: this.options.password,
113
+ database: this.options.database,
114
+ port: this.options.port,
115
+ connectionLimit: this.options.connectionLimit,
116
+ queueLimit: 10
117
+ });
118
+ }
119
+ catch (e) {
120
+ (0, LogService_1.logCrit)("${MysqlService.js}", "Can't connect to MYSQL!");
121
+ return false;
88
122
  }
123
+ this.pool?.on('connection', (connection) => {
124
+ (0, LogService_1.logInfo)("${MysqlService.js}", "MYSQL CONNECTION CREATED");
125
+ });
126
+ this.pool?.on('acquire', (connection) => {
127
+ (0, LogService_1.logInfo)("${MysqlService.js}", "MYSQL CONNECTION ACQUIRED");
128
+ });
129
+ this.pool?.on('release', (connection) => {
130
+ (0, LogService_1.logInfo)("${MysqlService.js}", "MYSQL CONNECTION RELEASED");
131
+ });
132
+ this.pool?.on('enqueue', () => {
133
+ (0, LogService_1.logInfo)("${MysqlService.js}", "MYSQL CONNECTION ENQUEUED");
134
+ });
135
+ return new Promise(async (resolve, reject) => {
136
+ try {
137
+ const conn = await this.pool?.getConnection();
138
+ if (conn) {
139
+ conn?.release();
140
+ resolve(true);
141
+ }
142
+ else
143
+ resolve(false);
144
+ }
145
+ catch (e) {
146
+ (0, LogService_1.logCrit)("${MysqlService.js}", "Can't connect to MYSQL!");
147
+ resolve(false);
148
+ }
149
+ });
89
150
  }
90
151
  async onApplicationReady() { }
91
152
  static fieldsToObject(fields, ignoreSystemParameters) {
@@ -207,7 +268,7 @@ class MysqlService extends BaseService_1.BaseService {
207
268
  return value;
208
269
  }
209
270
  async execute(query, rollbackQuery) {
210
- return new Promise((resolve, reject) => {
271
+ return new Promise(async (resolve, reject) => {
211
272
  if (!this.pool) {
212
273
  (0, LogService_1.logError)("${MysqlService.js}", "No pool");
213
274
  resolve({
@@ -220,23 +281,11 @@ class MysqlService extends BaseService_1.BaseService {
220
281
  message: "Mysql pool not created"
221
282
  },
222
283
  data: null,
223
- fields: null
224
284
  });
225
285
  return;
226
286
  }
227
- this.pool.getConnection((err, conn) => {
228
- if (err) {
229
- (0, LogService_1.logError)("${MysqlService.js}", err);
230
- if (`${err}`.indexOf('ECONNREFUSED') !== -1) {
231
- this.recreatePool();
232
- }
233
- resolve({
234
- error: err,
235
- data: null,
236
- fields: null
237
- });
238
- return;
239
- }
287
+ try {
288
+ const conn = await this.pool.getConnection();
240
289
  if (!conn) {
241
290
  (0, LogService_1.logCrit)("${MysqlService.js}", `No connection created!`);
242
291
  resolve({
@@ -249,11 +298,28 @@ class MysqlService extends BaseService_1.BaseService {
249
298
  message: "Mysql pool cant get connection"
250
299
  },
251
300
  data: null,
252
- fields: null
253
301
  });
302
+ return;
254
303
  }
255
304
  this.sendQuery(conn, query, resolve, rollbackQuery);
256
- });
305
+ }
306
+ catch (e) {
307
+ (0, LogService_1.logError)("${MysqlService.js}", e);
308
+ if (`${e}`.indexOf('ECONNREFUSED') !== -1)
309
+ this.recreatePool();
310
+ resolve({
311
+ error: {
312
+ code: "NO_CONN",
313
+ errno: 100001,
314
+ fatal: true,
315
+ sql: query,
316
+ name: "NO_CONN",
317
+ message: (e && typeof e === "object" && "message" in e) ? e.message : "Mysql cant get connection"
318
+ },
319
+ data: null
320
+ });
321
+ return;
322
+ }
257
323
  });
258
324
  }
259
325
  async sendQuery(conn, query, resolve, rollback) {
@@ -279,7 +345,6 @@ class MysqlService extends BaseService_1.BaseService {
279
345
  message: "Error: " + err
280
346
  },
281
347
  data: null,
282
- fields: null,
283
348
  rollbackError: rollbackError
284
349
  });
285
350
  });
@@ -299,7 +364,6 @@ class MysqlService extends BaseService_1.BaseService {
299
364
  resolve({
300
365
  error: queryResult.err,
301
366
  data: null,
302
- fields: null,
303
367
  rollbackError: rollbackError,
304
368
  isDuplicateError: dup
305
369
  });
@@ -312,87 +376,40 @@ class MysqlService extends BaseService_1.BaseService {
312
376
  resolve({
313
377
  error: queryResult.err,
314
378
  data: queryResult.results,
315
- fields: queryResult.fields
316
379
  });
317
380
  }
318
381
  async queryAsync(conn, query) {
319
- return new Promise((resolve, reject) => {
320
- try {
321
- conn.query(query, (err, results, fields) => {
322
- resolve({
323
- err: err,
324
- results: results,
325
- fields: fields
326
- });
327
- });
328
- }
329
- catch (e) {
330
- resolve({
331
- err: {
332
- code: "QUERY_ERR",
333
- errno: 100002,
334
- fatal: true,
335
- sql: query,
336
- name: "QUERY_ERR",
337
- message: "Error: " + e
338
- }
339
- });
340
- }
341
- });
342
- }
343
- async createPool() {
344
- (0, LogService_1.logInfo)("${MysqlService.js}", "Connecting to mysql: \n HOST: " + this.options.host + '\n PORT:' + this.options.port);
345
- let err = false;
346
- if (this.pool) {
347
- try {
348
- this.pool.removeAllListeners();
349
- this.pool.end(err => {
350
- if (err)
351
- (0, LogService_1.logError)("${MysqlService.js}", err);
352
- });
353
- }
354
- catch (e) {
355
- (0, LogService_1.logCrit)("${MysqlService.js}", e);
356
- }
357
- }
358
382
  try {
359
- this.pool = mysql_1.default.createPool({
360
- connectionLimit: this.options.connectionLimit,
361
- host: this.options.host,
362
- user: this.options.user,
363
- password: this.options.password,
364
- port: this.options.port,
365
- database: this.options.database,
366
- multipleStatements: true
367
- });
383
+ const result = await conn.query(query);
384
+ return {
385
+ err: null,
386
+ results: result[0],
387
+ };
368
388
  }
369
389
  catch (e) {
370
- (0, LogService_1.logCrit)("${MysqlService.js}", "Can't connect to MYSQL!");
371
- err = true;
372
- }
373
- if (!err && this.pool) {
374
- this.pool.on("error", (evt) => {
375
- (0, LogService_1.logError)("${MysqlService.js}", evt);
376
- });
377
- }
378
- return new Promise((res, rej) => {
379
- if (err) {
380
- res(false);
381
- return;
382
- }
383
- if (!this.pool) {
384
- res(false);
385
- return;
390
+ const err = e;
391
+ if (err && typeof err === "object" && "code" in err && "errno" in err && "sql" in err && "name" in err && "message" in err) {
392
+ return {
393
+ err: {
394
+ code: err.code,
395
+ errno: err.errno,
396
+ sql: query,
397
+ name: err.name,
398
+ message: err.message
399
+ }
400
+ };
386
401
  }
387
- this.pool.getConnection((e, cnn) => {
388
- if (e) {
389
- (0, LogService_1.logError)("${MysqlService.js}", e.message);
390
- res(false);
391
- return;
402
+ return {
403
+ err: {
404
+ code: "QUERY_ERR",
405
+ errno: 100002,
406
+ fatal: true,
407
+ sql: query,
408
+ name: "QUERY_ERR",
409
+ message: "Error: " + e
392
410
  }
393
- res(true);
394
- });
395
- });
411
+ };
412
+ }
396
413
  }
397
414
  }
398
415
  exports.MysqlService = MysqlService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "cors": "^2.8.5",
26
26
  "express": "^4.19.2",
27
27
  "express-fileupload": "^1.5.0",
28
- "mysql": "^2.18.1",
28
+ "mysql2": "^3.11.3",
29
29
  "ws": "^8.18.0"
30
30
  },
31
31
  "devDependencies": {