1 /* ---------------------------------------------------------------------------
2 * Copyright (C) 2008 Equinox Software, Inc
3 * Mike Rylander <miker@esilibrary.com>
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.
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 * ---------------------------------------------------------------------------
17 if(!dojo._hasResource["openils.PermaCrud"]) {
19 dojo._hasResource["openils.PermaCrud"] = true;
20 dojo.provide("openils.PermaCrud");
21 dojo.require("fieldmapper.Fieldmapper");
22 dojo.require("openils.User");
24 dojo.declare('openils.PermaCrud', null, {
30 constructor : function ( kwargs ) {
31 kwargs = kwargs || {};
33 this.authtoken = kwargs.authtoken;
37 new OpenSRF.ClientSession('open-ils.pcrud');
41 this.session.state == OSRF_APP_SESSION_CONNECTED
42 ) this.connected = true;
45 auth : function (token) {
46 if (token) this.authtoken = token;
47 return this.authtoken || openils.User.authtoken;
50 connect : function ( onerror ) {
51 if (!this.connected && !this.session.connect()) {
52 this.connected = false;
53 if (onerror) onerror(this.session);
56 this.connected = true;
60 disconnect : function ( onerror ) {
61 if (!this.session.disconnect()) {
62 if (onerror) onerror(this.session);
69 retrieve : function ( fm_class /* Fieldmapper class hint */, id /* Fieldmapper object primary key value */, opts /* Option hash */) {
71 var req_hash = dojo.mixin(
73 { method : 'open-ils.pcrud.retrieve.' + fm_class,
74 params : [ this.auth(), id ]
78 if (!opts.async && !opts.timeout) req_hash.timeout = 10;
81 var req = this.session.request( req_hash );
84 req.onerror = function (r) { throw js2JSON(r); };
86 // if it's an async call and the user does not care about
87 // the responses, pull them off the network and discard them
88 if (!req_hash.timeout && !req.oncomplete)
89 req.oncomplete = function (r) { while(r.recv()){}; };
93 // for synchronous calls with no handlers, return the first received value
94 if (req_hash.timeout && !opts.oncomplete && !opts.onresponse) {
95 var resp = req.recv();
96 if(resp) return resp.content();
103 retrieveAll : function ( fm_class /* Fieldmapper class hint */, opts /* Option hash */) {
104 var pkey = fieldmapper[fm_class].Identifier;
108 if (opts.order_by) order_by.order_by = opts.order_by;
109 if (opts.select) order_by.select = opts.select;
111 var method = 'open-ils.pcrud.search.' + fm_class;
112 if(!opts.streaming) method += '.atomic';
115 search[pkey] = { '!=' : null };
117 var req_hash = dojo.mixin(
120 params : [ this.auth(), search, order_by ]
124 if (!opts.async && !opts.timeout) req_hash.timeout = 10;
127 var req = this.session.request( req_hash );
130 req.onerror = function (r) { throw js2JSON(r); };
132 // if it's an async call and the user does not care about
133 // the responses, pull them off the network and discard them
134 if (!req_hash.timeout && !req.oncomplete)
135 req.oncomplete = function (r) { while(r.recv()){}; };
139 // for synchronous calls with no handlers, return the first received value
140 if (req_hash.timeout && !opts.oncomplete && !opts.onresponse) {
141 var resp = req.recv();
142 if(resp) return resp.content();
149 search : function ( fm_class /* Fieldmapper class hint */, search /* Fieldmapper query object */, opts /* Option hash */) {
152 if (opts.order_by) order_by.order_by = opts.order_by;
153 if (opts.select) order_by.select = opts.select;
155 var method = 'open-ils.pcrud.search.' + fm_class;
156 if(!opts.streaming) method += '.atomic';
158 var req_hash = dojo.mixin(
161 params : [ this.auth(), search, order_by ]
165 if (!opts.async && !opts.timeout) req_hash.timeout = 10;
168 var req = this.session.request( req_hash );
171 req.onerror = function (r) { throw js2JSON(r); };
173 // if it's an async call and the user does not care about
174 // the responses, pull them off the network and discard them
175 if (!req_hash.timeout && !req.oncomplete)
176 req.oncomplete = function (r) { while(r.recv()){}; };
180 // for synchronous calls with no handlers, return the first received value
181 if (req_hash.timeout && !opts.oncomplete && !opts.onresponse) {
182 var resp = req.recv();
183 if(resp) return resp.content();
190 _CUD : function ( method /* 'create' or 'update' or 'delete' */, list /* Fieldmapper object */, opts /* Option hash */) {
193 if (dojo.isArray(list)) {
194 if (list.classname) list = [ list ];
199 if (!this.connected) this.connect();
203 function _CUD_recursive ( obj_list, pos, final_complete, final_error ) {
204 var obj = obj_list[pos];
206 method : 'open-ils.pcrud.' + method + '.' + obj.classname,
207 params : [ _pcrud.auth(), obj ],
208 onerror : final_error || function (r) { _pcrud.disconnect(); throw '_CUD: Error creating, deleting or updating ' + js2JSON(obj); }
211 var req = _pcrud.session.request( req_hash );
212 req._final_complete = final_complete;
213 req._final_error = final_error;
215 if (++pos == obj_list.length) {
216 req.oncomplete = function (r) {
218 _pcrud.session.request({
219 method : 'open-ils.pcrud.transaction.commit',
221 params : [ _pcrud.auth() ],
222 onerror : function (r) {
224 throw 'Transaction commit error';
226 oncomplete : function (r) {
228 if ( res && res.content() ) {
229 if(req._final_complete)
230 req._final_complete(req);
234 throw 'Transaction commit error';
240 req.onerror = function (r) {
241 if (r._final_error) r._final_error(r);
247 req._obj_list = obj_list;
248 req.oncomplete = function (r) {
250 if ( res && res.content() ) {
251 _CUD_recursive( r._obj_list, r._pos, r._final_complete );
254 throw '_CUD: Error creating, deleting or updating ' + js2JSON(obj);
262 var f_complete = opts.oncomplete;
263 var f_error = opts.onerror;
265 this.session.request({
266 method : 'open-ils.pcrud.transaction.begin',
268 params : [ _pcrud.auth() ],
269 onerror : function (r) {
271 throw 'Transaction begin error';
273 oncomplete : function (r) {
275 if ( res && res.content() ) {
276 _CUD_recursive( list, 0, f_complete, f_error );
279 throw 'Transaction begin error';
285 create : function ( list, opts ) {
286 this._CUD( 'create', list, opts );
289 update : function ( list, opts ) {
290 this._CUD( 'update', list, opts );
293 delete : function ( list, opts ) {
294 this._CUD( 'delete', list, opts );
297 apply : function ( list, opts ) {
298 this._auto_CUD( list, opts );
301 _auto_CUD : function ( list /* Fieldmapper object */, opts /* Option hash */) {
305 if (dojo.isArray(list)) {
306 if (list.classname) list = [ list ];
311 if (!this.connected) this.connect();
315 function _auto_CUD_recursive ( obj_list, pos, final_complete, final_error ) {
316 var obj = obj_list[pos];
319 if (obj.ischanged()) method = 'update';
320 if (obj.isnew()) method = 'create';
321 if (obj.isdeleted()) method = 'delete';
322 if (!method) throw 'No action detected';
325 method : 'open-ils.pcrud.' + method + '.' + obj.classname,
327 params : [ _pcrud.auth(), obj ],
328 onerror : final_error || function (r) { _pcrud.disconnect(); throw '_auto_CUD: Error creating, deleting or updating ' + js2JSON(obj); }
331 var req = _pcrud.session.request( req_hash );
332 req._final_complete = final_complete;
333 req._final_error = final_error;
335 if (++pos == obj_list.length) {
336 req.oncomplete = function (r) {
338 _pcrud.session.request({
339 method : 'open-ils.pcrud.transaction.commit',
341 params : [ _pcrud.auth() ],
342 onerror : function (r) {
344 throw 'Transaction commit error';
346 oncomplete : function (r) {
348 if ( res && res.content() ) {
349 _auto_CUD_recursive( list, 0 );
352 throw 'Transaction commit error';
357 if (r._final_complete) r._final_complete(r);
361 req.onerror = function (r) {
362 if (r._final_error) r._final_error(r);
368 req._obj_list = obj_list;
369 req.oncomplete = function (r) {
371 if ( res && res.content() ) {
372 _auto_CUD_recursive( r._obj_list, r._pos, r._final_complete, r._final_error );
375 throw '_auto_CUD: Error creating, deleting or updating ' + js2JSON(obj);
383 var f_complete = opts.oncomplete;
384 var f_error = opts.onerror;
386 this.session.request({
387 method : 'open-ils.pcrud.transaction.begin',
389 params : [ _pcrud.auth() ],
390 onerror : function (r) {
392 throw 'Transaction begin error';
394 oncomplete : function (r) {
396 if ( res && res.content() ) {
397 _auto_CUD_recursive( list, 0, f_complete, f_error );
400 throw 'Transaction begin error';