Skip to content

Commit 66b09f4

Browse files
Temp - works with callbacks. Working on converting it to promises
1 parent f90414b commit 66b09f4

12 files changed

+357
-14
lines changed

database-creation.sql

+10
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,14 @@ GRANT ALL ON `hapiestmysql`.* to 'hapiestmysql'@'%' IDENTIFIED BY 'hapiestmysql'
88
GRANT ALL ON `hapiestmysql`.* to 'hapiestmysql'@'localhost' IDENTIFIED BY 'hapiestmysql';
99
GRANT ALL ON `hapiestmysql`.* to 'hapiestmysql'@'127.0.0.1' IDENTIFIED BY 'hapiestmysql';
1010

11+
FLUSH PRIVILEGES;
12+
13+
DROP DATABASE IF EXISTS `hapiestmysql_test`;
14+
CREATE DATABASE IF NOT EXISTS `hapiestmysql_test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
15+
16+
/* User for API server connecting to database when collocated; probably only used for local dev */
17+
GRANT ALL ON `hapiestmysql_test`.* to 'hapiestmysql'@'%' IDENTIFIED BY 'hapiestmysql';
18+
GRANT ALL ON `hapiestmysql_test`.* to 'hapiestmysql'@'localhost' IDENTIFIED BY 'hapiestmysql';
19+
GRANT ALL ON `hapiestmysql_test`.* to 'hapiestmysql'@'127.0.0.1' IDENTIFIED BY 'hapiestmysql';
20+
1121
FLUSH PRIVILEGES;

lib/mysqlPoolConnectionConfig.js

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class MysqlPoolConnectionConfig extends VO {
2525
get password() { return this.get('password'); }
2626
get database() { return this.get('database'); }
2727
get connectionLimit() { return this.get('connectionLimit'); }
28+
get multipleStatements() { return this.get('multipleStatements'); }
2829

2930
}
3031

lib/mysqlPoolConnectionConfigFactory.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class MysqlPoolConnectionsConfigFactory {
3737
* @param {string} config.user
3838
* @param {string} config.password
3939
* @param {int} config.connectionLimit
40+
* @param {bool} config.multipleStatements
4041
*
4142
* @returns {MysqlPoolConnectionConfig}
4243
*/
@@ -60,7 +61,8 @@ class Internals {
6061
user: Internals.getValue(nodeConfig, writeOrRead, 'user'),
6162
password: Internals.getValue(nodeConfig, writeOrRead, 'password'),
6263
database: Internals.getValue(nodeConfig, writeOrRead, 'database'),
63-
connectionLimit: Internals.getValue(nodeConfig, writeOrRead, 'connectionLimit')
64+
connectionLimit: Internals.getValue(nodeConfig, writeOrRead, 'connectionLimit'),
65+
multipleStatements: Internals.getValue(nodeConfig, writeOrRead, 'multipleStatements')
6466
};
6567

6668
Internals.mergeIfDefined(nodeConfig, config, writeOrRead, 'port');

lib/mysqlPoolConnectionConfigSchema.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ module.exports = {
88
database: Joi.string().required(),
99
user: Joi.string().max(32).required(),
1010
password: Joi.string().required(),
11-
connectionLimit: Joi.number().integer().required()
11+
connectionLimit: Joi.number().integer().required(),
12+
multipleStatements: Joi.bool().optional()
1213
};

lib/mysqlService.js

+21-4
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class MysqlService {
9191
return Promise.resolve()
9292
.then(() => MysqlQuery.validateInsert(insertQuery))
9393
.then(() => this._writePool.queryAsync(insertQuery))
94-
.then((result) => Promise.resolve(MysqlInsertResultFactory.createFromResult(result)))
94+
.then((result) => MysqlInsertResultFactory.createFromResult(result))
9595
.catch(err => {
9696
this._logSqlError(err, insertQuery);
9797
throw err;
@@ -107,36 +107,53 @@ class MysqlService {
107107
return Promise.resolve()
108108
.then(() => MysqlQuery.validateUpdate(updateQuery))
109109
.then(() => this._writePool.queryAsync(updateQuery))
110-
.then((result) => Promise.resolve(MysqlInsertResultFactory.createFromResult(result)))
110+
.then((result) => MysqlInsertResultFactory.createFromResult(result))
111111
.catch(err => {
112112
this._logSqlError(err, updateQuery);
113113
throw err;
114114
})
115115
;
116116
}
117117

118+
/**
119+
* @param {string} deleteQuery
120+
* @returns {Promise.<MysqlModificationResult,Error>}
121+
*/
118122
delete(deleteQuery) {
119123
return Promise.resolve()
120124
.then(() => MysqlQuery.validateDelete(deleteQuery))
121125
.then(() => this._writePool.queryAsync(deleteQuery))
122-
.then((result) => Promise.resolve(MysqlInsertResultFactory.createFromResult(result)))
126+
.then((result) => MysqlInsertResultFactory.createFromResult(result))
123127
.catch(err => {
124128
this._logSqlError(err, deleteQuery);
125129
throw err;
126130
})
127131
;
128132
}
129133

134+
/**
135+
* @param {string} query
136+
* @returns {Promise.<*>}
137+
*/
130138
executeGenericQuery(query) {
131139
return Promise.resolve()
132-
.then(() => this._writePool.queryAsync(query)) // We have to execute generic queries against "master");
140+
.then(() => {return this._writePool.queryAsync(query)}) // We have to execute generic queries against "master");
133141
.catch(err => {
134142
this._logSqlError(err, query);
135143
throw err;
136144
})
137145
;
138146
}
139147

148+
/**
149+
* Executes all queries using executeGenericQuery
150+
* @param {String[]} queries
151+
* @returns {Promise}
152+
*/
153+
executeQueries(queries) {
154+
return Promise.mapSeries(queries, (query) => this.executeGenericQuery(query));
155+
}
156+
140157
clean(input) {
141158
return Mysql.escape(input);
142159
}

lib/mysqlServiceFactory.js

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
const MysqlPoolConnectionConfigFactory = require('./mysqlPoolConnectionConfigFactory');
44
const MysqlService = require('./mysqlService');
55

6+
// @TODO: add a nodeConfig "root" concept so createFromNodeConfig can apply for multiple database connections within a config file
7+
68
class MysqlServiceFactory {
79

810
/**
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
class MysqlDatabaseSetup {
4+
5+
/**
6+
* @param {MysqlDatabaseSetupDao} dao
7+
*/
8+
constructor(dao) {
9+
this._dao = dao;
10+
}
11+
12+
/**
13+
*
14+
*/
15+
replicateAllTables(done) {
16+
this._dao.replicateAllTables(done);
17+
}
18+
19+
/**
20+
* @param {string[]} tables - list of tables to recreate in our unit testing database
21+
*/
22+
replicateTables(tables) {
23+
tables.forEach(table => {
24+
const query = `SHOW CREATE TABLE ${this._schemaSourceDatabase}.${table};`;
25+
this._mysqlService.executeGenericQuery(query)
26+
.then(createTable => console.log(createTable));
27+
});
28+
}
29+
30+
}
31+
32+
module.exports = MysqlDatabaseSetup;
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
'use strict';
2+
3+
const Promise = require('bluebird');
4+
const Async = require('async');
5+
6+
class MysqlDatabaseSetupDao {
7+
8+
/**
9+
* @param {MysqlService} mysqlService
10+
* @param {string} schemaSourceDatabase
11+
*/
12+
constructor(mysqlService, schemaSourceDatabase) {
13+
this._mysqlService = mysqlService;
14+
this._schemaSourceDatabase = schemaSourceDatabase;
15+
}
16+
17+
replicateAllTables(done) {
18+
const self = this;
19+
20+
Async.auto({
21+
tables: (next) => {
22+
self.getAllTablesFromSourceDatabase(next)
23+
},
24+
dropTables: ['tables', function(results, next) {
25+
const tables = results.tables;
26+
const dropTablesSql = self.getDropTablesSql(tables);
27+
28+
self._mysqlService.executeGenericQuery(dropTablesSql)
29+
.then(() => next());
30+
}],
31+
createTables: ['dropTables', function(results, next) {
32+
const tables = results.tables;
33+
self.getCreateTablesSql(tables, (err, sql) => {
34+
self._mysqlService.executeGenericQuery(sql)
35+
.then(() => next());
36+
})
37+
}]
38+
}, (err, results) => {
39+
done();
40+
});
41+
}
42+
43+
/**
44+
* @returns {Promise.<String[]>} - an array of table names
45+
*/
46+
getAllTablesFromSourceDatabase(done) {
47+
const allTablesQuery = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${this._schemaSourceDatabase}';`;
48+
return this._mysqlService.selectAll(allTablesQuery)
49+
.then(allTables => {
50+
done(null, allTables.map(tableRow => tableRow.TABLE_NAME))
51+
});
52+
}
53+
54+
/**
55+
* @param tables
56+
* @returns {string}
57+
*/
58+
getDropTablesSql(tables) {
59+
const dropTableQueries = ['SET foreign_key_checks = 0;'];
60+
tables.forEach(table => dropTableQueries.push(`DROP TABLE IF EXISTS ${table};`));
61+
dropTableQueries.push('SET foreign_key_checks = 1;');
62+
63+
return dropTableQueries.join("\n");
64+
}
65+
66+
/**
67+
* @param {String[]} tables
68+
* @param {function(err, string)} done
69+
*/
70+
getCreateTablesSql(tables, done) {
71+
const createTablesQueries = ['SET foreign_key_checks = 0;'];
72+
const self = this;
73+
74+
Async.eachSeries(tables, (table, eachNext) => {
75+
self.getCreateTableSql(table, (err, sql) => {
76+
createTablesQueries.push(sql);
77+
eachNext();
78+
})
79+
}, () => {
80+
createTablesQueries.push('SET foreign_key_checks = 1;');
81+
done(null, createTablesQueries.join("\n"));
82+
});
83+
}
84+
85+
getCreateTableSql(table, done) {
86+
this.getCreateTableStatement(table, (err, sql) => {
87+
done(null, sql);
88+
});
89+
}
90+
91+
getCreateTableStatement(table, done) {
92+
const getCreateTableSql = `SHOW CREATE TABLE ${this._schemaSourceDatabase}.${table};`;
93+
this._mysqlService.executeGenericQuery(getCreateTableSql)
94+
.then(createTableResult => done(null, createTableResult[0]['Create Table'] + ';'))
95+
;
96+
}
97+
98+
}
99+
100+
module.exports = MysqlDatabaseSetupDao;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
const MysqlDatabaseSetupDao = require('./mysqlDatabaseSetupDao');
4+
5+
class MysqlDatabaseSetupDaoFactory {
6+
7+
/**
8+
* @param {MysqlService} mysqlService
9+
* @param {string} schemaSourceDatabase
10+
* @returns {MysqlDatabaseSetupDao}
11+
*/
12+
static create(mysqlService, schemaSourceDatabase) {
13+
return new MysqlDatabaseSetupDao(mysqlService, schemaSourceDatabase);
14+
}
15+
16+
}
17+
18+
module.exports = MysqlDatabaseSetupDaoFactory;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
const MysqlDatabaseSetup = require('./mysqlDatabaseSetup');
4+
const MysqlDatabaseSetupDaoFactory = require('./mysqlDatabaseSetupDaoFactory');
5+
6+
class MysqlDatabaseSetupFactory {
7+
8+
/**
9+
* @param {MysqlService} mysqlService
10+
* @param {string} schemaSourceDatabase
11+
* @returns {MysqlDatabaseSetup}
12+
*/
13+
static create(mysqlService, schemaSourceDatabase) {
14+
const dao = MysqlDatabaseSetupDaoFactory.create(mysqlService, schemaSourceDatabase);
15+
return new MysqlDatabaseSetup(dao);
16+
}
17+
18+
}
19+
20+
module.exports = MysqlDatabaseSetupFactory;

0 commit comments

Comments
 (0)