Merge branch 'tizen_4.0' into tizen_5.0
[platform/core/api/webapi-plugins.git] / src / datacontrol / datacontrol_api.js
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 var validator_ = xwalk.utils.validator;
18 var converter_ = xwalk.utils.converter;
19 var types_ = validator_.Types;
20 var type_ = xwalk.utils.type;
21 var native_ = new xwalk.utils.NativeManager(extension);
22
23 var DATA_CONTROL_MANAGER_LISTENER_ID = 'DataControlManagerChangeCallback';
24
25 var DataType = {
26     MAP: 'MAP',
27     SQL: 'SQL'
28 };
29
30 var DataControlListenersManager = (function() {
31     function changeEvent(event) {
32         var successCallback;
33
34         if (DataType.SQL === event.type.substr(0, 3)) {
35             if (type_.isEmptyObject(this._SQLDataControlCbMap)) {
36                 return;
37             }
38             for (var listenerId in this._SQLDataControlCbMap) {
39                 if (this._SQLDataControlCbMap.hasOwnProperty(listenerId)) {
40                     if (
41                         this._SQLDataControlCbMap[listenerId].providerId ===
42                             event.providerId &&
43                         this._SQLDataControlCbMap[listenerId].dataId === event.dataId
44                     ) {
45                         successCallback = this._SQLDataControlCbMap[listenerId]
46                             .changeCallback;
47                         if (type_.isFunction(successCallback)) {
48                             successCallback(event.type, {
49                                 columns: event.columns,
50                                 values: event.values
51                             });
52                         }
53                     }
54                 }
55             }
56         } else {
57             if (type_.isEmptyObject(this._MAPDataControlCbMap)) {
58                 return;
59             }
60             for (var listenerId in this._MAPDataControlCbMap) {
61                 if (this._MAPDataControlCbMap.hasOwnProperty(listenerId)) {
62                     if (
63                         this._MAPDataControlCbMap[listenerId].providerId ===
64                             event.providerId &&
65                         this._MAPDataControlCbMap[listenerId].dataId === event.dataId
66                     ) {
67                         successCallback = this._MAPDataControlCbMap[listenerId]
68                             .changeCallback;
69                         if (type_.isFunction(successCallback)) {
70                             successCallback(event.type, {
71                                 columns: event.columns,
72                                 values: event.values
73                             });
74                         }
75                     }
76                 }
77             }
78         }
79     }
80
81     function _DataControlListenerManager() {
82         this._SQLDataControlCbMap = {};
83         this._MAPDataControlCbMap = {};
84         this.lastListenerId = 0;
85         this.changeEvent = changeEvent.bind(this);
86     }
87
88     _DataControlListenerManager.prototype.addChangeListener = function(
89         type,
90         providerId,
91         dataId,
92         changeCallback,
93         errorCallback
94     ) {
95         var _realWatchId = 0;
96         if (DataType.SQL === type) {
97             for (var i in this._SQLDataControlCbMap) {
98                 if (
99                     this._SQLDataControlCbMap.hasOwnProperty(i) &&
100                     this._SQLDataControlCbMap[i].providerId === providerId &&
101                     this._SQLDataControlCbMap[i].dataId === dataId
102                 ) {
103                     _realWatchId = this._SQLDataControlCbMap[i].realWatchId;
104                 }
105             }
106         } else {
107             for (var i in this._MAPDataControlCbMap) {
108                 if (
109                     this._MAPDataControlCbMap.hasOwnProperty(i) &&
110                     this._MAPDataControlCbMap[i].providerId === providerId &&
111                     this._MAPDataControlCbMap[i].dataId === dataId
112                 ) {
113                     _realWatchId = this._MAPDataControlCbMap[i].realWatchId;
114                 }
115             }
116         }
117
118         if (!_realWatchId) {
119             var callback = function(result) {
120                 if (native_.isFailure(result)) {
121                     native_.callIfPossible(errorCallback, native_.getErrorObject(result));
122                     return;
123                 }
124             };
125             var result = native_.call(
126                 'DataControlConsumerObject_addChangeListener',
127                 {
128                     providerId: providerId,
129                     dataId: dataId,
130                     type: type
131                 },
132                 callback
133             );
134
135             if (native_.isFailure(result)) {
136                 throw native_.getErrorObject(result);
137             } else {
138                 result = native_.getResultObject(result);
139                 _realWatchId = converter_.toLong(result.watchId, true);
140             }
141             if (
142                 type_.isEmptyObject(this._SQLDataControlCbMap) &&
143                 type_.isEmptyObject(this._MAPDataControlCbMap)
144             ) {
145                 native_.addListener(DATA_CONTROL_MANAGER_LISTENER_ID, this.changeEvent);
146             }
147         }
148
149         if (DataType.SQL === type) {
150             this._SQLDataControlCbMap[++this.lastListenerId] = {
151                 providerId: providerId,
152                 dataId: dataId,
153                 changeCallback: changeCallback,
154                 realWatchId: _realWatchId
155             };
156         } else {
157             this._MAPDataControlCbMap[++this.lastListenerId] = {
158                 providerId: providerId,
159                 dataId: dataId,
160                 changeCallback: changeCallback,
161                 realWatchId: _realWatchId
162             };
163         }
164
165         return this.lastListenerId;
166     };
167
168     _DataControlListenerManager.prototype.removeChangeListener = function(
169         type,
170         providerId,
171         dataId,
172         listenerId
173     ) {
174         var _realWatchId = 0;
175         if (
176             DataType.SQL === type &&
177             !type_.isUndefined(this._SQLDataControlCbMap[listenerId])
178         ) {
179             _realWatchId = this._SQLDataControlCbMap[listenerId].realWatchId;
180             delete this._SQLDataControlCbMap[listenerId];
181             for (var i in this._SQLDataControlCbMap) {
182                 if (
183                     this._SQLDataControlCbMap.hasOwnProperty(i) &&
184                     this._SQLDataControlCbMap[i].realWatchId === _realWatchId
185                 ) {
186                     return;
187                 }
188             }
189         } else if (
190             DataType.MAP === type &&
191             !type_.isUndefined(this._MAPDataControlCbMap[listenerId])
192         ) {
193             _realWatchId = this._MAPDataControlCbMap[listenerId].realWatchId;
194             delete this._MAPDataControlCbMap[listenerId];
195             for (var i in this._MAPDataControlCbMap) {
196                 if (
197                     this._MAPDataControlCbMap.hasOwnProperty(i) &&
198                     this._MAPDataControlCbMap[i].realWatchId === _realWatchId
199                 ) {
200                     return;
201                 }
202             }
203         } else {
204             console.log('Type invalid or listener was not added');
205             return;
206         }
207
208         if (0 != _realWatchId) {
209             native_.call('DataControlConsumerObject_removeChangeListener', {
210                 watchId: _realWatchId
211             });
212
213             if (
214                 type_.isEmptyObject(this._SQLDataControlCbMap) &&
215                 type_.isEmptyObject(this._MAPDataControlCbMap)
216             ) {
217                 native_.removeListener(DATA_CONTROL_MANAGER_LISTENER_ID);
218             }
219         }
220     };
221
222     return _DataControlListenerManager;
223 })();
224
225 var listenersManager = new DataControlListenersManager();
226
227 function SetReadOnlyProperty(obj, n, v) {
228     Object.defineProperty(obj, n, { value: v, writable: false });
229 }
230
231 function DataControlManager() {
232     // constructor of DataControlManager
233 }
234
235 var privUtils_ = xwalk.utils;
236
237 var getDataControlConsumer = function(providerId, dataId, type) {
238     privUtils_.checkPrivilegeAccess(privUtils_.privilege.DATACONTROL_CONSUMER);
239     var args = validator_.validateArgs(arguments, [
240         { name: 'providerId', type: types_.STRING },
241         { name: 'dataId', type: types_.STRING },
242         { name: 'type', type: types_.ENUM, values: [DataType.SQL, DataType.MAP] }
243     ]);
244
245     var returnObject = null;
246     if (DataType.SQL === type) {
247         returnObject = new SQLDataControlConsumer();
248     } else if (DataType.MAP == type) {
249         returnObject = new MappedDataControlConsumer();
250     }
251
252     SetReadOnlyProperty(returnObject, 'type', args.type); // read only property
253     SetReadOnlyProperty(returnObject, 'providerId', args.providerId); // read only
254     // property
255     SetReadOnlyProperty(returnObject, 'dataId', args.dataId); // read only property
256
257     return returnObject;
258 };
259
260 DataControlManager.prototype.getDataControlConsumer = function(providerId, dataId, type) {
261     return getDataControlConsumer.apply(null, arguments);
262 };
263
264 function DataControlConsumerObject() {
265     // constructor of DataControlConsumerObject
266 }
267
268 DataControlConsumerObject.prototype.addChangeListener = function() {
269     var args = validator_.validateArgs(arguments, [
270         {
271             name: 'dataChangeCallback',
272             type: types_.FUNCTION,
273             optional: false,
274             nullable: false
275         },
276         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
277     ]);
278
279     var type = DataType.SQL;
280     if (this instanceof MappedDataControlConsumer) {
281         type = DataType.MAP;
282     }
283
284     return listenersManager.addChangeListener(
285         type,
286         this.providerId,
287         this.dataId,
288         args.dataChangeCallback,
289         args.errorCallback
290     );
291 };
292
293 DataControlConsumerObject.prototype.removeChangeListener = function() {
294     var args = validator_.validateArgs(arguments, [
295         { name: 'watchId', type: types_.LONG }
296     ]);
297
298     var type = DataType.SQL;
299     if (this instanceof MappedDataControlConsumer) {
300         type = DataType.MAP;
301     }
302
303     listenersManager.removeChangeListener(
304         type,
305         this.providerId,
306         this.dataId,
307         args.watchId
308     );
309 };
310
311 function SQLDataControlConsumer() {
312     // constructor of SQLDataControlConsumer
313 }
314
315 SQLDataControlConsumer.prototype = new DataControlConsumerObject();
316 SQLDataControlConsumer.prototype.constructor = SQLDataControlConsumer;
317
318 SQLDataControlConsumer.prototype.insert = function() {
319     var args = validator_.validateArgs(arguments, [
320         { name: 'reqId', type: types_.LONG },
321         { name: 'insertionData', type: types_.DICTIONARY },
322         {
323             name: 'successCallback',
324             type: types_.FUNCTION,
325             optional: true,
326             nullable: true
327         },
328         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
329     ]);
330
331     // doing conversion of all elements to string
332     var ins = validator_.validateArgs(
333         [args.insertionData.columns, args.insertionData.values],
334         [
335             { name: 'columns', type: types_.ARRAY, values: types_.STRING },
336             { name: 'values', type: types_.ARRAY, values: types_.STRING }
337         ]
338     );
339
340     var nativeParam = {
341         providerId: this.providerId,
342         dataId: this.dataId,
343         reqId: args.reqId,
344         insertionData: args.insertionData
345     };
346
347     var syncResult = native_.call('SQLDataControlConsumer_insert', nativeParam, function(
348         result
349     ) {
350         if (result.status == 'success') {
351             if (args.successCallback) {
352                 args.successCallback(result['requestId'], result['result']);
353             }
354         }
355         if (result.status == 'error') {
356             if (args.errorCallback) {
357                 var err = result['result'];
358                 var e = new WebAPIException(err.name, err.message);
359                 args.errorCallback(result['requestId'], e);
360             }
361         }
362     });
363
364     if (native_.isFailure(syncResult)) {
365         throw native_.getErrorObject(syncResult);
366     }
367 };
368
369 SQLDataControlConsumer.prototype.update = function() {
370     var args = validator_.validateArgs(arguments, [
371         { name: 'reqId', type: types_.LONG },
372         { name: 'updateData', type: types_.DICTIONARY },
373         { name: 'where', type: types_.STRING },
374         {
375             name: 'successCallback',
376             type: types_.FUNCTION,
377             optional: true,
378             nullable: true
379         },
380         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
381     ]);
382
383     var nativeParam = {
384         providerId: this.providerId,
385         dataId: this.dataId,
386         reqId: args.reqId,
387         where: args.where,
388         updateData: args.updateData
389     };
390
391     var syncResult = native_.call('SQLDataControlConsumer_update', nativeParam, function(
392         result
393     ) {
394         if (result.status == 'success') {
395             if (args.successCallback) {
396                 args.successCallback(result['requestId']);
397             }
398         }
399         if (result.status == 'error') {
400             if (args.errorCallback) {
401                 var err = result['result'];
402                 var e = new WebAPIException(err.name, err.message);
403                 args.errorCallback(result['requestId'], e);
404             }
405         }
406     });
407
408     if (native_.isFailure(syncResult)) {
409         throw native_.getErrorObject(syncResult);
410     }
411 };
412
413 SQLDataControlConsumer.prototype.remove = function() {
414     var args = validator_.validateArgs(arguments, [
415         { name: 'reqId', type: types_.LONG },
416         { name: 'where', type: types_.STRING },
417         {
418             name: 'successCallback',
419             type: types_.FUNCTION,
420             optional: true,
421             nullable: true
422         },
423         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
424     ]);
425
426     var nativeParam = {
427         providerId: this.providerId,
428         dataId: this.dataId,
429         reqId: args.reqId,
430         where: args.where
431     };
432
433     var syncResult = native_.call('SQLDataControlConsumer_remove', nativeParam, function(
434         result
435     ) {
436         if (result.status == 'success') {
437             if (args.successCallback) {
438                 args.successCallback(result['requestId']);
439             }
440         }
441         if (result.status == 'error') {
442             if (args.errorCallback) {
443                 var err = result['result'];
444                 var e = new WebAPIException(err.name, err.message);
445                 args.errorCallback(result['requestId'], e);
446             }
447         }
448     });
449
450     if (native_.isFailure(syncResult)) {
451         throw native_.getErrorObject(syncResult);
452     }
453 };
454
455 SQLDataControlConsumer.prototype.select = function() {
456     var args = validator_.validateArgs(arguments, [
457         { name: 'reqId', type: types_.LONG },
458         { name: 'columns', type: types_.ARRAY },
459         { name: 'where', type: types_.STRING },
460         { name: 'successCallback', type: types_.FUNCTION },
461         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true },
462         { name: 'page', type: types_.LONG, optional: true, nullable: true },
463         { name: 'maxNumberPerPage', type: types_.LONG, optional: true, nullable: true },
464         { name: 'order', type: types_.STRING, optional: true, nullable: true }
465     ]);
466
467     var nativeParam = {
468         providerId: this.providerId,
469         dataId: this.dataId,
470         reqId: args.reqId,
471         columns: args.columns,
472         where: args.where
473     };
474     if (args['page']) {
475         nativeParam['page'] = args.page;
476     }
477     if (args['maxNumberPerPage']) {
478         nativeParam['maxNumberPerPage'] = args.maxNumberPerPage;
479     }
480     if (args['order']) {
481         nativeParam['order'] = args.order;
482     }
483
484     var syncResult = native_.call('SQLDataControlConsumer_select', nativeParam, function(
485         result
486     ) {
487         if (result.status == 'success') {
488             args.successCallback(result['result'], result['requestId']);
489         }
490         if (result.status == 'error') {
491             if (args.errorCallback) {
492                 var err = result['result'];
493                 var e = new WebAPIException(err.name, err.message);
494                 args.errorCallback(result['requestId'], e);
495             }
496         }
497     });
498
499     if (native_.isFailure(syncResult)) {
500         throw native_.getErrorObject(syncResult);
501     }
502 };
503
504 function MappedDataControlConsumer() {
505     // constructor of MappedDataControlConsumer
506 }
507
508 MappedDataControlConsumer.prototype = new DataControlConsumerObject();
509 MappedDataControlConsumer.prototype.constructor = MappedDataControlConsumer;
510
511 MappedDataControlConsumer.prototype.addValue = function() {
512     var args = validator_.validateArgs(arguments, [
513         { name: 'reqId', type: types_.LONG },
514         { name: 'key', type: types_.STRING },
515         { name: 'value', type: types_.STRING },
516         {
517             name: 'successCallback',
518             type: types_.FUNCTION,
519             optional: true,
520             nullable: true
521         },
522         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
523     ]);
524
525     var nativeParam = {
526         providerId: this.providerId,
527         dataId: this.dataId,
528         reqId: args.reqId,
529         key: args.key,
530         value: args.value
531     };
532
533     var syncResult = native_.call(
534         'MappedDataControlConsumer_addValue',
535         nativeParam,
536         function(result) {
537             if (result.status == 'success') {
538                 if (args.successCallback) {
539                     args.successCallback(result['requestId']);
540                 }
541             }
542             if (result.status == 'error') {
543                 if (args.errorCallback) {
544                     var err = result['result'];
545                     var e = new WebAPIException(err.name, err.message);
546                     args.errorCallback(result['requestId'], e);
547                 }
548             }
549         }
550     );
551
552     if (native_.isFailure(syncResult)) {
553         throw native_.getErrorObject(syncResult);
554     }
555 };
556
557 MappedDataControlConsumer.prototype.removeValue = function() {
558     var args = validator_.validateArgs(arguments, [
559         { name: 'reqId', type: types_.LONG },
560         { name: 'key', type: types_.STRING },
561         { name: 'value', type: types_.STRING },
562         { name: 'successCallback', type: types_.FUNCTION },
563         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
564     ]);
565
566     var nativeParam = {
567         providerId: this.providerId,
568         dataId: this.dataId,
569         reqId: args.reqId,
570         key: args.key,
571         value: args.value
572     };
573
574     var syncResult = native_.call(
575         'MappedDataControlConsumer_removeValue',
576         nativeParam,
577         function(result) {
578             if (result.status == 'success') {
579                 args.successCallback(result['requestId']);
580             }
581             if (result.status == 'error') {
582                 if (args.errorCallback) {
583                     var err = result['result'];
584                     var e = new WebAPIException(err.name, err.message);
585                     args.errorCallback(result['requestId'], e);
586                 }
587             }
588         }
589     );
590
591     if (native_.isFailure(syncResult)) {
592         throw native_.getErrorObject(syncResult);
593     }
594 };
595
596 MappedDataControlConsumer.prototype.getValue = function() {
597     var args = validator_.validateArgs(arguments, [
598         { name: 'reqId', type: types_.LONG },
599         { name: 'key', type: types_.STRING },
600         { name: 'successCallback', type: types_.FUNCTION },
601         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
602     ]);
603
604     var nativeParam = {
605         providerId: this.providerId,
606         dataId: this.dataId,
607         reqId: args.reqId,
608         key: args.key
609     };
610
611     var syncResult = native_.call(
612         'MappedDataControlConsumer_getValue',
613         nativeParam,
614         function(result) {
615             if (result.status == 'success') {
616                 args.successCallback(result['result'], result['requestId']);
617             }
618             if (result.status == 'error') {
619                 if (args.errorCallback) {
620                     var err = result['result'];
621                     var e = new WebAPIException(err.name, err.message);
622                     args.errorCallback(result['requestId'], e);
623                 }
624             }
625         }
626     );
627
628     if (native_.isFailure(syncResult)) {
629         throw native_.getErrorObject(syncResult);
630     }
631 };
632
633 MappedDataControlConsumer.prototype.updateValue = function() {
634     var args = validator_.validateArgs(arguments, [
635         { name: 'reqId', type: types_.LONG },
636         { name: 'key', type: types_.STRING },
637         { name: 'oldValue', type: types_.STRING },
638         { name: 'newValue', type: types_.STRING },
639         { name: 'successCallback', type: types_.FUNCTION },
640         { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
641     ]);
642
643     var nativeParam = {
644         providerId: this.providerId,
645         dataId: this.dataId,
646         reqId: args.reqId,
647         key: args.key,
648         oldValue: args.oldValue,
649         newValue: args.newValue
650     };
651
652     var syncResult = native_.call(
653         'MappedDataControlConsumer_updateValue',
654         nativeParam,
655         function(result) {
656             if (result.status == 'success') {
657                 args.successCallback(result['requestId']);
658             }
659             if (result.status == 'error') {
660                 if (args.errorCallback) {
661                     var err = result['result'];
662                     var e = new WebAPIException(err.name, err.message);
663                     args.errorCallback(result['requestId'], e);
664                 }
665             }
666         }
667     );
668
669     if (native_.isFailure(syncResult)) {
670         throw native_.getErrorObject(syncResult);
671     }
672 };
673
674 exports = new DataControlManager();