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