Matcher2.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. "use strict";
  2. // Autogenerated by cport.py on 2013-09-17 14:37
  3. var Matcher2 = module.exports = function (docMatcher, constrainIndexKey){
  4. // File: matcher.cpp lines: 94-102
  5. var indexExpression = this.spliceForIndex(constrainIndexKey, docMatcher._expression.get(), this._spliceInfo);
  6. if (indexExpression) {
  7. this._expression.reset(indexExpression);
  8. }
  9. }, klass = Matcher2, base = Object , proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  10. // DEPENDENCIES
  11. var errors = require("../../Errors.js"),
  12. ErrorCodes = errors.ErrorCodes,
  13. MatchExpression = require("./MatchExpression.js"),
  14. FalseMatchExpression = require("./FalseMatchExpression.js"),
  15. ComparisonMatchExpression = require("./ComparisonMatchExpression.js"),
  16. InMatchExpression = require("./InMatchExpression.js"),
  17. AndMatchExpression = require("./AndMatchExpression.js"),
  18. OrMatchExpression = require("./OrMatchExpression.js"),
  19. IndexKeyMatchableDocument = require('./IndexKeyMatchableDocument.js'),
  20. ListOfMatchExpression = require('./ListOfMatchExpression.js'),
  21. LeafMatchExpression = require("./LeafMatchExpression.js");
  22. // File: matcher.h lines: 82-82
  23. proto._expression = undefined;
  24. // File: matcher.h lines: 80-80
  25. proto._indexKey = undefined;
  26. // File: matcher.h lines: 79-79
  27. proto._pattern = undefined;
  28. // File: matcher.h lines: 84-84
  29. proto._spliceInfo = undefined;
  30. // File: matcher.h lines: 82-82
  31. proto._expression = undefined;
  32. // File: matcher.h lines: 80-80
  33. proto._indexKey = undefined;
  34. // File: matcher.h lines: 79-79
  35. proto._pattern = undefined;
  36. // File: matcher.h lines: 84-84
  37. proto._spliceInfo = undefined;
  38. /**
  39. *
  40. * This documentation was automatically generated. Please update when you touch this function.
  41. * @method _spliceForIndex
  42. * @param
  43. *
  44. */
  45. proto._spliceForIndex = function _spliceForIndex(keys, full, spliceInfo){
  46. // File: matcher.cpp lines: 236-380
  47. var dup, i, obj, lme;
  48. switch (full.matchType()) {
  49. case MatchExpression.ALWAYS_FALSE:
  50. return new FalseMatchExpression();
  51. case MatchExpression.GEO_NEAR:
  52. case MatchExpression.NOT:
  53. case MatchExpression.NOR:
  54. // maybe?
  55. return null;
  56. case MatchExpression.OR:
  57. case MatchExpression.AND:
  58. dup = new ListOfMatchExpression();
  59. for (i = 0; i < full.numChildren(); i++) {
  60. var sub = this._spliceForIndex(keys, full.getChild(i), spliceInfo);
  61. if (!sub)
  62. continue;
  63. if (!dup.get()) {
  64. if (full.matchType() == MatchExpression.AND)
  65. dup.reset(new AndMatchExpression());
  66. else
  67. dup.reset(new OrMatchExpression());
  68. }
  69. dup.add(sub);
  70. }
  71. if (dup.get()) {
  72. if (full.matchType() == MatchExpression.OR && dup.numChildren() != full.numChildren()) {
  73. // TODO: I think this should actuall get a list of all the fields
  74. // and make sure that's the same
  75. // with an $or, have to make sure its all or nothing
  76. return null;
  77. }
  78. return dup.release();
  79. }
  80. return null;
  81. case MatchExpression.EQ:
  82. var cmp = new ComparisonMatchExpression(full);
  83. if (cmp.getRHS().type() == Array) {
  84. // need to convert array to an $in
  85. if (!keys.count(cmp.path().toString()))
  86. return null;
  87. var newIn = new InMatchExpression();
  88. newIn.init(cmp.path());
  89. if (newIn.getArrayFilterEntries().addEquality(cmp.getRHS()).isOK())
  90. return null;
  91. if (cmp.getRHS().Obj().isEmpty())
  92. newIn.getArrayFilterEntries().addEquality(undefined);
  93. obj = cmp.getRHS().Obj();
  94. for(i in obj) {
  95. var s = newIn.getArrayFilterEntries().addEquality( obj[i].next() );
  96. if (s.code != ErrorCodes.OK)
  97. return null;
  98. }
  99. return newIn.release();
  100. }
  101. else if (cmp.getRHS().type() === null) {
  102. //spliceInfo.hasNullEquality = true;
  103. return null;
  104. }
  105. break;
  106. case MatchExpression.LTE:
  107. case MatchExpression.LT:
  108. case MatchExpression.GT:
  109. case MatchExpression.GTE:
  110. cmp = new ComparisonMatchExpression(full);
  111. if ( cmp.getRHS().type() === null) {
  112. // null and indexes don't play nice
  113. //spliceInfo.hasNullEquality = true;
  114. return null;
  115. }
  116. break;
  117. case MatchExpression.REGEX:
  118. case MatchExpression.MOD:
  119. lme = new LeafMatchExpression(full);
  120. if (!keys.count(lme.path().toString()))
  121. return null;
  122. return lme.shallowClone();
  123. case MatchExpression.MATCH_IN:
  124. lme = new LeafMatchExpression(full);
  125. if (!keys.count(lme.path().toString()))
  126. return null;
  127. var cloned = new InMatchExpression(lme.shallowClone());
  128. if (cloned.getArrayFilterEntries().hasEmptyArray())
  129. cloned.getArrayFilterEntries().addEquality(undefined);
  130. // since { $in : [[1]] } matches [1], need to explode
  131. for (i = cloned.getArrayFilterEntries().equalities().begin(); i != cloned.getArrayFilterEntries().equalities().end(); ++i) {
  132. var x = cloned[i];
  133. if (x.type() == Array) {
  134. for(var j in x) {
  135. cloned.getArrayFilterEntries().addEquality(x[j]);
  136. }
  137. }
  138. }
  139. return cloned;
  140. case MatchExpression.ALL:
  141. // TODO: convert to $in
  142. return null;
  143. case MatchExpression.ELEM_MATCH_OBJECT:
  144. case MatchExpression.ELEM_MATCH_VALUE:
  145. // future
  146. return null;
  147. case MatchExpression.GEO:
  148. case MatchExpression.SIZE:
  149. case MatchExpression.EXISTS:
  150. case MatchExpression.NIN:
  151. case MatchExpression.TYPE_OPERATOR:
  152. case MatchExpression.ATOMIC:
  153. case MatchExpression.WHERE:
  154. // no go
  155. return null;
  156. }
  157. return null;
  158. };
  159. /**
  160. *
  161. * This documentation was automatically generated. Please update when you touch this function.
  162. * @method atomic
  163. * @param
  164. *
  165. */
  166. proto.atomic = function atomic(){
  167. // File: matcher.cpp lines: 120-133
  168. if (!this._expression)
  169. return false;
  170. if (this._expression.matchType() == MatchExpression.ATOMIC)
  171. return true;
  172. // we only go down one level
  173. for (var i = 0; i < this._expression.numChildren(); i++) {
  174. if (this._expression.getChild(i).matchType() == MatchExpression.ATOMIC)
  175. return true;
  176. }
  177. return false;
  178. };
  179. /**
  180. *
  181. * This documentation was automatically generated. Please update when you touch this function.
  182. * @method getQuery
  183. * @param
  184. *
  185. */
  186. proto.getQuery = function getQuery(){
  187. // File: matcher.h lines: 65-64
  188. return this._pattern;
  189. };
  190. /**
  191. *
  192. * This documentation was automatically generated. Please update when you touch this function.
  193. * @method hasExistsFalse
  194. * @param
  195. *
  196. */
  197. proto.hasExistsFalse = function hasExistsFalse(){
  198. // File: matcher.cpp lines: 172-180
  199. if (this._spliceInfo.hasNullEquality) {
  200. // { a : NULL } is very dangerous as it may not got indexed in some cases
  201. // so we just totally ignore
  202. return true;
  203. }
  204. return this._isExistsFalse(this._expression.get(), false, this._expression.matchType() == MatchExpression.AND ? -1 : 0);
  205. };
  206. /**
  207. *
  208. * This documentation was automatically generated. Please update when you touch this function.
  209. * @method keyMatch
  210. * @param
  211. *
  212. */
  213. proto.keyMatch = function keyMatch(docMatcher){
  214. // File: matcher.cpp lines: 199-206
  215. if (!this._expression)
  216. return docMatcher._expression.get() === null;
  217. if (!docMatcher._expression)
  218. return false;
  219. if (this._spliceInfo.hasNullEquality)
  220. return false;
  221. return this._expression.equivalent(docMatcher._expression.get());
  222. };
  223. /**
  224. *
  225. * This documentation was automatically generated. Please update when you touch this function.
  226. * @method matches
  227. * @param
  228. *
  229. */
  230. proto.matches = function matches(doc, details){
  231. // File: matcher.cpp lines: 105-116
  232. if (!this._expression)
  233. return true;
  234. if (this._indexKey.isEmpty())
  235. return this._expression.matchesBSON(doc, details);
  236. if (!doc.isEmpty() && doc.firstElement().fieldName()[0])
  237. return this._expression.matchesBSON(doc, details);
  238. var mydoc = new IndexKeyMatchableDocument(this._indexKey, doc);
  239. return this._expression.matches(mydoc, details);
  240. };
  241. /**
  242. *
  243. * This documentation was automatically generated. Please update when you touch this function.
  244. * @method singleSimpleCriterion
  245. * @param
  246. *
  247. */
  248. proto.singleSimpleCriterion = function singleSimpleCriterion(){
  249. // File: matcher.cpp lines: 184-196
  250. if (!this._expression)
  251. return false;
  252. if (this._expression.matchType() == MatchExpression.EQ)
  253. return true;
  254. if (this._expression.matchType() == MatchExpression.AND && this._expression.numChildren() == 1 && this._expression.getChild(0).matchType() == MatchExpression.EQ)
  255. return true;
  256. return false;
  257. };
  258. /**
  259. *
  260. * This documentation was automatically generated. Please update when you touch this function.
  261. * @method spliceForIndex
  262. * @param
  263. *
  264. */
  265. proto.spliceForIndex = function spliceForIndex(key, full, spliceInfo){
  266. // File: matcher.cpp lines: 209-217
  267. var keys = [],
  268. e, i;
  269. for (i in key) {
  270. e = key[i];
  271. keys.insert(e.fieldName());
  272. }
  273. return this._spliceForIndex(keys, full, spliceInfo);
  274. };
  275. /**
  276. *
  277. * This documentation was automatically generated. Please update when you touch this function.
  278. * @method toString
  279. * @param
  280. *
  281. */
  282. proto.toString = function toString(){
  283. // File: matcher.h lines: 66-65
  284. return this._pattern.toString();
  285. };