]>
Commit | Line | Data |
---|---|---|
f0cfe83e AD |
1 | define("dojo/store/util/SimpleQueryEngine", ["../../_base/array" /*=====, "../api/Store" =====*/], function(arrayUtil /*=====, Store =====*/){ |
2 | ||
3 | // module: | |
4 | // dojo/store/util/SimpleQueryEngine | |
5 | ||
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/api/Store.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 = SimpleQueryEngine; | |
44 | // | // define our query method | |
45 | // | this.query = function(query, options){ | |
46 | // | return QueryResults(this.queryEngine(query, options)(this.data)); | |
47 | // | }; | |
48 | // | }; | |
49 | ||
50 | // create our matching query function | |
51 | switch(typeof query){ | |
52 | default: | |
53 | throw new Error("Can not query with a " + typeof query); | |
54 | case "object": case "undefined": | |
55 | var queryObject = query; | |
56 | query = function(object){ | |
57 | for(var key in queryObject){ | |
58 | var required = queryObject[key]; | |
59 | if(required && required.test){ | |
60 | // an object can provide a test method, which makes it work with regex | |
61 | if(!required.test(object[key], object)){ | |
62 | return false; | |
63 | } | |
64 | }else if(required != object[key]){ | |
65 | return false; | |
66 | } | |
67 | } | |
68 | return true; | |
69 | }; | |
70 | break; | |
71 | case "string": | |
72 | // named query | |
73 | if(!this[query]){ | |
74 | throw new Error("No filter function " + query + " was found in store"); | |
75 | } | |
76 | query = this[query]; | |
77 | // fall through | |
78 | case "function": | |
79 | // fall through | |
80 | } | |
81 | function execute(array){ | |
82 | // execute the whole query, first we filter | |
83 | var results = arrayUtil.filter(array, query); | |
84 | // next we sort | |
85 | var sortSet = options && options.sort; | |
86 | if(sortSet){ | |
87 | results.sort(typeof sortSet == "function" ? sortSet : function(a, b){ | |
88 | for(var sort, i=0; sort = sortSet[i]; i++){ | |
89 | var aValue = a[sort.attribute]; | |
90 | var bValue = b[sort.attribute]; | |
91 | if (aValue != bValue){ | |
92 | return !!sort.descending == (aValue == null || 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 | ||
110 | }); |