Skip to content

Commit b091def

Browse files
committed
[feat] Trails Stores
1 parent 483feb8 commit b091def

File tree

12 files changed

+138
-143
lines changed

12 files changed

+138
-143
lines changed

api/services/FootprintService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
const _ = require('lodash')
4-
const Service = require('trails/lib/service')
4+
const Service = require('trails/lib/Service')
55
const ModelError = require('../../lib').ModelError
66

77
const manageError = err => {

api/services/SchemaMigrationService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
const Service = require('trails/lib/service')
3+
const Service = require('trails/lib/Service')
44

55
/**
66
* @module SchemaMigrationService

archetype/config/database.js

Lines changed: 0 additions & 37 deletions
This file was deleted.

config/database.js

Lines changed: 0 additions & 11 deletions
This file was deleted.

config/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
exports.trailpack = require('./trailpack')
2-
exports.database = require('./database')

index.js

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint no-console: [0] */
12
'use strict'
23

34
const Trailpack = require('trailpack/datastore')
@@ -15,7 +16,7 @@ module.exports = class SequelizeTrailpack extends Trailpack {
1516
this.app.config.log.logger.warn('No store configured at config.database.stores, models will be ignored')
1617
}
1718
return Promise.all([
18-
lib.Validator.validateDatabaseConfig(this.app.config.database)
19+
lib.Validator.validateStoresConfig(stores)
1920
])
2021
}
2122

@@ -36,40 +37,55 @@ module.exports = class SequelizeTrailpack extends Trailpack {
3637

3738
this.orm = this.orm || {}
3839
this.app.orm = {}
39-
this.connections = lib.Transformer.transformStores(this.app)
40-
this.models = lib.Transformer.transformModels(this.app)
41-
42-
_.each(this.models, (model, modelName) => {
43-
_.each(this.connections, (connection, name) => {
44-
if (model.connection === name) {
45-
const Model = connection.define(modelName, model.schema, model.config)
46-
47-
if (model.config) {
48-
if (model.config.classMethods) {
49-
for (const methodName in model.config.classMethods) {
50-
Model[methodName] = model.config.classMethods[methodName]
51-
}
52-
}
40+
this.connections = lib.Transformer.transformStoreConnections(this.app)
41+
this.app.models = lib.Transformer.transformModels(this.app)
42+
43+
this.stores = _.mapValues(this.app.config.get('stores'), (store, storeName) => {
44+
return {
45+
models: _.pickBy(this.app.models, { store: storeName }),
46+
connection: this.connections[storeName],
47+
migrate: store.migrate || this.app.config.get('models.migrate')
48+
}
49+
})
5350

54-
if (model.config.instanceMethods) {
55-
for (const methodName in model.config.instanceMethods) {
56-
Model.prototype[methodName] = model.config.instanceMethods[methodName]
57-
}
51+
// Loop through store models and define them in Sequelize
52+
_.each(this.stores, (store, storeName) => {
53+
_.each(store.models, (model, modelName) => {
54+
const Model = store.connection.define(modelName, model.schema, model.options)
55+
56+
if (model.options) {
57+
if (model.options.classMethods) {
58+
for (const methodName in model.options.classMethods) {
59+
Model[methodName] = model.options.classMethods[methodName]
5860
}
5961
}
6062

61-
this.app.orm[model.globalId] = Model
63+
if (model.options.instanceMethods) {
64+
for (const methodName in model.options.instanceMethods) {
65+
Model.prototype[methodName] = model.options.instanceMethods[methodName]
66+
}
67+
}
6268
}
69+
this.app.orm[model.globalId] = Model
6370
})
6471
})
6572

66-
_.each(this.models, (model, modelName) => {
67-
if (!this.app.orm[model.globalId]) return //ignore model if not configured
68-
69-
if (this.app.orm[model.globalId].associate)
70-
this.app.orm[model.globalId].associate(this.app.orm)
73+
// Loop through store models and associate
74+
_.each(this.stores, (store, storeName) => {
75+
// Run Associate on the Models
76+
_.each(store.models, (model, modelName) => {
77+
// ignore model if not configured
78+
if (!this.app.orm[model.globalId]) {
79+
return
80+
}
81+
// Associate models if method defined
82+
if (this.app.orm[model.globalId].associate) {
83+
this.app.orm[model.globalId].associate(this.app.orm)
84+
}
7185

72-
this.orm[model.globalId.toLowerCase()] = this.app.orm[model.globalId]
86+
// Reset the orm Model
87+
this.orm[model.globalId.toLowerCase()] = this.app.orm[model.globalId]
88+
})
7389
})
7490

7591
return this.migrate()
@@ -80,9 +96,9 @@ module.exports = class SequelizeTrailpack extends Trailpack {
8096
*/
8197
async unload() {
8298
return Promise.all(
83-
_.map(this.connections, connection => {
99+
_.map(this.stores, store => {
84100
return new Promise((resolve, reject) => {
85-
connection.close()
101+
store.connection.close()
86102
resolve()
87103
})
88104
})
@@ -91,18 +107,20 @@ module.exports = class SequelizeTrailpack extends Trailpack {
91107

92108
async migrate() {
93109
const SchemaMigrationService = this.app.services.SchemaMigrationService
94-
const migrate = this.app.config.get('database.models.migrate')
95-
96-
if (migrate === 'none') return
97110

98111
return Promise.all(
99-
_.map(this.connections, connection => {
100-
101-
if (migrate === 'drop') {
102-
return SchemaMigrationService.dropDB(connection)
112+
_.map(this.stores, store => {
113+
if (store.migrate === 'drop') {
114+
return SchemaMigrationService.dropDB(store.connection)
115+
}
116+
else if (store.migrate === 'alter') {
117+
return SchemaMigrationService.alterDB(store.connection)
118+
}
119+
else if (store.migrate === 'none') {
120+
return
103121
}
104-
else if (migrate === 'alter') {
105-
return SchemaMigrationService.alterDB(connection)
122+
else {
123+
return
106124
}
107125
})
108126
)

lib/schemas.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@
22
const joi = require('joi')
33

44
module.exports = {
5-
databaseConfig: joi.object().keys({
6-
orm: joi.string(),
7-
models: joi.object().keys({
8-
defaultStore: joi.string().required(),
9-
migrate: joi.string()
10-
}),
11-
stores: joi.object()
12-
}),
5+
storesConfig: joi.object().keys({
6+
orm: joi.string()
7+
}).unknown(),
138

149
models: joi.object().keys({
1510
autoPK: joi.boolean(),

lib/transformer.js

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,14 @@ const _ = require('lodash')
55
const Sequelize = require('sequelize')
66

77
module.exports = {
8-
98
/**
109
* Augment the model definition with some sequelize-required properties
1110
*/
1211
transformModels (app) {
1312

14-
const models = app.models
15-
const dbConfig = app.config.database
13+
// const models = app.models
1614

17-
return _.mapValues(models, (model, modelName) => {
15+
return _.mapValues(app.models, (model, modelName) => {
1816
const config = model.constructor.config(app, Sequelize) || {}
1917
const schema = model.constructor.schema(app, Sequelize) || {}
2018

@@ -26,16 +24,41 @@ module.exports = {
2624
config.options.tableName = modelName.toLowerCase()
2725
}
2826

29-
return {
30-
identity: modelName.toLowerCase(),
31-
globalId: modelName,
32-
tableName: config.tableName || modelName.toLowerCase(),
33-
connection: config.store || app.config.get('database.models.defaultStore'),
34-
migrate: config.migrate || app.config.get('database.models.migrate'),
35-
config: config.options,
36-
schema: schema
37-
}
38-
27+
Object.defineProperties(model, {
28+
identity: {
29+
value: modelName.toLowerCase(),
30+
writable: false
31+
},
32+
Sequelize: {
33+
value: Sequelize,
34+
writable: true
35+
},
36+
globalId: {
37+
value: modelName,
38+
writable: false
39+
},
40+
tableName: {
41+
value: config.tableName || modelName.toLowerCase(),
42+
writable: false
43+
},
44+
store: {
45+
value: config.store || app.config.get('models.defaultStore'),
46+
writable: false
47+
},
48+
migrate: {
49+
value: config.migrate || app.config.get('models.migrate'),
50+
writable: false
51+
},
52+
options: {
53+
value: config.options,
54+
writable: true
55+
},
56+
schema: {
57+
value: schema,
58+
writable: true
59+
}
60+
})
61+
return model
3962
})
4063
},
4164

@@ -58,7 +81,7 @@ module.exports = {
5881
* @param {Object} stores
5982
* @return {Object}
6083
*/
61-
pickStores (stores) {
84+
pickStoreConnections (stores) {
6285
return _.pickBy(stores, (_store, name) => {
6386
return ((_store.dialect && _.isString(_store.dialect))
6487
|| _.startsWith(_store.uri, 'mysql://')
@@ -71,8 +94,8 @@ module.exports = {
7194
/**
7295
* Transform the Trails.js "stores" config into a Sequelize object
7396
*/
74-
transformStores (app) {
75-
const stores = this.pickStores(app.config.get('database.stores'))
97+
transformStoreConnections (app) {
98+
const stores = this.pickStoreConnections(app.config.get('stores'))
7699
const sequelize = {}
77100
Object.keys(stores).forEach(key => {
78101
sequelize[key] = this.createFromConfig(stores[key])

lib/validator.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ const joi = require('joi')
22
const lib = require('.')
33

44
module.exports = {
5-
validateDatabaseConfig (config) {
5+
validateStoresConfig (config) {
66
return new Promise((resolve, reject) => {
7-
joi.validate(config, lib.Schemas.databaseConfig, (err, value) => {
7+
joi.validate(config, lib.Schemas.storesConfig, (err, value) => {
88
if (err) return reject(err)
99

1010
return resolve(value)

0 commit comments

Comments
 (0)