]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/PermaCrud.js
make sync-style the default for pcrud, use {async:true} to go async
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / PermaCrud.js
1 /* ---------------------------------------------------------------------------
2  * Copyright (C) 2008  Equinox Software, Inc
3  * Mike Rylander <miker@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ---------------------------------------------------------------------------
15  */
16
17 if(!dojo._hasResource["openils.PermaCrud"]) {
18
19     dojo._hasResource["openils.PermaCrud"] = true;
20     dojo.provide("openils.PermaCrud");
21     dojo.require("fieldmapper.Fieldmapper");
22     dojo.require("openils.User");
23
24     dojo.declare('openils.PermaCrud', null, {
25
26         session : null,
27         authtoken : null,
28         connnected : false,
29
30         constructor : function ( kwargs ) {
31             kwargs = kwargs || {};
32
33             this.authtoken = kwargs.authtoken;
34
35             this.session =
36                 kwargs.session ||
37                 new OpenSRF.ClientSession('open-ils.pcrud');
38
39             if (
40                 this.session &&
41                 this.session.state == OSRF_APP_SESSION_CONNECTED
42             ) this.connected = true;
43         },
44
45         auth : function (token) {
46             if (token) this.authtoken = token;
47             return this.authtoken || openils.User.authtoken;
48         },
49
50         connect : function ( onerror ) {
51             if (!this.connected && !this.session.connect()) {
52                 this.connected = false;
53                 if (onerror) onerror(this.session);
54                 return false;
55             }
56             this.connected = true;
57             return true;
58         },
59
60         disconnect : function ( onerror ) {
61             if (!this.session.disconnect()) {
62                 if (onerror) onerror(this.session);
63                 return false;
64             }
65             return true;
66         },
67         
68
69         retrieve : function ( fm_class /* Fieldmapper class hint */, id /* Fieldmapper object primary key value */,  opts /* Option hash */) {
70             var req_hash = dojo.mixin(
71                 opts, 
72                 { method : 'open-ils.pcrud.retrieve.' + fm_class,
73                   params : [ this.auth(), id ]
74                 }
75             );
76
77             if (!opts.async && !opts.timeout) req_hash.timeout = 10;
78
79             var _pcrud = this;
80             var req = this.session.request( req_hash );
81
82
83             if (!req.onerror)
84                 req.onerror = function (r) { throw js2JSON(r); };
85
86             if (!req.oncomplete)
87                 req.oncomplete = function (r) { r.result = r.recv(); _pcrud.last_result = r.result; };
88
89             req.send();
90
91             if (req_hash.timeout) return req.result.content();
92             return req;
93         },
94
95         retrieveAll : function ( fm_class /* Fieldmapper class hint */, opts /* Option hash */) {
96             var pkey = fieldmapper[fm_class].Identifier;
97
98             var order_by = {};
99             if (opts.order_by) order_by.order_by = opts.order_by;
100             if (opts.select) order_by.select = opts.select;
101
102             var search = {};
103             search[pkey] = { '!=' : null };
104
105             var req_hash = dojo.mixin(
106                 opts, 
107                 { method : 'open-ils.pcrud.search.' + fm_class + '.atomic',
108                   params : [ this.auth(), search, order_by ]
109                 }
110             );
111
112             if (!opts.async && !opts.timeout) req_hash.timeout = 10;
113
114             var _pcrud = this;
115             var req = this.session.request( req_hash );
116
117             if (!req.onerror)
118                 req.onerror = function (r) { throw js2JSON(r); };
119
120             if (!req.oncomplete)
121                 req.oncomplete = function (r) { r.result = r.recv(); _pcrud.last_result = r.result; };
122
123             req.send();
124
125             if (req_hash.timeout) return req.result.content();
126             return req;
127         },
128
129         search : function ( fm_class /* Fieldmapper class hint */, search /* Fieldmapper query object */, opts /* Option hash */) {
130             var order_by = {};
131             if (opts.order_by) order_by.order_by = opts.order_by;
132             if (opts.select) order_by.select = opts.select;
133
134             var req_hash = dojo.mixin(
135                 opts, 
136                 { method : 'open-ils.pcrud.search.' + fm_class + '.atomic',
137                   params : [ this.auth(), search, order_by ]
138                 }
139             );
140
141             if (!opts.async && !opts.timeout) req_hash.timeout = 10;
142
143             var _pcrud = this;
144             var req = this.session.request( req_hash );
145
146             if (!req.onerror)
147                 req.onerror = function (r) { throw js2JSON(r); };
148
149             if (!req.oncomplete)
150                 req.oncomplete = function (r) { r.result = r.recv(); _pcrud.last_result = r.result; };
151
152             req.send();
153
154             if (req_hash.timeout) return req.result.content();
155             return req;
156         },
157
158         _CUD : function ( method /* 'create' or 'update' or 'delete' */, list /* Fieldmapper object */, opts /* Option hash */) {
159
160             if (dojo.isArray(list)) {
161                 if (list.classname) list = [ list ];
162             } else {
163                 list = [ list ];
164             }
165
166             if (!this.connected) this.connect();
167
168             var _pcrud = this;
169
170             function _CUD_recursive ( obj_list, pos, final_complete, final_error ) {
171                 var obj = obj_list[pos];
172                 var req_hash = {
173                     method : 'open-ils.pcrud.' + method + '.' + obj.classname,
174                     params : [ _pcrud.auth(), obj ],
175                     onerror : final_error || function (r) { _pcrud.disconnect(); throw '_CUD: Error creating, deleting or updating ' + js2JSON(obj); }
176                 };
177
178                 var req = _pcrud.session.request( req_hash );
179                 req._final_complete = final_complete;
180                 req._final_error = final_error;
181
182                 if (++pos == obj_list.length) {
183                     req.oncomplete = function (r) {
184
185                         _pcrud.session.request({
186                             method : 'open-ils.pcrud.transaction.commit',
187                             timeout : 10,
188                             params : [ ses ],
189                             onerror : function (r) {
190                                 _pcrud.disconnect();
191                                 throw 'Transaction commit error';
192                             },      
193                             oncomplete : function (r) {
194                                 var res = r.recv();
195                                 if ( res && res.content() ) {
196                                     _auto_CUD_recursive( list, 0 );
197                                 } else {
198                                     _pcrud.disconnect();
199                                     throw 'Transaction commit error';
200                                 }
201                             },
202                         }).send();
203
204                         if (r._final_complete) r._final_complete(r);
205                         _pcrud.disconnect();
206                     };
207
208                     req.onerror = function (r) {
209                         if (r._final_error) r._final_error(r);
210                         _pcrud.disconnect();
211                     };
212
213                 } else {
214                     req._pos = pos;
215                     req._obj_list = obj_list;
216                     req.oncomplete = function (r) {
217                         var res = r.recv();
218                         if ( res && res.content() ) {
219                             _CUD_recursive( r._obj_list, r._pos, r._final_complete );
220                         } else {
221                             _pcrud.disconnect();
222                             throw '_CUD: Error creating, deleting or updating ' + js2JSON(obj);
223                         }
224                     };
225                 }
226
227                 req.send();
228             }
229
230             var f_complete = opts.oncomplete;
231             var f_error = opts.onerror;
232
233             this.session.request({
234                 method : 'open-ils.pcrud.transaction.begin',
235                 timeout : 10,
236                 params : [ ses ],
237                 onerror : function (r) {
238                     _pcrud.disconnect();
239                     throw 'Transaction begin error';
240                 },      
241                 oncomplete : function (r) {
242                     var res = r.recv();
243                     if ( res && res.content() ) {
244                         _CUD_recursive( list, 0, f_complete, f_error );
245                     } else {
246                         _pcrud.disconnect();
247                         throw 'Transaction begin error';
248                     }
249                 },
250             }).send();
251         },
252
253         create : function ( list, opts ) {
254             this._CUD( 'create', list, opts );
255         },
256
257         update : function ( list, opts ) {
258             this._CUD( 'update', list, opts );
259         },
260
261         delete : function ( list, opts ) {
262             this._CUD( 'delete', list, opts );
263         },
264
265         apply : function ( list, opts ) {
266             this._auto_CUD( list, opts );
267         },
268
269         _auto_CUD : function ( list /* Fieldmapper object */, opts /* Option hash */) {
270
271             if (dojo.isArray(list)) {
272                 if (list.classname) list = [ list ];
273             } else {
274                 list = [ list ];
275             }
276
277             if (!this.connected) this.connect();
278
279             var _pcrud = this;
280
281             function _auto_CUD_recursive ( obj_list, pos, final_complete, final_error ) {
282                 var obj = obj_list[pos];
283
284                 var method;
285                 if (obj.ischanged()) method = 'update';
286                 if (obj.isnew())     method = 'create';
287                 if (obj.isdeleted()) method = 'delete';
288                 if (!method) throw 'No action detected';
289
290                 var req_hash = {
291                     method : 'open-ils.pcrud.' + method + '.' + obj.classname,
292                     timeout : 10,
293                     params : [ _pcrud.auth(), obj ],
294                     onerror : final_error || function (r) { _pcrud.disconnect(); throw '_auto_CUD: Error creating, deleting or updating ' + js2JSON(obj); }
295                 };
296
297                 var req = _pcrud.session.request( req_hash );
298                 req._final_complete = final_complete;
299                 req._final_error = final_error;
300
301                 if (++pos == obj_list.length) {
302                     req.oncomplete = function (r) {
303
304                         _pcrud.session.request({
305                             method : 'open-ils.pcrud.transaction.commit',
306                             timeout : 10,
307                             params : [ ses ],
308                             onerror : function (r) {
309                                 _pcrud.disconnect();
310                                 throw 'Transaction commit error';
311                             },      
312                             oncomplete : function (r) {
313                                 var res = r.recv();
314                                 if ( res && res.content() ) {
315                                     _auto_CUD_recursive( list, 0 );
316                                 } else {
317                                     _pcrud.disconnect();
318                                     throw 'Transaction commit error';
319                                 }
320                             },
321                         }).send();
322
323                         if (r._final_complete) r._final_complete(r);
324                         _pcrud.disconnect();
325                     };
326
327                     req.onerror = function (r) {
328                         if (r._final_error) r._final_error(r);
329                         _pcrud.disconnect();
330                     };
331
332                 } else {
333                     req._pos = pos;
334                     req._obj_list = obj_list;
335                     req.oncomplete = function (r) {
336                         var res = r.recv();
337                         if ( res && res.content() ) {
338                             _auto_CUD_recursive( r._obj_list, r._pos, r._final_complete, r._final_error );
339                         } else {
340                             _pcrud.disconnect();
341                             throw '_auto_CUD: Error creating, deleting or updating ' + js2JSON(obj);
342                         }
343                     };
344                 }
345
346                 req.send();
347             }
348
349             var f_complete = opts.oncomplete;
350             var f_error = opts.onerror;
351
352             this.session.request({
353                 method : 'open-ils.pcrud.transaction.begin',
354                 timeout : 10,
355                 params : [ ses ],
356                 onerror : function (r) {
357                     _pcrud.disconnect();
358                     throw 'Transaction begin error';
359                 },      
360                 oncomplete : function (r) {
361                     var res = r.recv();
362                     if ( res && res.content() ) {
363                         _auto_CUD_recursive( list, 0, f_complete, f_error );
364                     } else {
365                         _pcrud.disconnect();
366                         throw 'Transaction begin error';
367                     }
368                 },
369             }).send();
370         }
371
372     });
373 }
374
375