@oino-ts/db-mariadb 0.5.2 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -85,7 +85,8 @@ class OINOMariadbData extends db_1.OINODbDataSet {
85
85
  */
86
86
  class OINODbMariadb extends db_1.OINODb {
87
87
  static _fieldLengthRegex = /([^\(\)]+)(\s?\((\d+)\s?\,?\s?(\d*)?\))?/i;
88
- static _exceptionMessageRegex = /\(([^\)]*)\) (.*)\nsql\:(.*)?/i;
88
+ static _connectionExceptionMessageRegex = /\(([^\)]*)\) (.*)/i;
89
+ static _sqlExceptionMessageRegex = /\(([^\)]*)\) (.*)\nsql\:(.*)?/i;
89
90
  _pool;
90
91
  /**
91
92
  * Constructor of `OINODbMariadb`
@@ -97,7 +98,8 @@ class OINODbMariadb extends db_1.OINODb {
97
98
  if (this._params.type !== "OINODbMariadb") {
98
99
  throw new Error(db_1.OINO_ERROR_PREFIX + ": Not OINODbMariadb-type: " + this._params.type);
99
100
  }
100
- this._pool = mariadb_1.default.createPool({ host: params.url, database: params.database, port: params.port, user: params.user, password: params.password, acquireTimeout: 2000, debug: false, rowsAsArray: true });
101
+ this._pool = mariadb_1.default.createPool({ host: this._params.url, database: this._params.database, port: this._params.port, user: this._params.user, password: this._params.password, acquireTimeout: 2000, debug: false, rowsAsArray: true });
102
+ delete this._params.password; // do not store password in db object
101
103
  // this._pool.on("acquire", (conn: mariadb.Connection) => {
102
104
  // OINOLog.info("OINODbMariadb acquire", {conn:conn})
103
105
  // })
@@ -148,7 +150,7 @@ class OINODbMariadb extends db_1.OINODb {
148
150
  return Promise.resolve(result);
149
151
  }
150
152
  catch (err) {
151
- const msg_parts = err.message.match(OINODbMariadb._exceptionMessageRegex) || [];
153
+ const msg_parts = err.message.match(OINODbMariadb._sqlExceptionMessageRegex) || [];
152
154
  // OINOLog.debug("OINODbMariadb._exec exception", {connection: msg_parts[1], message:msg_parts[2], sql:msg_parts[3]}) // print connection info just to log so tests don't break on runtime output
153
155
  throw new Error(msg_parts[2]);
154
156
  }
@@ -270,17 +272,57 @@ class OINODbMariadb extends db_1.OINODb {
270
272
  *
271
273
  */
272
274
  async connect() {
275
+ const result = new db_1.OINOResult();
276
+ let connection = null;
273
277
  try {
274
278
  // make sure that any items are correctly URL encoded in the connection string
275
279
  // OINOLog.debug("OINODbMariadb.connect")
276
- await this._pool.on;
277
- // await this._client.connect()
278
- return Promise.resolve(true);
280
+ connection = await this._pool.getConnection();
281
+ this.isConnected = true;
282
+ }
283
+ catch (err) {
284
+ const msg_parts = err.message.match(OINODbMariadb._connectionExceptionMessageRegex) || [];
285
+ result.setError(500, "Error connecting to server: " + msg_parts[2], "OINODbMariadb.connect");
286
+ db_1.OINOLog.error(result.statusMessage, { error: err });
287
+ }
288
+ finally {
289
+ if (connection) {
290
+ await connection.end();
291
+ }
292
+ }
293
+ return Promise.resolve(result);
294
+ }
295
+ /**
296
+ * Validate connection to database is working.
297
+ *
298
+ */
299
+ async validate() {
300
+ db_1.OINOBenchmark.start("OINODb", "validate");
301
+ let result = new db_1.OINOResult();
302
+ try {
303
+ const sql = this._getValidateSql(this._params.database);
304
+ // OINOLog.debug("OINODbMariadb.validate", {sql:sql})
305
+ const sql_res = await this.sqlSelect(sql);
306
+ // OINOLog.debug("OINODbMariadb.validate", {sql_res:sql_res})
307
+ if (sql_res.isEmpty()) {
308
+ result.setError(400, "DB returned no rows for select!", "OINODbMariadb.validate");
309
+ }
310
+ else if (sql_res.getRow().length == 0) {
311
+ result.setError(400, "DB returned no values for database!", "OINODbMariadb.validate");
312
+ }
313
+ else if (sql_res.getRow()[0] == "0") {
314
+ result.setError(400, "DB returned no schema for database!", "OINODbMariadb.validate");
315
+ }
316
+ else {
317
+ this.isValidated = true;
318
+ }
279
319
  }
280
320
  catch (err) {
281
- // ... error checks
282
- throw new Error(db_1.OINO_ERROR_PREFIX + ": Error connecting to OINODbMariadb server: " + err);
321
+ result.setError(500, "Exception validating connection: " + err.message, "OINODbMariadb.validate");
322
+ db_1.OINOLog.error(result.statusMessage, { error: err });
283
323
  }
324
+ db_1.OINOBenchmark.end("OINODb", "validate");
325
+ return result;
284
326
  }
285
327
  /**
286
328
  * Execute a select operation.
@@ -337,6 +379,14 @@ WHERE C.TABLE_SCHEMA = '${dbName}' AND C.TABLE_NAME = '${tableName}'
337
379
  ORDER BY C.ORDINAL_POSITION;`;
338
380
  return sql;
339
381
  }
382
+ _getValidateSql(dbName) {
383
+ const sql = `SELECT
384
+ Count(c.COLUMN_NAME) AS COLUMN_COUNT
385
+ FROM information_schema.COLUMNS C
386
+ LEFT JOIN information_schema.KEY_COLUMN_USAGE KCU ON KCU.TABLE_SCHEMA = C.TABLE_SCHEMA AND KCU.TABLE_NAME = C.TABLE_NAME AND C.COLUMN_NAME = KCU.COLUMN_NAME and KCU.REFERENCED_TABLE_NAME IS NOT NULL
387
+ WHERE C.TABLE_SCHEMA = '${dbName}';`;
388
+ return sql;
389
+ }
340
390
  /**
341
391
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
342
392
  * the model.
@@ -3,7 +3,7 @@
3
3
  * License, v. 2.0. If a copy of the MPL was not distributed with this
4
4
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
- import { OINODb, OINODbDataSet, OINOBooleanDataField, OINONumberDataField, OINOStringDataField, OINO_ERROR_PREFIX, OINOBenchmark, OINODatetimeDataField, OINOBlobDataField, OINO_INFO_PREFIX, OINODB_EMPTY_ROW, OINODB_EMPTY_ROWS, OINOLog } from "@oino-ts/db";
6
+ import { OINODb, OINODbDataSet, OINOBooleanDataField, OINONumberDataField, OINOStringDataField, OINO_ERROR_PREFIX, OINOBenchmark, OINODatetimeDataField, OINOBlobDataField, OINO_INFO_PREFIX, OINODB_EMPTY_ROW, OINODB_EMPTY_ROWS, OINOLog, OINOResult } from "@oino-ts/db";
7
7
  import mariadb from "mariadb";
8
8
  /**
9
9
  * Implmentation of OINODbDataSet for MariaDb.
@@ -82,7 +82,8 @@ class OINOMariadbData extends OINODbDataSet {
82
82
  */
83
83
  export class OINODbMariadb extends OINODb {
84
84
  static _fieldLengthRegex = /([^\(\)]+)(\s?\((\d+)\s?\,?\s?(\d*)?\))?/i;
85
- static _exceptionMessageRegex = /\(([^\)]*)\) (.*)\nsql\:(.*)?/i;
85
+ static _connectionExceptionMessageRegex = /\(([^\)]*)\) (.*)/i;
86
+ static _sqlExceptionMessageRegex = /\(([^\)]*)\) (.*)\nsql\:(.*)?/i;
86
87
  _pool;
87
88
  /**
88
89
  * Constructor of `OINODbMariadb`
@@ -94,7 +95,8 @@ export class OINODbMariadb extends OINODb {
94
95
  if (this._params.type !== "OINODbMariadb") {
95
96
  throw new Error(OINO_ERROR_PREFIX + ": Not OINODbMariadb-type: " + this._params.type);
96
97
  }
97
- this._pool = mariadb.createPool({ host: params.url, database: params.database, port: params.port, user: params.user, password: params.password, acquireTimeout: 2000, debug: false, rowsAsArray: true });
98
+ this._pool = mariadb.createPool({ host: this._params.url, database: this._params.database, port: this._params.port, user: this._params.user, password: this._params.password, acquireTimeout: 2000, debug: false, rowsAsArray: true });
99
+ delete this._params.password; // do not store password in db object
98
100
  // this._pool.on("acquire", (conn: mariadb.Connection) => {
99
101
  // OINOLog.info("OINODbMariadb acquire", {conn:conn})
100
102
  // })
@@ -145,7 +147,7 @@ export class OINODbMariadb extends OINODb {
145
147
  return Promise.resolve(result);
146
148
  }
147
149
  catch (err) {
148
- const msg_parts = err.message.match(OINODbMariadb._exceptionMessageRegex) || [];
150
+ const msg_parts = err.message.match(OINODbMariadb._sqlExceptionMessageRegex) || [];
149
151
  // OINOLog.debug("OINODbMariadb._exec exception", {connection: msg_parts[1], message:msg_parts[2], sql:msg_parts[3]}) // print connection info just to log so tests don't break on runtime output
150
152
  throw new Error(msg_parts[2]);
151
153
  }
@@ -267,17 +269,57 @@ export class OINODbMariadb extends OINODb {
267
269
  *
268
270
  */
269
271
  async connect() {
272
+ const result = new OINOResult();
273
+ let connection = null;
270
274
  try {
271
275
  // make sure that any items are correctly URL encoded in the connection string
272
276
  // OINOLog.debug("OINODbMariadb.connect")
273
- await this._pool.on;
274
- // await this._client.connect()
275
- return Promise.resolve(true);
277
+ connection = await this._pool.getConnection();
278
+ this.isConnected = true;
279
+ }
280
+ catch (err) {
281
+ const msg_parts = err.message.match(OINODbMariadb._connectionExceptionMessageRegex) || [];
282
+ result.setError(500, "Error connecting to server: " + msg_parts[2], "OINODbMariadb.connect");
283
+ OINOLog.error(result.statusMessage, { error: err });
284
+ }
285
+ finally {
286
+ if (connection) {
287
+ await connection.end();
288
+ }
289
+ }
290
+ return Promise.resolve(result);
291
+ }
292
+ /**
293
+ * Validate connection to database is working.
294
+ *
295
+ */
296
+ async validate() {
297
+ OINOBenchmark.start("OINODb", "validate");
298
+ let result = new OINOResult();
299
+ try {
300
+ const sql = this._getValidateSql(this._params.database);
301
+ // OINOLog.debug("OINODbMariadb.validate", {sql:sql})
302
+ const sql_res = await this.sqlSelect(sql);
303
+ // OINOLog.debug("OINODbMariadb.validate", {sql_res:sql_res})
304
+ if (sql_res.isEmpty()) {
305
+ result.setError(400, "DB returned no rows for select!", "OINODbMariadb.validate");
306
+ }
307
+ else if (sql_res.getRow().length == 0) {
308
+ result.setError(400, "DB returned no values for database!", "OINODbMariadb.validate");
309
+ }
310
+ else if (sql_res.getRow()[0] == "0") {
311
+ result.setError(400, "DB returned no schema for database!", "OINODbMariadb.validate");
312
+ }
313
+ else {
314
+ this.isValidated = true;
315
+ }
276
316
  }
277
317
  catch (err) {
278
- // ... error checks
279
- throw new Error(OINO_ERROR_PREFIX + ": Error connecting to OINODbMariadb server: " + err);
318
+ result.setError(500, "Exception validating connection: " + err.message, "OINODbMariadb.validate");
319
+ OINOLog.error(result.statusMessage, { error: err });
280
320
  }
321
+ OINOBenchmark.end("OINODb", "validate");
322
+ return result;
281
323
  }
282
324
  /**
283
325
  * Execute a select operation.
@@ -334,6 +376,14 @@ WHERE C.TABLE_SCHEMA = '${dbName}' AND C.TABLE_NAME = '${tableName}'
334
376
  ORDER BY C.ORDINAL_POSITION;`;
335
377
  return sql;
336
378
  }
379
+ _getValidateSql(dbName) {
380
+ const sql = `SELECT
381
+ Count(c.COLUMN_NAME) AS COLUMN_COUNT
382
+ FROM information_schema.COLUMNS C
383
+ LEFT JOIN information_schema.KEY_COLUMN_USAGE KCU ON KCU.TABLE_SCHEMA = C.TABLE_SCHEMA AND KCU.TABLE_NAME = C.TABLE_NAME AND C.COLUMN_NAME = KCU.COLUMN_NAME and KCU.REFERENCED_TABLE_NAME IS NOT NULL
384
+ WHERE C.TABLE_SCHEMA = '${dbName}';`;
385
+ return sql;
386
+ }
337
387
  /**
338
388
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
339
389
  * the model.
@@ -1,11 +1,12 @@
1
- import { OINODb, OINODbParams, OINODbDataSet, OINODbApi, OINODataCell } from "@oino-ts/db";
1
+ import { OINODb, OINODbParams, OINODbDataSet, OINODbApi, OINODataCell, OINOResult } from "@oino-ts/db";
2
2
  /**
3
3
  * Implementation of MariaDb/MySql-database.
4
4
  *
5
5
  */
6
6
  export declare class OINODbMariadb extends OINODb {
7
7
  private static _fieldLengthRegex;
8
- private static _exceptionMessageRegex;
8
+ private static _connectionExceptionMessageRegex;
9
+ private static _sqlExceptionMessageRegex;
9
10
  private _pool;
10
11
  /**
11
12
  * Constructor of `OINODbMariadb`
@@ -58,7 +59,12 @@ export declare class OINODbMariadb extends OINODb {
58
59
  * Connect to database.
59
60
  *
60
61
  */
61
- connect(): Promise<boolean>;
62
+ connect(): Promise<OINOResult>;
63
+ /**
64
+ * Validate connection to database is working.
65
+ *
66
+ */
67
+ validate(): Promise<OINOResult>;
62
68
  /**
63
69
  * Execute a select operation.
64
70
  *
@@ -74,6 +80,7 @@ export declare class OINODbMariadb extends OINODb {
74
80
  */
75
81
  sqlExec(sql: string): Promise<OINODbDataSet>;
76
82
  private _getSchemaSql;
83
+ private _getValidateSql;
77
84
  /**
78
85
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
79
86
  * the model.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oino-ts/db-mariadb",
3
- "version": "0.5.2",
3
+ "version": "0.6.1",
4
4
  "description": "OINO TS package for using Mariadb databases.",
5
5
  "author": "Matias Kiviniemi (pragmatta)",
6
6
  "license": "MPL-2.0",
@@ -21,7 +21,7 @@
21
21
  "module": "./dist/esm/index.js",
22
22
  "types": "./dist/types/index.d.ts",
23
23
  "dependencies": {
24
- "@oino-ts/db": "^0.5.2",
24
+ "@oino-ts/db": "^0.6.1",
25
25
  "mariadb": "^3.2.3"
26
26
  },
27
27
  "devDependencies": {
@@ -4,7 +4,7 @@
4
4
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
6
 
7
- import { OINODb, OINODbParams, OINODbDataSet, OINODbApi, OINOBooleanDataField, OINONumberDataField, OINOStringDataField, OINODbDataFieldParams, OINO_ERROR_PREFIX, OINODataRow, OINODataCell, OINOBenchmark, OINODatetimeDataField, OINOBlobDataField, OINO_INFO_PREFIX, OINODB_EMPTY_ROW, OINODB_EMPTY_ROWS, OINOLog } from "@oino-ts/db";
7
+ import { OINODb, OINODbParams, OINODbDataSet, OINODbApi, OINOBooleanDataField, OINONumberDataField, OINOStringDataField, OINODbDataFieldParams, OINO_ERROR_PREFIX, OINODataRow, OINODataCell, OINOBenchmark, OINODatetimeDataField, OINOBlobDataField, OINO_INFO_PREFIX, OINODB_EMPTY_ROW, OINODB_EMPTY_ROWS, OINOLog, OINOResult } from "@oino-ts/db";
8
8
 
9
9
  import mariadb from "mariadb";
10
10
 
@@ -91,7 +91,8 @@ class OINOMariadbData extends OINODbDataSet {
91
91
  export class OINODbMariadb extends OINODb {
92
92
 
93
93
  private static _fieldLengthRegex = /([^\(\)]+)(\s?\((\d+)\s?\,?\s?(\d*)?\))?/i
94
- private static _exceptionMessageRegex = /\(([^\)]*)\) (.*)\nsql\:(.*)?/i
94
+ private static _connectionExceptionMessageRegex = /\(([^\)]*)\) (.*)/i
95
+ private static _sqlExceptionMessageRegex = /\(([^\)]*)\) (.*)\nsql\:(.*)?/i
95
96
 
96
97
  private _pool:mariadb.Pool
97
98
 
@@ -106,8 +107,9 @@ export class OINODbMariadb extends OINODb {
106
107
  if (this._params.type !== "OINODbMariadb") {
107
108
  throw new Error(OINO_ERROR_PREFIX + ": Not OINODbMariadb-type: " + this._params.type)
108
109
  }
109
- this._pool = mariadb.createPool({ host: params.url, database: params.database, port: params.port, user: params.user, password: params.password, acquireTimeout: 2000, debug:false, rowsAsArray: true })
110
-
110
+ this._pool = mariadb.createPool({ host: this._params.url, database: this._params.database, port: this._params.port, user: this._params.user, password: this._params.password, acquireTimeout: 2000, debug:false, rowsAsArray: true })
111
+ delete this._params.password // do not store password in db object
112
+
111
113
  // this._pool.on("acquire", (conn: mariadb.Connection) => {
112
114
  // OINOLog.info("OINODbMariadb acquire", {conn:conn})
113
115
  // })
@@ -160,7 +162,7 @@ export class OINODbMariadb extends OINODb {
160
162
  return Promise.resolve(result)
161
163
 
162
164
  } catch (err) {
163
- const msg_parts = (err as Error).message.match(OINODbMariadb._exceptionMessageRegex) || []
165
+ const msg_parts = (err as Error).message.match(OINODbMariadb._sqlExceptionMessageRegex) || []
164
166
  // OINOLog.debug("OINODbMariadb._exec exception", {connection: msg_parts[1], message:msg_parts[2], sql:msg_parts[3]}) // print connection info just to log so tests don't break on runtime output
165
167
  throw new Error(msg_parts[2]);
166
168
  } finally {
@@ -285,17 +287,58 @@ export class OINODbMariadb extends OINODb {
285
287
  * Connect to database.
286
288
  *
287
289
  */
288
- async connect(): Promise<boolean> {
290
+ async connect(): Promise<OINOResult> {
291
+ const result:OINOResult = new OINOResult()
292
+ let connection:mariadb.Connection|null = null
289
293
  try {
290
294
  // make sure that any items are correctly URL encoded in the connection string
291
295
  // OINOLog.debug("OINODbMariadb.connect")
292
- await this._pool.on
293
- // await this._client.connect()
294
- return Promise.resolve(true)
296
+ connection = await this._pool.getConnection()
297
+ this.isConnected = true
298
+
295
299
  } catch (err) {
296
- // ... error checks
297
- throw new Error(OINO_ERROR_PREFIX + ": Error connecting to OINODbMariadb server: " + err)
298
- }
300
+ const msg_parts = (err as Error).message.match(OINODbMariadb._connectionExceptionMessageRegex) || []
301
+ result.setError(500, "Error connecting to server: " + msg_parts[2], "OINODbMariadb.connect")
302
+ OINOLog.error(result.statusMessage, {error:err})
303
+ } finally {
304
+ if (connection) {
305
+ await connection.end()
306
+ }
307
+ }
308
+
309
+ return Promise.resolve(result)
310
+ }
311
+
312
+ /**
313
+ * Validate connection to database is working.
314
+ *
315
+ */
316
+ async validate(): Promise<OINOResult> {
317
+ OINOBenchmark.start("OINODb", "validate")
318
+ let result:OINOResult = new OINOResult()
319
+ try {
320
+ const sql = this._getValidateSql(this._params.database)
321
+ // OINOLog.debug("OINODbMariadb.validate", {sql:sql})
322
+ const sql_res:OINODbDataSet = await this.sqlSelect(sql)
323
+ // OINOLog.debug("OINODbMariadb.validate", {sql_res:sql_res})
324
+ if (sql_res.isEmpty()) {
325
+ result.setError(400, "DB returned no rows for select!", "OINODbMariadb.validate")
326
+
327
+ } else if (sql_res.getRow().length == 0) {
328
+ result.setError(400, "DB returned no values for database!", "OINODbMariadb.validate")
329
+
330
+ } else if (sql_res.getRow()[0] == "0") {
331
+ result.setError(400, "DB returned no schema for database!", "OINODbMariadb.validate")
332
+
333
+ } else {
334
+ this.isValidated = true
335
+ }
336
+ } catch (err:any) {
337
+ result.setError(500, "Exception validating connection: " + err.message, "OINODbMariadb.validate")
338
+ OINOLog.error(result.statusMessage, {error:err})
339
+ }
340
+ OINOBenchmark.end("OINODb", "validate")
341
+ return result
299
342
  }
300
343
 
301
344
  /**
@@ -357,6 +400,17 @@ ORDER BY C.ORDINAL_POSITION;`
357
400
  return sql
358
401
  }
359
402
 
403
+ private _getValidateSql(dbName:string):string {
404
+ const sql =
405
+ `SELECT
406
+ Count(c.COLUMN_NAME) AS COLUMN_COUNT
407
+ FROM information_schema.COLUMNS C
408
+ LEFT JOIN information_schema.KEY_COLUMN_USAGE KCU ON KCU.TABLE_SCHEMA = C.TABLE_SCHEMA AND KCU.TABLE_NAME = C.TABLE_NAME AND C.COLUMN_NAME = KCU.COLUMN_NAME and KCU.REFERENCED_TABLE_NAME IS NOT NULL
409
+ WHERE C.TABLE_SCHEMA = '${dbName}';`
410
+ return sql
411
+ }
412
+
413
+
360
414
  /**
361
415
  * Initialize a data model by getting the SQL schema and populating OINODbDataFields of
362
416
  * the model.