Variables.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. "use strict";
  2. /**
  3. * Class that stores/tracks variables
  4. * @class Variables
  5. * @namespace mungedb-aggregate.pipeline.expressions
  6. * @module mungedb-aggregate
  7. * @constructor
  8. **/
  9. var Variables = module.exports = function Variables(numVars, root){
  10. if(numVars) {
  11. if(typeof numVars !== 'number') {
  12. throw new Error('numVars must be a number');
  13. }
  14. }
  15. this._root = root || {};
  16. this._rest = numVars ? [] : undefined; //An array of `Value`s
  17. this._numVars = numVars;
  18. }, klass = Variables,
  19. base = Object,
  20. proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  21. klass.ROOT_ID = -1;
  22. // PROTOTYPE MEMBERS
  23. /**
  24. * Sets the root variable
  25. * @method setRoot
  26. * @parameter root {Document} The root variable
  27. **/
  28. proto.setRoot = function setRoot(root){
  29. if(!(root instanceof Object && root.constructor.name === 'Object')) { //NOTE: Type checking cause c++ does this for you
  30. throw new Error('root must be an Object');
  31. }
  32. this._root = root;
  33. };
  34. /**
  35. * Clears the root variable
  36. * @method clearRoot
  37. **/
  38. proto.clearRoot = function clearRoot(){
  39. this._root = {};
  40. };
  41. /**
  42. * Gets the root variable
  43. * @method getRoot
  44. * @return {Document} the root variable
  45. **/
  46. proto.getRoot = function getRoot(){
  47. return this._root;
  48. };
  49. /**
  50. * Inserts a value with the given id
  51. * @method setValue
  52. * @param id {Number} The index where the value is stored in the _rest Array
  53. * @param value {Value} The value to store
  54. **/
  55. proto.setValue = function setValue(id, value) {
  56. //NOTE: Some added type enforcement cause c++ does this for you
  57. if(typeof id !== 'number') {
  58. throw new Error('id must be a Number');
  59. }
  60. if(id === klass.ROOT_ID) {
  61. throw new Error("mError 17199: can't use Variables#setValue to set ROOT");
  62. }
  63. if(id >= this._numVars) { // a > comparator would be off-by-one; i.e. if we have 5 vars, the max id would be 4
  64. throw new Error("You have more variables than _numVars");
  65. }
  66. this._rest[id] = value;
  67. };
  68. /**
  69. * Get the value at the given id
  70. * @method getValue
  71. * @param id {Number} The index where the value was stored
  72. * @return {Value} The value
  73. **/
  74. proto.getValue = function getValue(id) {
  75. //NOTE: Some added type enforcement cause c++ does this for you
  76. if(typeof id !== 'number') {
  77. throw new Error('id must be a Number');
  78. }
  79. if(id === klass.ROOT_ID) {
  80. return this._root;
  81. }
  82. if(id >= this._numVars) { // a > comparator would be off-by-one; i.e. if we have 5 vars, the max id would be 4
  83. throw new Error("Cannot get value; id was greater than _numVars");
  84. }
  85. return this._rest[id];
  86. };
  87. /**
  88. * Get the value for id if it's a document
  89. * @method getDocument
  90. * @param id {Number} The index where the document was stored
  91. * @return {Object} The document
  92. **/
  93. proto.getDocument = function getDocument(id) {
  94. //NOTE: Some added type enforcement cause c++ does this for you
  95. if(typeof id !== 'number') {
  96. throw new Error('id must be a Number');
  97. }
  98. if(id === klass.ROOT_ID) {
  99. return this._root;
  100. }
  101. if(id >= this._numVars) { // a > comparator would be off-by-one; i.e. if we have 5 vars, the max id would be 4
  102. throw new Error("Cannot get value; id was greater than _numVars");
  103. }
  104. var value = this._rest[id];
  105. if(typeof value === 'object' && value.constructor.name === 'Object') {
  106. return value;
  107. }
  108. return {};
  109. };