]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/services/lovefield.js
LP#1706124: Make include inactive patrons checkbox sticky
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / services / lovefield.js
1 var osb = lf.schema.create('offline', 2);
2
3 osb.createTable('Object').
4     addColumn('type', lf.Type.STRING).          // class hint
5     addColumn('id', lf.Type.STRING).           // obj id
6     addColumn('object', lf.Type.OBJECT).
7     addPrimaryKey(['type','id']);
8
9 osb.createTable('CacheDate').
10     addColumn('type', lf.Type.STRING).          // class hint
11     addColumn('cachedate', lf.Type.DATE_TIME).  // when was it last updated
12     addPrimaryKey(['type']);
13
14 osb.createTable('Setting').
15     addColumn('name', lf.Type.STRING).
16     addColumn('value', lf.Type.STRING).
17     addPrimaryKey(['name']);
18
19 osb.createTable('StatCat').
20     addColumn('id', lf.Type.INTEGER).
21     addColumn('value', lf.Type.OBJECT).
22     addPrimaryKey(['id']);
23
24 osb.createTable('OfflineXact').
25     addColumn('seq', lf.Type.INTEGER).
26     addColumn('value', lf.Type.OBJECT).
27     addPrimaryKey(['seq'], true);
28
29 osb.createTable('OfflineBlocks').
30     addColumn('barcode', lf.Type.STRING).
31     addColumn('reason', lf.Type.STRING).
32     addPrimaryKey(['barcode']);
33
34 lf.connecting = true;
35 osb.connect().then(function (db) {
36     lf.offlineDB = db;
37     lf.connecting = false;
38 });
39
40 /**
41  * Core Service - egLovefield
42  *
43  * Lovefield wrapper factory for low level offline stuff
44  *
45  */
46 angular.module('egCoreMod')
47
48 .factory('egLovefield', ['$q','$rootScope','egCore','$timeout', 
49                  function($q , $rootScope , egCore , $timeout) { 
50     
51     var service = {};
52
53     function connectOrGo (resolver) {
54         if (lf.offlineDB) {
55             return resolver();
56         }
57
58         // apparently, this might take a while...
59         if (lf.connecting) return $timeout(function() {
60                 return connectOrGo(resolver);
61         });
62
63         console.log('egLovefield connecting to offline DB');
64
65         try {
66             return osb.connect().then(function (db) {
67                 lf.offlineDB = db;
68                 return resolver();
69             });
70         } catch (err) {
71                 alert('attempted reconnect failure: ' + err.toString());
72         }
73     }
74
75     service.isCacheGood = function (type) {
76
77         return connectOrGo(function() {
78             var cacheDate = lf.offlineDB.getSchema().table('CacheDate');
79
80             return lf.offlineDB.
81                 select(cacheDate.cachedate).
82                 from(cacheDate).
83                 where(cacheDate.type.eq(type)).
84                 exec().then(function(results) {
85                     if (results.length == 0) {
86                         return $q.when(false);
87                     }
88
89                     var now = new Date();
90     
91                     // hard-coded 1 day offline cache timeout
92                     return $q.when((now.getTime() - results[0]['cachedate'].getTime()) <= 86400000);
93                 })
94         });
95     }
96
97     service.destroyPendingOfflineXacts = function () {
98         return connectOrGo(function() {
99             var table = lf.offlineDB.getSchema().table('OfflineXact');
100             return lf.offlineDB.
101                 delete().
102                 from(table).
103                 exec();
104         });
105     }
106
107     service.havePendingOfflineXacts = function () {
108         return connectOrGo(function() {
109             var table = lf.offlineDB.getSchema().table('OfflineXact');
110             return lf.offlineDB.
111                 select(table.reason).
112                 from(table).
113                 exec().
114                 then(function(list) {
115                     return $q.when(Boolean(list.length > 0))
116                 });
117         });
118     }
119
120     service.retrievePendingOfflineXacts = function () {
121         return connectOrGo(function() {
122             var table = lf.offlineDB.getSchema().table('OfflineXact');
123             return lf.offlineDB.
124                 select(table.value).
125                 from(table).
126                 exec().
127                 then(function(list) {
128                     return $q.when(list.map(function(x) { return x.value }))
129                 });
130         });
131     }
132
133     service.destroyOfflineBlocks = function () {
134         return connectOrGo(function() {
135             var table = lf.offlineDB.getSchema().table('OfflineBlocks');
136             return $q.when(
137                 lf.offlineDB.
138                     delete().
139                     from(table).
140                     exec()
141             );
142         });
143     }
144
145     service.addOfflineBlock = function (barcode, reason) {
146         return connectOrGo(function() {
147             var table = lf.offlineDB.getSchema().table('OfflineBlocks');
148             return $q.when(
149                 lf.offlineDB.
150                     insertOrReplace().
151                     into(table).
152                     values([ table.createRow({ barcode : barcode, reason : reason }) ]).
153                     exec()
154             );
155         });
156     }
157
158     // Returns a promise with true for blocked, false for not blocked
159     service.testOfflineBlock = function (barcode) {
160         return connectOrGo(function() {
161             var table = lf.offlineDB.getSchema().table('OfflineBlocks');
162             return lf.offlineDB.
163                 select(table.reason).
164                 from(table).
165                 where(table.barcode.eq(barcode)).
166                 exec().then(function(list) {
167                     if(list.length > 0) return $q.when(list[0].reason);
168                     return $q.when(null);
169                 });
170         });
171     }
172
173     service.addOfflineXact = function (obj) {
174         return connectOrGo(function() {
175             var table = lf.offlineDB.getSchema().table('OfflineXact');
176             return $q.when(
177                 lf.offlineDB.
178                     insertOrReplace().
179                     into(table).
180                     values([ table.createRow({ value : obj }) ]).
181                     exec()
182             );
183         });
184     }
185
186     service.setStatCatsCache = function (statcats) {
187         if (lf.isOffline) return $q.when();
188
189         return connectOrGo(function() {
190             var table = lf.offlineDB.getSchema().table('StatCat');
191             var rlist = [];
192
193             angular.forEach(statcats, function (val) {
194                 rlist.push(table.createRow({
195                     id    : val.id(),
196                     value : egCore.idl.toHash(val)
197                 }));
198             });
199             return lf.offlineDB.
200                 insertOrReplace().
201                 into(table).
202                 values(rlist).
203                 exec();
204         });
205     }
206
207     service.getStatCatsCache = function () {
208         return connectOrGo(function() {
209
210             var table = lf.offlineDB.getSchema().table('StatCat');
211             var result = [];
212             return lf.offlineDB.
213                 select(table.value).
214                 from(table).
215                 exec().then(function(list) {
216                     angular.forEach(list, function (s) {
217                         var sc = egCore.idl.fromHash('actsc', s.value);
218     
219                         if (angular.isArray(sc.default_entries())) {
220                             sc.default_entries(
221                                 sc.default_entries().map( function (k) {
222                                     return egCore.idl.fromHash('actsced', k);
223                                 })
224                             );
225                         }
226     
227                         if (angular.isArray(sc.entries())) {
228                             sc.entries(
229                                 sc.entries().map( function (k) {
230                                     return egCore.idl.fromHash('actsce', k);
231                                 })
232                             );
233                         }
234     
235                         result.push(sc);
236                     });
237                     return $q.when(result);
238                 });
239     
240         });
241     }
242
243     service.setSettingsCache = function (settings) {
244         if (lf.isOffline) return $q.when();
245
246         return connectOrGo(function() {
247
248             var table = lf.offlineDB.getSchema().table('Setting');
249             var rlist = [];
250
251             angular.forEach(settings, function (val, key) {
252                 rlist.push(
253                     table.createRow({
254                         name  : key,
255                         value : JSON.stringify(val)
256                     })
257                 );
258             });
259
260             return lf.offlineDB.
261                 insertOrReplace().
262                 into(table).
263                 values(rlist).
264                 exec();
265         });
266     }
267
268     service.getSettingsCache = function (settings) {
269         return connectOrGo(function() {
270
271             var table = lf.offlineDB.getSchema().table('Setting');
272
273             var search_pred = table.name.isNotNull();
274             if (settings && settings.length) {
275                 search_pred = table.name.in(settings);
276             }
277                 
278             return lf.offlineDB.
279                 select(table.name, table.value).
280                 from(table).
281                 where(search_pred).
282                 exec().then(function(list) {
283                     angular.forEach(list, function (s) {
284                         s.value = JSON.parse(s.value)
285                     });
286                     return $q.when(list);
287                 });
288         });
289     }
290
291     service.setListInOfflineCache = function (type, list) {
292         if (lf.isOffline) return $q.when();
293
294         return connectOrGo(function() {
295
296             service.isCacheGood(type).then(function(good) {
297                 if (!good) {
298                     var object = lf.offlineDB.getSchema().table('Object');
299                     var cacheDate = lf.offlineDB.getSchema().table('CacheDate');
300                     var pkey = egCore.idl.classes[type].pkey;
301         
302                     angular.forEach(list, function(item) {
303                         var row = object.createRow({
304                             type    : type,
305                             id      : '' + item[pkey](),
306                             object  : egCore.idl.toHash(item)
307                         });
308                         lf.offlineDB.insertOrReplace().into(object).values([row]).exec();
309                     });
310         
311                     var row = cacheDate.createRow({
312                         type      : type,
313                         cachedate : new Date()
314                     });
315         
316                     console.log('egLovefield saving ' + type + ' list');
317                     lf.offlineDB.insertOrReplace().into(cacheDate).values([row]).exec();
318                 }
319             })
320         });
321     }
322
323     service.getListFromOfflineCache = function(type) {
324         return connectOrGo(function() {
325
326             var object = lf.offlineDB.getSchema().table('Object');
327
328             return lf.offlineDB.
329                 select(object.object).
330                 from(object).
331                 where(object.type.eq(type)).
332                 exec().then(function(results) {
333                     return $q.when(results.map(function(item) {
334                         return egCore.idl.fromHash(type,item['object'])
335                     }));
336                 });
337         });
338     }
339
340     service.reconstituteList = function(type) {
341         if (lf.isOffline) {
342             console.log('egLovefield reading ' + type + ' list');
343             return service.getListFromOfflineCache(type).then(function (list) {
344                 egCore.env.absorbList(list, type, true)
345                 return $q.when(true);
346             });
347         }
348         return $q.when(false);
349     }
350
351     service.reconstituteTree = function(type) {
352         if (lf.isOffline) {
353             console.log('egLovefield reading ' + type + ' tree');
354
355             var pkey = egCore.idl.classes[type].pkey;
356             var parent_field = 'parent';
357
358             if (type == 'aou') {
359                 parent_field = 'parent_ou';
360             }
361
362             return service.getListFromOfflineCache(type).then(function (list) {
363                 var hash = {};
364                 var top = null;
365                 angular.forEach(list, function (item) {
366
367                     // Special case for aou, to reconstitue ou_type
368                     if (type == 'aou') {
369                         if (item.ou_type()) {
370                             item.ou_type( egCore.idl.fromHash('aout', item.ou_type()) );
371                         }
372                     }
373
374                     hash[''+item[pkey]()] = item;
375                     if (!item[parent_field]()) {
376                         top = item;
377                     } else if (angular.isObject(item[parent_field]())) {
378                         // un-objectify the parent
379                         item[parent_field](
380                             item[parent_field]()[pkey]()
381                         );
382                     }
383                 });
384
385                 angular.forEach(list, function (item) {
386                     item.children([]); // just clear it out if there's junk in there
387
388                     if (item[parent_field]()) {
389                         item[parent_field]( hash[''+item[parent_field]()] );
390                     }
391
392                     item.children( list.filter(function (kid) {
393                         return kid[parent_field]() == item[pkey]();
394                     }) );
395                 });
396
397                 egCore.env.absorbTree(top, type, true)
398                 return $q.when(true)
399             });
400         }
401         return $q.when(false);
402     }
403
404     return service;
405 }]);
406