source: Dev/branches/rest-dojo-ui/client/rft/store.js @ 381

Last change on this file since 381 was 379, checked in by hendrikvanantwerpen, 13 years ago

Changed SurveyListView? to more general OrderedDndList?.
Survey page has rudimentary properties dialog and saves included questions.
Fixed bug in store for null question.

File size: 10.0 KB
Line 
1define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/array','dojo/_base/Deferred','dojo/_base/xhr','dojo/json','dojo/store/util/QueryResults'],
2    function(declare,lang,array,Deferred,xhr,JSON,QueryResults){
3   
4        var CouchStore = declare(null, {
5            /** dojo.Store implementation for CouchDB
6             *
7             * See for details on the REST API, the wiki
8             * at http://wiki.apache.org/couchdb/HTTP_Document_API.
9             */
10                target: "",
11                accepts: "application/json",
12            idProperty: "_id",
13            revProperty: "_rev",
14            _responseIdProperty: "id",
15            _responseRevProperty: "rev",
16                constructor: function(options){
17                        declare.safeMixin(this, options);
18            },
19                getIdentity: function(object){
20                        return object[this.idProperty];
21            },
22                getRevision: function(object){
23                        return object[this.revProperty];
24            },
25                get: function(id){
26                var dfd = new Deferred();
27                        xhr("GET", {
28                                url: this.target + id,
29                                handleAs: "json",
30                                headers: {
31                                Accept: this.accepts
32                    }
33                        }).then(function(result){
34                    if ( result.error ) {
35                        dfd.reject(result.reason);
36                    } else {
37                        dfd.resolve(result);
38                    }
39                }, function(err){
40                    dfd.reject(err);
41                });
42                return dfd.promise;
43            },
44                put: function(object, options){
45                 // summary:
46                 //     put an object in CouchDB
47                 // object: Object
48                 //     The object to put
49                 // options: Object
50                 //     Options object as
51                 //         id: String
52                 //
53                        options = options || {};
54
55                var dfd = new Deferred();
56                        var id = options.id ? options.id : this.getIdentity(object);
57                        var hasId = typeof id != "undefined";
58                        xhr(hasId ? "PUT" : "POST", {
59                                    url: hasId ? this.target + id : this.target,
60                                    postData: JSON.stringify(object),
61                                    handleAs: "json",
62                                    headers:{
63                                            "Content-Type": "application/json",
64                                            Accept: this.accepts
65                                    }
66                            }).then(lang.hitch(this,function(result){
67                    if ( result.error ) {
68                        dfd.reject(result.reason);
69                    } else {
70                        object[this.idProperty] = result[this._responseIdProperty];
71                        object[this.revProperty] = result[this._responseRevProperty];
72                        dfd.resolve(object);
73                    }
74                }), function(err){
75                    dfd.reject(err);
76                });
77                return dfd.promise;
78            },
79                add: function(object, options){
80                return this.put(object,options);
81            },
82                remove: function(id,rev){
83                var dfd = new Deferred();
84                        xhr("DELETE",{
85                                url: this.target + id,
86                                    headers: {
87                        'If-Match': rev
88                    }
89                        }).then(function(result){
90                    if ( result.error ) {
91                        dfd.reject(result.reason);
92                    } else {
93                        dfd.resolve();
94                    }
95                },function(err){
96                    dfd.reject(err);
97                });
98                return dfd.promise;
99            },
100            query: function(query, options){
101                // summary:
102                //    query a couchdb view
103                // query: String
104                //    name of a couchdb view you want to query, relative to the current database
105                // options: Object
106                //     options object as
107                //        start: Number
108                //            Start results at this item
109                //        count: Number
110                //            Number of items to return
111                //        sort: [{attribute:'key',descending:true|false}]
112                //            CouchDB only support sorting by key, so only 'key'
113                //            is allowed as attribute value. Multiple sort items
114                //            are ignored.
115                //        key: String|Array|Object
116                //            Return only values with this key.
117                //            Excludes start/endkey usage.
118                //        startkey: String|Array|Object
119                //            Return values starting from this key.
120                //        endkey: String|Array|Object
121                //            Return values with key lower than this key.
122                //        include_docs: true|false
123                //            Return the full documents instead of the view
124                //            values.
125                //        reduce: true|false
126                //            Execute reduce on the view or not. Default depends
127                //            on if a reduce function is defined on the view.
128                //        group: true|false
129                //            Should values be grouped per key or not? Default
130                //            is false.
131                //        group_level: Number
132                //            When group = true and the key is an array,
133                //            determines which elements starting from the first
134                //            are used for grouping. Default is 0.
135                //        get_keys: true|false
136                //            Instead of returning the values or documents,
137                //            return the array of keys as the result.
138                //            This does not affect the forPairs function.
139                        options = options || {};
140
141                var dfd = new Deferred();
142                var queryOpts = {};
143                if ( !query ) {
144                    query = '_all_docs';
145                }
146
147                if (!lang.isString(query)) {
148                    console.warn("Query must be a view name");
149                }
150
151                // Standard options
152                if (options.start >= 0) {
153                    queryOpts.skip = options.start;
154                }
155                if (options.count >= 0) {
156                    queryOpts.limit = options.count;
157                }
158                if (options.sort) {
159                    if (options.sort[0]) {
160                        if (options.sort[0].attribute && options.sort[0].attribute !== "key") {
161                            console.warn("Can only sort on key");
162                        }
163                        if (options.sort[0].descending) {
164                            queryOpts.descending = true;
165                        }
166                    }
167                    if (options.sort.length > 1) {
168                        console.warn("multiple sort fields not supported");
169                    }
170                }
171
172                // Custom options
173                if (options.key !== undefined) {
174                    queryOpts.key = options.key;
175                } else if (options.keys !== undefined) {
176                    queryOpts.keys = options.keys;
177                } else if (options.startkey !== undefined || options.endkey !== undefined) {
178                    queryOpts.startkey = options.startkey;
179                    queryOpts.endkey = options.endkey;
180                }
181                if (options.include_docs !== undefined) {
182                    queryOpts.include_docs = options.include_docs;
183                }
184                if (options.reduce !== undefined) {
185                    queryOpts.reduce = options.reduce;
186                }
187                if (options.group !== undefined) {
188                    queryOpts.group = options.group;
189                    if (options.group_level !== undefined) {
190                        queryOpts.group_level = options.group_level;
191                    }
192                }
193
194                for (var qp in queryOpts) {
195                    queryOpts[qp] = JSON.stringify(queryOpts[qp]);
196                }
197                            query += '?' + xhr.objectToQuery(queryOpts);
198
199                        xhr("GET", {
200                                url: this.target + query,
201                                handleAs: "json",
202                                headers: {
203                        Accept: this.accepts
204                    }
205                        }).then(function(result){
206                    if (result.error) {
207                        dfd.reject(result.reason);
208                    } else  {
209                        var results;
210                        var values = array.map(result.rows,function(result){
211                            return options.include_docs === true ? result.doc : result.value;
212                        });
213                        var keys = array.map(result.rows,function(result){
214                            return result.key;
215                        });
216                        if (options.get_keys === true) {
217                            results = keys;
218                            results.values = values;
219                        } else {
220                            results = values;
221                            results.keys = keys;
222                        }
223                        dfd.resolve(results);
224                    }
225                },function(err){
226                    dfd.reject(err);
227                });
228                        return CouchResults(dfd.promise);
229            }
230        });
231
232        function CouchResults(results) {
233            results = QueryResults(results);
234            results.forPairs = function(callback,thisObject) {
235                callback = lang.hitch(thisObject,callback);
236                return Deferred.when(results,function(results) {
237                    var values = results.values || results;
238                    var keys = results.keys || results;
239                    return array.forEach(values, function(value,index) {
240                        callback(value,keys[index],index);
241                    });
242                });
243            }
244            return results;
245        }
246
247        return new CouchStore({target: 'data/rft/'});
248
249    });
Note: See TracBrowser for help on using the repository browser.