modelBindKnex.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. const { inheritModel } = require('./inheritModel');
  2. const { staticHiddenProps } = require('./modelUtils');
  3. const { defineNonEnumerableProperty } = require('./modelUtils');
  4. function bindKnex(ModelClass, knex) {
  5. let BoundModelClass = getBoundModelFromCache(ModelClass, knex);
  6. if (BoundModelClass === null) {
  7. BoundModelClass = inheritModel(ModelClass);
  8. BoundModelClass = copyHiddenProperties(ModelClass, BoundModelClass);
  9. BoundModelClass.knex(knex);
  10. BoundModelClass = putBoundModelToCache(ModelClass, BoundModelClass, knex);
  11. BoundModelClass = bindRelations(ModelClass, BoundModelClass, knex);
  12. }
  13. return BoundModelClass;
  14. }
  15. function getBoundModelFromCache(ModelClass, knex) {
  16. const cache = getCache(knex);
  17. const cacheKey = ModelClass.uniqueTag();
  18. return cache.get(cacheKey) || null;
  19. }
  20. function getCache(knex) {
  21. if (!knex.$$objection) {
  22. createCache(knex);
  23. }
  24. return knex.$$objection.boundModels;
  25. }
  26. function createCache(knex) {
  27. defineNonEnumerableProperty(knex, '$$objection', {
  28. boundModels: new Map()
  29. });
  30. }
  31. function copyHiddenProperties(ModelClass, BoundModelClass) {
  32. for (let i = 0, l = staticHiddenProps.length; i < l; ++i) {
  33. const prop = staticHiddenProps[i];
  34. // $$relations and $$relationArray are handled in separately.
  35. if (ModelClass.hasOwnProperty(prop) && prop !== '$$relations' && prop !== '$$relationArray') {
  36. defineNonEnumerableProperty(BoundModelClass, prop, ModelClass[prop]);
  37. }
  38. }
  39. return BoundModelClass;
  40. }
  41. function putBoundModelToCache(ModelClass, BoundModelClass, knex) {
  42. const cache = getCache(knex);
  43. const cacheKey = ModelClass.uniqueTag();
  44. cache.set(cacheKey, BoundModelClass);
  45. return BoundModelClass;
  46. }
  47. function bindRelations(ModelClass, BoundModelClass, knex) {
  48. const relations = ModelClass.getRelationArray();
  49. const boundRelations = Object.create(null);
  50. const boundRelationArray = [];
  51. for (let i = 0, l = relations.length; i < l; ++i) {
  52. const relation = relations[i];
  53. const boundRelation = relation.bindKnex(knex);
  54. boundRelations[relation.name] = boundRelation;
  55. boundRelationArray.push(boundRelation);
  56. }
  57. defineNonEnumerableProperty(BoundModelClass, '$$relations', boundRelations);
  58. defineNonEnumerableProperty(BoundModelClass, '$$relationArray', boundRelationArray);
  59. return BoundModelClass;
  60. }
  61. module.exports = {
  62. bindKnex
  63. };