model-manager.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. 'use strict';
  2. const Toposort = require('toposort-class');
  3. const _ = require('lodash');
  4. class ModelManager {
  5. constructor(sequelize) {
  6. this.models = [];
  7. this.sequelize = sequelize;
  8. }
  9. addModel(model) {
  10. this.models.push(model);
  11. this.sequelize.models[model.name] = model;
  12. return model;
  13. }
  14. removeModel(modelToRemove) {
  15. this.models = this.models.filter(model => model.name !== modelToRemove.name);
  16. delete this.sequelize.models[modelToRemove.name];
  17. }
  18. getModel(against, options) {
  19. options = _.defaults(options || {}, {
  20. attribute: 'name'
  21. });
  22. return this.models.find(model => model[options.attribute] === against);
  23. }
  24. get all() {
  25. return this.models;
  26. }
  27. /**
  28. * Iterate over Models in an order suitable for e.g. creating tables.
  29. * Will take foreign key constraints into account so that dependencies are visited before dependents.
  30. *
  31. * @param {Function} iterator method to execute on each model
  32. * @param {object} [options] iterator options
  33. * @private
  34. */
  35. forEachModel(iterator, options) {
  36. const models = {};
  37. const sorter = new Toposort();
  38. let sorted;
  39. let dep;
  40. options = _.defaults(options || {}, {
  41. reverse: true
  42. });
  43. for (const model of this.models) {
  44. let deps = [];
  45. let tableName = model.getTableName();
  46. if (_.isObject(tableName)) {
  47. tableName = `${tableName.schema}.${tableName.tableName}`;
  48. }
  49. models[tableName] = model;
  50. for (const attrName in model.rawAttributes) {
  51. if (Object.prototype.hasOwnProperty.call(model.rawAttributes, attrName)) {
  52. const attribute = model.rawAttributes[attrName];
  53. if (attribute.references) {
  54. dep = attribute.references.model;
  55. if (_.isObject(dep)) {
  56. dep = `${dep.schema}.${dep.tableName}`;
  57. }
  58. deps.push(dep);
  59. }
  60. }
  61. }
  62. deps = deps.filter(dep => tableName !== dep);
  63. sorter.add(tableName, deps);
  64. }
  65. sorted = sorter.sort();
  66. if (options.reverse) {
  67. sorted = sorted.reverse();
  68. }
  69. for (const name of sorted) {
  70. iterator(models[name], name);
  71. }
  72. }
  73. }
  74. module.exports = ModelManager;
  75. module.exports.ModelManager = ModelManager;
  76. module.exports.default = ModelManager;