Variables.js 3.2 KB

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