All files / lib/model/nw/dataSource EntityContainer.js

100% Statements 29/29
100% Branches 6/6
100% Functions 13/13
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126    1x 1x 1x 1x 1x         1x                                     31x 93x 76x   93x 70x                                         32x     32x 32x 24x                       19x 18x 1x         17x                     5x 5x 2x         3x                     31x                     38x       1x  
"use strict";
 
const _ = require("lodash");
const AnnotationTarget = require("../../oasis/annotations/AnnotationTarget");
const AssociationSet = require("./AssociationSet");
const EntitySet = require("./EntitySet");
const FunctionImport = require("./FunctionImport");
 
// schema level elements collection
// order is important for initialization because, AssociationSetEnd references EntityType, FunctionImport can reference EntitySet
// (MS-CSDL requires order in xml: FunctionImport, EntitySet, AssociationSet)
const childCollections = [
  {
    name: "entitySets",
    sourceElement: "EntitySet",
    Class: EntitySet,
  },
  {
    name: "associationSets",
    sourceElement: "AssociationSet",
    Class: AssociationSet,
  },
  {
    name: "functionImports",
    sourceElement: "FunctionImport",
    Class: FunctionImport,
  },
];
 
function initChildProperties(container, schema) {
  childCollections.forEach((collection) => {
    let child = _.get(container.raw, collection.sourceElement, []).map(
      (t) => new collection.Class(t, schema)
    );
    Object.defineProperty(container, collection.name, {
      get: () => child,
    });
  });
}
 
/**
 * Envelopes an EntityContainer.
 *
 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/mc-csdl/031f2e18-935b-461b-95ce-62e11432047a
 * http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/cs01/odata-csdl-xml-v4.01-cs01.html#sec_EntityContainer
 *
 * @class EntityContainer
 * @extends {AnnotationTarget}
 */
class EntityContainer extends AnnotationTarget {
  /**
   * Creates an instance of EntityContainer.
   * @param {Object} rawMetadata raw metadata object for entity container
   * @memberof EntityContainer
   */
  constructor(rawMetadata) {
    super(rawMetadata);
 
    let isDefault =
      _.get(rawMetadata.$, "m:IsDefaultEntityContainer", "false") === "true";
    Object.defineProperty(this, "isDefault", {
      get: () => isDefault,
    });
  }
 
  /**
   * Gets an EntitySet defined in container
   *
   * @param {string} [name] entity set name
   * @returns {EntitySet} set with given name
   * @memberof EntityContainer
   */
  getEntitySet(name) {
    let set = this.entitySets.find((s) => s.name === name);
    if (!set) {
      throw new Error(
        `EntitySet '${name}' not found in entity container '${this.name}'`
      );
    }
 
    return set;
  }
 
  /**
   * Gets an FunctionImport defined in container
   *
   * @param {string} [name] function import name
   * @returns {EntitySet} set with given name
   * @memberof EntityContainer
   */
  getFunctionImport(name) {
    let set = this.functionImports.find((s) => s.name === name);
    if (!set) {
      throw new Error(
        `FunctionImport '${name}' not found in entity container '${this.name}'`
      );
    }
 
    return set;
  }
 
  /**
   * Initializes entity container child collection properties. Decoupled from constructor,
   * because it needs to resolve schema references and entity container elements.
   *
   * @param {CsdlSchema} schema to resolve references
   * @memberof EntityContainer
   */
  initSchemaDependentProperties(schema) {
    initChildProperties(this, schema);
  }
 
  /**
   * Resolves model path within this enetity container.
   *
   * @param {strin} [path] model path
   * @returns {Object} resolved container element
   * @memberof EntityContainer
   */
  resolveModelPath(path) {
    return path ? this.entitySets.find((e) => e.name === path) : this;
  }
}
 
module.exports = EntityContainer;