SimpleQueryEngine.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. define("dojo/store/util/SimpleQueryEngine", ["../../_base/array"], function(arrayUtil) {
  2. // module:
  3. // dojo/store/util/SimpleQueryEngine
  4. // summary:
  5. // The module defines a simple filtering query engine for object stores.
  6. return function(query, options){
  7. // summary:
  8. // Simple query engine that matches using filter functions, named filter
  9. // functions or objects by name-value on a query object hash
  10. //
  11. // description:
  12. // The SimpleQueryEngine provides a way of getting a QueryResults through
  13. // the use of a simple object hash as a filter. The hash will be used to
  14. // match properties on data objects with the corresponding value given. In
  15. // other words, only exact matches will be returned.
  16. //
  17. // This function can be used as a template for more complex query engines;
  18. // for example, an engine can be created that accepts an object hash that
  19. // contains filtering functions, or a string that gets evaluated, etc.
  20. //
  21. // When creating a new dojo.store, simply set the store's queryEngine
  22. // field as a reference to this function.
  23. //
  24. // query: Object
  25. // An object hash with fields that may match fields of items in the store.
  26. // Values in the hash will be compared by normal == operator, but regular expressions
  27. // or any object that provides a test() method are also supported and can be
  28. // used to match strings by more complex expressions
  29. // (and then the regex's or object's test() method will be used to match values).
  30. //
  31. // options: dojo.store.util.SimpleQueryEngine.__queryOptions?
  32. // An object that contains optional information such as sort, start, and count.
  33. //
  34. // returns: Function
  35. // A function that caches the passed query under the field "matches". See any
  36. // of the "query" methods on dojo.stores.
  37. //
  38. // example:
  39. // Define a store with a reference to this engine, and set up a query method.
  40. //
  41. // | var myStore = function(options){
  42. // | // ...more properties here
  43. // | this.queryEngine = dojo.store.util.SimpleQueryEngine;
  44. // | // define our query method
  45. // | this.query = function(query, options){
  46. // | return dojo.store.util.QueryResults(this.queryEngine(query, options)(this.data));
  47. // | };
  48. // | };
  49. // create our matching query function
  50. switch(typeof query){
  51. default:
  52. throw new Error("Can not query with a " + typeof query);
  53. case "object": case "undefined":
  54. var queryObject = query;
  55. query = function(object){
  56. for(var key in queryObject){
  57. var required = queryObject[key];
  58. if(required && required.test){
  59. if(!required.test(object[key])){
  60. return false;
  61. }
  62. }else if(required != object[key]){
  63. return false;
  64. }
  65. }
  66. return true;
  67. };
  68. break;
  69. case "string":
  70. // named query
  71. if(!this[query]){
  72. throw new Error("No filter function " + query + " was found in store");
  73. }
  74. query = this[query];
  75. // fall through
  76. case "function":
  77. // fall through
  78. }
  79. function execute(array){
  80. // execute the whole query, first we filter
  81. var results = arrayUtil.filter(array, query);
  82. // next we sort
  83. if(options && options.sort){
  84. results.sort(function(a, b){
  85. for(var sort, i=0; sort = options.sort[i]; i++){
  86. var aValue = a[sort.attribute];
  87. var bValue = b[sort.attribute];
  88. // valueOf enables proper comparison of dates
  89. aValue = aValue != null ? aValue.valueOf() : aValue;
  90. bValue = bValue != null ? bValue.valueOf() : bValue;
  91. if (aValue != bValue) {
  92. return !!sort.descending == aValue > bValue ? -1 : 1;
  93. }
  94. }
  95. return 0;
  96. });
  97. }
  98. // now we paginate
  99. if(options && (options.start || options.count)){
  100. var total = results.length;
  101. results = results.slice(options.start || 0, (options.start || 0) + (options.count || Infinity));
  102. results.total = total;
  103. }
  104. return results;
  105. }
  106. execute.matches = query;
  107. return execute;
  108. };
  109. });