]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/PermaCrud.js
initial refactoring and bug fixes
[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             var _pcrud = this;
78             var req = this.session.request( req_hash );
79
80             if (!req.onerror)
81                 req.onerror = function (r) { throw js2JSON(r); };
82
83             if (!req.oncomplete)
84                 req.oncomplete = function (r) { r.result = r.recv(); _pcrud.last_result = r.result; };
85
86             req.send();
87
88             return req;
89             },
90
91             retrieveAll : function ( fm_class /* Fieldmapper class hint */, opts /* Option hash */) {
92             var pkey = fieldmapper[fm_class].Identifier;
93
94             var order_by = {};
95             if (opts.order_by) order_by.order_by = opts.order_by;
96             if (opts.select) order_by.select = opts.select;
97
98             var search = {};
99             search[pkey] = { '!=' : null };
100
101             var req_hash = dojo.mixin(
102                 opts, 
103                 { method : 'open-ils.pcrud.search.' + fm_class + '.atomic',
104                   params : [ this.auth(), search, order_by ]
105                 }
106             );
107
108             var _pcrud = this;
109             var req = this.session.request( req_hash );
110
111             if (!req.onerror)
112                 req.onerror = function (r) { throw js2JSON(r); };
113
114             if (!req.oncomplete)
115                 req.oncomplete = function (r) { r.result = r.recv(); _pcrud.last_result = r.result; };
116
117             req.send();
118
119             return req;
120             },
121
122             search : function ( fm_class /* Fieldmapper class hint */, search /* Fieldmapper query object */, opts /* Option hash */) {
123             var order_by = {};
124             if (opts.order_by) order_by.order_by = opts.order_by;
125             if (opts.select) order_by.select = opts.select;
126
127             var req_hash = dojo.mixin(
128                 opts, 
129                 { method : 'open-ils.pcrud.search.' + fm_class + '.atomic',
130                   params : [ this.auth(), search, order_by ]
131                 }
132             );
133
134             var _pcrud = this;
135             var req = this.session.request( req_hash );
136
137             if (!req.onerror)
138                 req.onerror = function (r) { throw js2JSON(r); };
139
140             if (!req.oncomplete)
141                 req.oncomplete = function (r) { r.result = r.recv(); _pcrud.last_result = r.result; };
142
143             req.send();
144
145             return req;
146             },
147
148         _CUD : function ( method /* 'create' or 'update' or 'delete' */, list /* Fieldmapper object */, opts /* Option hash */) {
149
150             if (dojo.isArray(list)) {
151                 if (list.classname) list = [ list ];
152             } else {
153                 list = [ list ];
154             }
155
156             if (!this.connected) this.connect();
157
158             var _pcrud = this;
159
160             function _CUD_recursive ( obj_list, pos, final_complete, final_error ) {
161                 var obj = obj_list[pos];
162                 var req_hash = {
163                     method : 'open-ils.pcrud.' + method + '.' + obj.classname,
164                     params : [ _pcrud.auth(), obj ],
165                     onerror : final_error || function (r) { _pcrud.disconnect(); throw '_CUD: Error creating, deleting or updating ' + js2JSON(obj); }
166                 };
167
168                 var req = _pcrud.session.request( req_hash );
169                 req._final_complete = final_complete;
170                 req._final_error = final_error;
171
172                 if (++pos == obj_list.length) {
173                     req.oncomplete = function (r) {
174
175                         _pcrud.session.request({
176                             method : 'open-ils.pcrud.transaction.commit',
177                             timeout : 10,
178                             params : [ ses ],
179                             onerror : function (r) {
180                                 _pcrud.disconnect();
181                                 throw 'Transaction commit error';
182                             },      
183                             oncomplete : function (r) {
184                                 var res = r.recv();
185                                 if ( res && res.content() ) {
186                                     _auto_CUD_recursive( list, 0 );
187                                 } else {
188                                     _pcrud.disconnect();
189                                     throw 'Transaction commit error';
190                                 }
191                             },
192                         }).send();
193
194                         if (r._final_complete) r._final_complete(r);
195                         _pcrud.disconnect();
196                     };
197
198                     req.onerror = function (r) {
199                         if (r._final_error) r._final_error(r);
200                         _pcrud.disconnect();
201                     };
202
203                 } else {
204                     req._pos = pos;
205                     req._obj_list = obj_list;
206                     req.oncomplete = function (r) {
207                         var res = r.recv();
208                         if ( res && res.content() ) {
209                             _CUD_recursive( r._obj_list, r._pos, r._final_complete );
210                         } else {
211                             _pcrud.disconnect();
212                             throw '_CUD: Error creating, deleting or updating ' + js2JSON(obj);
213                         }
214                     };
215                 }
216
217                 req.send();
218             }
219
220             var f_complete = opts.oncomplete;
221             var f_error = opts.onerror;
222
223             this.session.request({
224                 method : 'open-ils.pcrud.transaction.begin',
225                 timeout : 10,
226                 params : [ ses ],
227                 onerror : function (r) {
228                     _pcrud.disconnect();
229                     throw 'Transaction begin error';
230                 },      
231                 oncomplete : function (r) {
232                     var res = r.recv();
233                     if ( res && res.content() ) {
234                         _CUD_recursive( list, 0, f_complete, f_error );
235                     } else {
236                         _pcrud.disconnect();
237                         throw 'Transaction begin error';
238                     }
239                 },
240                 }).send();
241         },
242
243         create : function ( list, opts ) {
244             this._CUD( 'create', list, opts );
245         },
246
247         update : function ( list, opts ) {
248             this._CUD( 'update', list, opts );
249         },
250
251         delete : function ( list, opts ) {
252             this._CUD( 'delete', list, opts );
253         },
254
255         apply : function ( list, opts ) {
256             this._auto_CUD( list, opts );
257         },
258
259         _auto_CUD : function ( list /* Fieldmapper object */, opts /* Option hash */) {
260
261             if (dojo.isArray(list)) {
262                 if (list.classname) list = [ list ];
263             } else {
264                 list = [ list ];
265             }
266
267             if (!this.connected) this.connect();
268
269             var _pcrud = this;
270
271             function _auto_CUD_recursive ( obj_list, pos, final_complete, final_error ) {
272                 var obj = obj_list[pos];
273
274                 var method;
275                 if (obj.ischanged()) method = 'update';
276                 if (obj.isnew())     method = 'create';
277                 if (obj.isdeleted()) method = 'delete';
278                 if (!method) throw 'No action detected';
279
280                 var req_hash = {
281                     method : 'open-ils.pcrud.' + method + '.' + obj.classname,
282                     timeout : 10,
283                     params : [ _pcrud.auth(), obj ],
284                     onerror : final_error || function (r) { _pcrud.disconnect(); throw '_auto_CUD: Error creating, deleting or updating ' + js2JSON(obj); }
285                 };
286
287                 var req = _pcrud.session.request( req_hash );
288                 req._final_complete = final_complete;
289                 req._final_error = final_error;
290
291                 if (++pos == obj_list.length) {
292                     req.oncomplete = function (r) {
293
294                         _pcrud.session.request({
295                             method : 'open-ils.pcrud.transaction.commit',
296                             timeout : 10,
297                             params : [ ses ],
298                             onerror : function (r) {
299                                 _pcrud.disconnect();
300                                 throw 'Transaction commit error';
301                             },      
302                             oncomplete : function (r) {
303                                 var res = r.recv();
304                                 if ( res && res.content() ) {
305                                     _auto_CUD_recursive( list, 0 );
306                                 } else {
307                                     _pcrud.disconnect();
308                                     throw 'Transaction commit error';
309                                 }
310                             },
311                         }).send();
312
313                         if (r._final_complete) r._final_complete(r);
314                         _pcrud.disconnect();
315                     };
316
317                     req.onerror = function (r) {
318                         if (r._final_error) r._final_error(r);
319                         _pcrud.disconnect();
320                     };
321
322                 } else {
323                     req._pos = pos;
324                     req._obj_list = obj_list;
325                     req.oncomplete = function (r) {
326                         var res = r.recv();
327                         if ( res && res.content() ) {
328                             _auto_CUD_recursive( r._obj_list, r._pos, r._final_complete, r._final_error );
329                         } else {
330                             _pcrud.disconnect();
331                             throw '_auto_CUD: Error creating, deleting or updating ' + js2JSON(obj);
332                         }
333                     };
334                 }
335
336                 req.send();
337             }
338
339             var f_complete = opts.oncomplete;
340             var f_error = opts.onerror;
341
342             this.session.request({
343                 method : 'open-ils.pcrud.transaction.begin',
344                 timeout : 10,
345                 params : [ ses ],
346                 onerror : function (r) {
347                     _pcrud.disconnect();
348                     throw 'Transaction begin error';
349                 },      
350                 oncomplete : function (r) {
351                     var res = r.recv();
352                     if ( res && res.content() ) {
353                         _auto_CUD_recursive( list, 0, f_complete, f_error );
354                     } else {
355                         _pcrud.disconnect();
356                         throw 'Transaction begin error';
357                     }
358                 },
359                 }).send();
360         }
361
362     });
363 }
364
365