Skip to content

Commit 7baea7b

Browse files
author
Pavel Romanov
committed
Initial commit
1 parent 70336c5 commit 7baea7b

16 files changed

+2191
-0
lines changed

.gitignore

2.65 KB
Binary file not shown.

connections/AbstractConnection.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
class AbstractConnection {
2+
constructor(config) {
3+
this.config = config;
4+
this.client = config.client;
5+
this.queries = config.queries;
6+
7+
if (new.target === AbstractConnection) {
8+
throw new TypeError('Abstract class can not be created!');
9+
}
10+
}
11+
12+
/**
13+
* @param {Object} queryObject
14+
* @param {Object} queryParams
15+
* @param {Object} queryOptions
16+
* @returns {Promise<Array>}
17+
*/
18+
query(queryObject, queryParams, queryOptions = null) {
19+
throw new TypeError('This method must be overridden!');
20+
}
21+
22+
/**
23+
* @returns {Promise<null>}
24+
*/
25+
transaction() {
26+
throw new TypeError('This method must be overridden!');
27+
}
28+
29+
/**
30+
* @returns {Promise<null>}
31+
*/
32+
commit() {
33+
throw new TypeError('This method must be overridden!');
34+
}
35+
36+
/**
37+
* @returns {Promise<null>}
38+
*/
39+
rollback() {
40+
throw new TypeError('This method must be overridden!');
41+
}
42+
43+
/**
44+
* @returns {String}
45+
*/
46+
getQueryText(queryName) {
47+
throw new TypeError('This method must be overridden!');
48+
}
49+
50+
/**
51+
* @param {String} queryText
52+
* @param {Array || Object} queryParams
53+
* @param {Object} queryOptions
54+
* @returns {Promise<Array>}
55+
*/
56+
rawQuery(queryText, queryParams, queryOptions = null) {
57+
throw new TypeError('This method must be overridden!');
58+
}
59+
60+
/**
61+
* @returns {Promise<null>}
62+
*/
63+
release() {
64+
throw new TypeError('This method must be overridden!');
65+
}
66+
67+
68+
}
69+
70+
module.exports = AbstractConnection;

connections/PostgresConnection.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const AbstractConnection = require('./AbstractConnection');
2+
// const log = require('../../../../app/components/log')(module);
3+
// const {NoSuchQuery} = require('../errors');
4+
const {escapeParams, QueryTemplater} = require('../query');
5+
6+
class PostgresConnection extends AbstractConnection {
7+
constructor(config) {
8+
super(config);
9+
}
10+
11+
// async query(queryName, queryParams, queryOptions = null) {
12+
// const self = this;
13+
//
14+
// // let timeOld;
15+
// // if (queryOptions && queryOptions.time) {
16+
// // timeOld = Date.now();
17+
// // }
18+
//
19+
// const data = await self.client.query(self.queries[queryName], queryParams);
20+
// const {rows} = data;
21+
//
22+
// // if (queryOptions && queryOptions.time) {
23+
// // log.info(`Query ${queryName} execution time: ${Date.now() - timeOld} ms`);
24+
// // }
25+
//
26+
// return rows;
27+
// }
28+
async _executeQuery(query) {
29+
const {rows} = await this.client.query(query);
30+
return rows;
31+
}
32+
33+
async rawQuery(queryText, queryParams, queryOptions = null) {
34+
// let timeOld;
35+
// if (queryOptions && queryOptions.time && queryOptions.queryName) {
36+
// timeOld = Date.now();
37+
// }
38+
39+
const {rows} = await this.client.query(queryText, queryParams);
40+
41+
// if (queryOptions && queryOptions.time) {
42+
// log.info(`Query ${queryOptions.queryName} execution time: ${Date.now() - timeOld} ms`);
43+
// }
44+
45+
return rows;
46+
}
47+
48+
async query(queryObject, queryParams, queryOptions = {}) {
49+
// TODO: unused destructed "types" need to add opportunity to pass array as PG arrays
50+
const {sql, types} = queryObject;
51+
let queryText = sql;
52+
53+
const {templateParams} = queryOptions;
54+
if (templateParams) {
55+
queryText = QueryTemplater.buildQuery(queryObject, templateParams);
56+
}
57+
58+
const preparedQuery = escapeParams(queryText, queryParams);
59+
console.log(preparedQuery);
60+
61+
// return this._executeQuery(preparedQuery);
62+
}
63+
64+
getQueryText(queryName) {
65+
return this.queries[queryName];
66+
}
67+
68+
async transaction() {
69+
await this.client.query('BEGIN;');
70+
}
71+
72+
async commit() {
73+
await this.client.query('COMMIT;');
74+
}
75+
76+
async rollback() {
77+
await this.client.query('ROLLBACK;');
78+
}
79+
80+
async release() {
81+
await this.client.release();
82+
}
83+
}
84+
85+
module.exports = PostgresConnection;

connectors/AbstractConnector.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class AbstractConnector {
2+
constructor(config) {
3+
this.config = config;
4+
5+
if (new.target === AbstractConnector) {
6+
throw new TypeError('Abstract class can not be created!');
7+
}
8+
}
9+
10+
/**
11+
* @returns {Promise<AbstractConnection>} Connection
12+
*/
13+
async getConnection() {
14+
throw new TypeError('This method must be overridden!');
15+
}
16+
17+
/**
18+
* @param {AbstractConnection} connection Abstract connection
19+
*/
20+
async releaseConnection(connection) {
21+
throw new TypeError('This method must be overridden!');
22+
}
23+
24+
/**
25+
* @async
26+
*/
27+
async closeConnection() {
28+
throw new TypeError('This method must be overridden!');
29+
}
30+
}
31+
32+
module.exports = AbstractConnector;

connectors/PostgresConnector.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const {Pool} = require('pg');
2+
// const log = require('../../../../app/components/log')(module);
3+
4+
const AbstractConnector = require('./AbstractConnector');
5+
const PostgresConnection = require('../connections/PostgresConnection');
6+
7+
class PostgresConnector extends AbstractConnector {
8+
constructor(config) {
9+
super(config);
10+
11+
this.pool = new Pool({...config});
12+
13+
// this.pool.on('error', error => {
14+
// // log.error(`Something happened with Postgres pool ${config.storageName}. errorCode: ${error.code}. error: ${error}`);
15+
// });
16+
}
17+
18+
async getConnection() {
19+
const client = await this.pool.connect();
20+
21+
const config = {
22+
client,
23+
...(this.config),
24+
};
25+
26+
const connection = new PostgresConnection(config);
27+
28+
return connection;
29+
}
30+
31+
32+
async releaseConnection(connection) {
33+
await connection.client.release();
34+
}
35+
36+
async closeConnection() {
37+
await this.pool.end();
38+
}
39+
}
40+
41+
module.exports = PostgresConnector;

connectors/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const PostgresConnector = require('./PostgresConnector');
2+
3+
module.exports = {
4+
PostgresConnector,
5+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// const config = require('../../../../app/components/config');
2+
3+
/**
4+
* @class
5+
*/
6+
class AbstractConnectorFactory {
7+
/**
8+
* @constructor
9+
* @param {Object} storageConfig path to query file
10+
*/
11+
constructor(storageConfig) {
12+
this.storageConfig = storageConfig;
13+
// this.queryPath = queryPath;
14+
15+
if (new.target === AbstractConnectorFactory) {
16+
throw new TypeError('You can not create instance of abstract class');
17+
}
18+
}
19+
20+
/**
21+
* @param {String} storageName storage name
22+
* @returns {Promise<AbstractConnector>} connector
23+
*/
24+
createConnector(storageName) {
25+
return null;
26+
}
27+
}
28+
29+
module.exports = AbstractConnectorFactory;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const AbstractConnectorFactory = require('./AbstractConnectorFactory');
2+
const {PostgresConnector} = require('../connectors');
3+
const {QueryGetter} = require('../query');
4+
5+
/**
6+
* @class
7+
*/
8+
class PostgresConnectorFactory extends AbstractConnectorFactory {
9+
_getStorageConfig(storageName) {
10+
const config = this.storageConfig[storageName];
11+
if (!config) {
12+
throw new ReferenceError('Invalid storage name!');
13+
}
14+
15+
return config;
16+
}
17+
18+
async createConnector(storageName) {
19+
const config = this._getStorageConfig(storageName);
20+
21+
// const queryGetter = new QueryGetter({fileName: this.queryPath});
22+
23+
// const queries = await queryGetter.getQueries();
24+
// this.storageConfig.queries = queries;
25+
const connector = new PostgresConnector({...config, storageName});
26+
27+
return connector;
28+
}
29+
}
30+
31+
module.exports = PostgresConnectorFactory;

factories/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const AbstractConnectorFactory = require('./AbstractConnectorFactory');
2+
const PostgresConnectorFactory = require('./PostgresConnectorFactory');
3+
module.exports = {
4+
AbstractConnectorFactory,
5+
PostgresConnectorFactory,
6+
};

index.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const {PostgresConnectorFactory} = require('./factories');
2+
3+
/**
4+
* @class
5+
*/
6+
class DataStorage {
7+
/**
8+
* @constructor
9+
* @param {Object} storageConfig sc
10+
* @private
11+
*/
12+
constructor(storageConfig) {
13+
this.storageConfig = storageConfig;
14+
/** @type {Map<String,AbstractConnector>} */
15+
this.connectors = new Map();
16+
/** @type {{String:AbstractConnectorFactory}} */
17+
this.factoriesAssociation = {
18+
'pg': new PostgresConnectorFactory(storageConfig),
19+
};
20+
}
21+
22+
// addFactory(name, factory) {
23+
// this.factoriesAssociation[name] = new factory(this.storageConfig)
24+
// }
25+
26+
/**
27+
* @param {String} connectorName connector name
28+
* @returns {Promise.<AbstractConnector>} Connector
29+
*/
30+
async getConnector(connectorName) {
31+
if (this.connectors.has(connectorName)) {
32+
return this.connectors.get(connectorName);
33+
}
34+
35+
const {storageType} = this.storageConfig[connectorName];
36+
37+
const connector = await this.factoriesAssociation[storageType].createConnector(connectorName);
38+
39+
if (connector) {
40+
this.connectors.set(connectorName, connector);
41+
} else {
42+
throw new ReferenceError('Connector not created');
43+
}
44+
45+
return connector;
46+
}
47+
48+
/**
49+
* @param {String} connectorName connector name
50+
* @returns {Promise.<AbstractConnection>} connection
51+
*/
52+
async getConnection(connectorName) {
53+
const connector = await this.getConnector(connectorName);
54+
55+
return connector.getConnection();
56+
}
57+
58+
/**
59+
* @async
60+
*/
61+
async disconnectAll() {
62+
for (const [, connector] of this.connectors) {
63+
await connector.closeConnection();
64+
// log.info(`Connector ${name} disconnected`);
65+
}
66+
}
67+
}
68+
69+
module.exports = DataStorage;
70+

0 commit comments

Comments
 (0)