2 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 using System.Collections.Generic;
18 using Tizen.Applications.DataControl.Core;
19 using System.Threading;
20 using System.Runtime.InteropServices;
22 namespace Tizen.Applications.DataControl
25 /// Represents the Consumer class for the DataControl consumer application.
27 /// <since_tizen> 3 </since_tizen>
28 public abstract class Consumer : IDisposable
31 private Interop.DataControl.SafeDataControlHandle _handle;
32 private string _dataID, _providerID;
33 private int _changeCallbackID = 0;
34 private const string LogTag = "Tizen.Applications.DataControl";
35 private bool _disposed = false;
36 private static Mutex _lock = new Mutex();
37 private Interop.DataControl.DataChangeCallback _dataChangeCallback;
38 private Interop.DataControl.AddCallbackResultCallback _addCallbackResultCallback;
40 private static class CallbackManager
42 private static IDictionary<string, Interop.DataControl.MapResponseCallbacks> _mapResponseCallbacks = new Dictionary<string, Interop.DataControl.MapResponseCallbacks>();
43 private static IDictionary<string, Interop.DataControl.MapBulkAddResponseCallback> _mapBulkResponseCallback = new Dictionary<string, Interop.DataControl.MapBulkAddResponseCallback>();
44 private static IDictionary<string, Interop.DataControl.SqlResponseCallbacks> _sqlResponseCallbacks = new Dictionary<string, Interop.DataControl.SqlResponseCallbacks>();
45 private static IDictionary<string, Interop.DataControl.SqlBulkInsertResponseCallback> _sqlBulkResponseCallback = new Dictionary<string, Interop.DataControl.SqlBulkInsertResponseCallback>();
46 private static IDictionary<int, Consumer> _reqConsumerDictionary = new Dictionary<int, Consumer>();
47 private static IDictionary<string, int> _reqProviderList = new Dictionary<string, int>();
48 private static void InsertResponse(int reqId, IntPtr provider, long insertedRowId, bool providerResult, string error, IntPtr userData)
50 Log.Debug(LogTag, $"InsertResponse {reqId.ToString()}");
51 if (!_reqConsumerDictionary.ContainsKey(reqId))
53 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
59 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}, rowID : {insertedRowId.ToString()}");
62 Consumer consumer = _reqConsumerDictionary[reqId];
63 consumer.OnInsertResult(new InsertResult(insertedRowId, providerResult));
64 _reqConsumerDictionary.Remove(reqId);
67 private static void BulkInsertResponse(int reqId, IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData)
70 Log.Debug(LogTag, $"BulkInsertResponse {reqId.ToString()}");
71 if (!_reqConsumerDictionary.ContainsKey(reqId))
73 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
79 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
82 if (bulkResults != IntPtr.Zero)
84 brd = new BulkResultData(new Interop.DataControl.SafeBulkResultDataHandle(bulkResults, false));
88 brd = new BulkResultData();
89 Log.Error(LogTag, $"reqId {reqId.ToString()}, bulkResults is null");
92 Consumer consumer = _reqConsumerDictionary[reqId];
93 consumer.OnBulkInsertResult(new BulkInsertResult(brd, providerResult));
94 _reqConsumerDictionary.Remove(reqId);
97 private static void SelectResponse(int reqId, IntPtr provider, IntPtr cursor, bool providerResult, string error, IntPtr userData)
100 Log.Debug(LogTag, $"SelectResponse {reqId.ToString()}");
101 if (!_reqConsumerDictionary.ContainsKey(reqId))
103 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
109 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
112 if (cursor != IntPtr.Zero)
116 dmc = CloneCursor(new CloneCursorCore(new Interop.DataControl.SafeCursorHandle(cursor, true)));
120 dmc = new MatrixCursor();
121 Log.Error(LogTag, $"reqId {reqId.ToString()}, {ex.ToString()}");
126 dmc = new MatrixCursor();
127 Log.Error(LogTag, $"reqId {reqId.ToString()}, cursor is null");
129 Consumer consumer = _reqConsumerDictionary[reqId];
130 consumer.OnSelectResult(new SelectResult(dmc, providerResult));
131 _reqConsumerDictionary.Remove(reqId);
134 private static void UpdateResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
136 if (!_reqConsumerDictionary.ContainsKey(reqId))
138 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
144 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
147 Consumer consumer = _reqConsumerDictionary[reqId];
148 consumer.OnUpdateResult(new UpdateResult(providerResult));
149 _reqConsumerDictionary.Remove(reqId);
152 private static void DeleteResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
154 if (!_reqConsumerDictionary.ContainsKey(reqId))
156 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
162 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
165 Consumer consumer = _reqConsumerDictionary[reqId];
166 consumer.OnDeleteResult(new DeleteResult(providerResult));
167 _reqConsumerDictionary.Remove(reqId);
170 static void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
172 managedArray = new string[size];
173 IntPtr[] IntPtrArray = new IntPtr[size];
174 Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
175 for (int iterator = 0; iterator < size; iterator++)
177 managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);
181 private static void MapGetResponse(int reqId, IntPtr provider, IntPtr valueList, int valueCount, bool providerResult, string error, IntPtr userData)
184 Log.Debug(LogTag, $"MapGetResponse {reqId.ToString()}");
185 if (!_reqConsumerDictionary.ContainsKey(reqId))
187 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
193 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
196 if (valueList !=null)
198 string[] stringArray;
199 IntPtrToStringArray(valueList, valueCount, out stringArray);
200 mgr = new MapGetResult(stringArray, providerResult);
204 mgr = new MapGetResult(new string[0], providerResult);
205 Log.Error(LogTag, $"reqId {reqId.ToString()}, valueList is null");
208 Consumer consumer = _reqConsumerDictionary[reqId];
209 consumer.OnMapGetResult(mgr);
210 _reqConsumerDictionary.Remove(reqId);
213 private static void MapBulkAddResponse(int reqId, IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData)
216 Log.Debug(LogTag, $"MapBulkAddResponse {reqId.ToString()}");
217 if (!_reqConsumerDictionary.ContainsKey(reqId))
219 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
225 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
228 if (bulkResults != IntPtr.Zero)
230 brd = new BulkResultData(new Interop.DataControl.SafeBulkResultDataHandle(bulkResults, false));
234 brd = new BulkResultData();
235 Log.Error(LogTag, $"reqId {reqId.ToString()}, bulkResults is null");
238 Consumer consumer = _reqConsumerDictionary[reqId];
239 consumer.OnMapBulkAddResult(new MapBulkAddResult(brd, providerResult));
240 _reqConsumerDictionary.Remove(reqId);
243 private static void MapAddResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
245 Log.Debug(LogTag, $"MapAddResponse {reqId.ToString()}");
246 if (!_reqConsumerDictionary.ContainsKey(reqId))
248 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
254 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
257 Consumer consumer = _reqConsumerDictionary[reqId];
258 consumer.OnMapAddResult(new MapAddResult(providerResult));
259 _reqConsumerDictionary.Remove(reqId);
262 private static void MapSetResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
264 Log.Debug(LogTag, $"MapSetResponse {reqId.ToString()}");
265 if (!_reqConsumerDictionary.ContainsKey(reqId))
267 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
273 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
276 Consumer consumer = _reqConsumerDictionary[reqId];
277 consumer.OnMapSetResult(new MapSetResult(providerResult));
278 _reqConsumerDictionary.Remove(reqId);
281 private static void MapRemoveResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
283 if (!_reqConsumerDictionary.ContainsKey(reqId))
285 Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
291 Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
294 Consumer consumer = _reqConsumerDictionary[reqId];
295 consumer.OnMapRemoveResult(new MapRemoveResult(providerResult));
296 _reqConsumerDictionary.Remove(reqId);
299 private static MatrixCursor CloneCursor(CloneCursorCore coreCursor)
301 int size = coreCursor.GetColumnCount();
303 string[] name = new string[size];
304 object[] newRow = new object[size];
305 ColumnType[] type = new ColumnType[size];
307 for (i = 0; i < size; i++)
309 name[i] = coreCursor.GetColumnName(i);
310 type[i] = coreCursor.GetColumnType(i);
313 MatrixCursor dmc = new MatrixCursor(name, type);
315 if (coreCursor.GetRowCount() <= 0)
323 for (i = 0; i < size; i++)
327 case ColumnType.ColumnTypeInt:
328 newRow[i] = coreCursor.GetInt64Value(i);
330 case ColumnType.ColumnTypeDouble:
331 newRow[i] = coreCursor.GetDoubleValue(i);
333 case ColumnType.ColumnTypeBlob:
334 newRow[i] = coreCursor.GetBlobValue(i);
336 case ColumnType.ColumnTypeString:
337 newRow[i] = coreCursor.GetStringValue(i);
344 while (coreCursor.Next());
349 internal static void RegisterReqId(int reqId, Consumer consumer)
352 _reqConsumerDictionary.Add(reqId, consumer);
353 _lock.ReleaseMutex();
356 internal static void RegisterCallback(Interop.DataControl.SafeDataControlHandle handle, string providerId)
359 Interop.DataControl.SqlResponseCallbacks sqlCallbacks;
360 Interop.DataControl.SqlBulkInsertResponseCallback sqlBulkCallbacks;
361 Interop.DataControl.MapResponseCallbacks mapCallbacks;
362 Interop.DataControl.MapBulkAddResponseCallback mapBulkCallbacks;
363 bool sqlRegistered = false;
364 bool mapRegistered = false;
366 if (_reqProviderList.ContainsKey(providerId))
368 _reqProviderList[providerId]++;
369 Log.Error(LogTag, "The data control is already set");
373 sqlCallbacks.Insert = new Interop.DataControl.SqlInsertResponseCallback(InsertResponse);
374 sqlCallbacks.Select = new Interop.DataControl.SqlSelectResponseCallback(SelectResponse);
375 sqlCallbacks.Update = new Interop.DataControl.SqlUpdateResponseCallback(UpdateResponse);
376 sqlCallbacks.Delete = new Interop.DataControl.SqlDeleteResponseCallback(DeleteResponse);
377 ret = Interop.DataControl.RegisterSqlResponseCallback(handle, ref sqlCallbacks, IntPtr.Zero);
378 if (ret != ResultType.Success)
380 Log.Error(LogTag, "Registering the sql callback function is failed : " + ret);
384 _sqlResponseCallbacks.Add(providerId, sqlCallbacks);
385 sqlRegistered = true;
388 sqlBulkCallbacks = new Interop.DataControl.SqlBulkInsertResponseCallback(BulkInsertResponse);
389 ret = Interop.DataControl.RegisterSqlBulkResponseCallback(handle, sqlBulkCallbacks, IntPtr.Zero);
390 if (ret != ResultType.Success)
392 Log.Error(LogTag, "Registering the sql bulk callback function is failed : " + ret);
396 _sqlBulkResponseCallback.Add(providerId, sqlBulkCallbacks);
399 mapCallbacks.Add = new Interop.DataControl.MapAddResponseCallback(MapAddResponse);
400 mapCallbacks.Set = new Interop.DataControl.MapSetResponseCallback(MapSetResponse);
401 mapCallbacks.Get = new Interop.DataControl.MapGetResponseCallback(MapGetResponse);
402 mapCallbacks.Remove = new Interop.DataControl.MapRemoveResponseCallback(MapRemoveResponse);
403 ret = Interop.DataControl.RegisterMapResponse(handle, ref mapCallbacks, IntPtr.Zero);
405 if (ret != ResultType.Success)
407 Log.Error(LogTag, "Registering the map callback function is failed : " + ret);
411 _mapResponseCallbacks.Add(providerId, mapCallbacks);
412 mapRegistered = true;
415 mapBulkCallbacks = new Interop.DataControl.MapBulkAddResponseCallback(MapBulkAddResponse);
416 ret = Interop.DataControl.RegisterMapBulkResponseCallback(handle, mapBulkCallbacks, IntPtr.Zero);
417 if (ret != ResultType.Success)
419 Log.Error(LogTag, "Registering the map bulk callback function is failed : " + ret);
423 _mapBulkResponseCallback.Add(providerId, mapBulkCallbacks);
426 if (!mapRegistered && !sqlRegistered)
428 ErrorFactory.ThrowException(ret, true, "Registering the response callback function is failed");
431 _reqProviderList.Add(providerId, 1);
434 internal static void UnregisterCallback(Interop.DataControl.SafeDataControlHandle handle, string providerId)
438 _reqProviderList[providerId]--;
439 count = _reqProviderList[providerId];
442 _reqProviderList.Remove(providerId);
444 _mapResponseCallbacks.Remove(providerId);
445 Interop.DataControl.UnregisterMapResponse(handle);
447 _mapBulkResponseCallback.Remove(providerId);
448 Interop.DataControl.UnregisterMapBulkResponseCallback(handle);
450 _sqlResponseCallbacks.Remove(providerId);
451 Interop.DataControl.UnregisterSqlResponseCallback(handle);
453 _sqlBulkResponseCallback.Remove(providerId);
454 Interop.DataControl.UnregisterSqlBulkResponseCallback(handle);
461 /// Sends the insert request to the provider application.
463 /// <remarks>The OnInsertResult will recieve the result of this API.</remarks>
464 /// <param name="insertData">The insert data.</param>
465 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
466 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
467 /// <exception cref="ArgumentOutOfRangeException">Thrown when the message has exceeded the maximum limit (1MB).</exception>
468 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
469 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
470 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
471 /// <since_tizen> 3 </since_tizen>
472 public void Insert(Bundle insertData)
477 if (insertData == null || insertData.SafeBundleHandle.IsInvalid)
479 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
483 ret = Interop.DataControl.Insert(_handle, insertData.SafeBundleHandle, out reqId);
484 _lock.ReleaseMutex();
485 if (ret != ResultType.Success)
487 ErrorFactory.ThrowException(ret, false, "Insert");
490 CallbackManager.RegisterReqId(reqId, this);
494 /// Sends the select request to the provider application.
496 /// <remarks>The OnSelectResult will recieve the result of this API.</remarks>
497 /// <param name="columnList">Select the target column list.</param>
498 /// <param name="where">The Where statement for the select query.</param>
499 /// <param name="order">The Order statement for the select query.</param>
500 /// <param name="pageNumber">Select the target page number.</param>
501 /// <param name="countPerPage">Select the row count per page.</param>
502 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
503 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied..</exception>
504 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
505 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
506 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
507 /// <since_tizen> 3 </since_tizen>
508 public void Select(string[] columnList, string where, string order, int pageNumber = 1, int countPerPage = 20)
512 if (columnList == null || columnList.Length == 0)
514 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column_list");
517 for (i = 0; i < columnList.Length; i++)
519 if (string.IsNullOrEmpty(columnList[i]))
521 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column_list index " + i.ToString());
526 ret = Interop.DataControl.Select(_handle, columnList, columnList.Length, where, order, pageNumber, countPerPage, out reqId);
527 _lock.ReleaseMutex();
528 if (ret != ResultType.Success)
530 ErrorFactory.ThrowException(ret, false, "Select");
532 Log.Info(LogTag, "select end. " + reqId.ToString());
534 CallbackManager.RegisterReqId(reqId, this);
538 /// Sends the delete request to the provider application.
540 /// <remarks>The OnDeleteResult will recieve the result of this API</remarks>
541 /// <param name="where">The Where statement for the delete query.</param>
542 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
543 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
544 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
545 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
546 /// <since_tizen> 3 </since_tizen>
547 public void Delete(string where)
553 ret = Interop.DataControl.Delete(_handle, where, out reqId);
554 _lock.ReleaseMutex();
555 if (ret != ResultType.Success)
557 ErrorFactory.ThrowException(ret, false, "Delete");
560 CallbackManager.RegisterReqId(reqId, this);
564 /// Sends the update request to the provider application.
566 /// <remarks>The OnUpdateResult will recieve result of this API.</remarks>
567 /// <param name="updateData">The update data.</param>
568 /// <param name="where">The Where statement for the query.</param>
569 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
570 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
571 /// <exception cref="ArgumentOutOfRangeException">Thrown when the message has exceeded the maximum limit (1MB).</exception>
572 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
573 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
574 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
575 /// <since_tizen> 3 </since_tizen>
576 public void Update(Bundle updateData, string where)
581 if (updateData == null || updateData.SafeBundleHandle.IsInvalid)
583 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
586 if (string.IsNullOrEmpty(where))
588 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "where");
592 ret = Interop.DataControl.Update(_handle, updateData.SafeBundleHandle, where, out reqId);
593 _lock.ReleaseMutex();
594 if (ret != ResultType.Success)
596 ErrorFactory.ThrowException(ret, false, "Update");
599 CallbackManager.RegisterReqId(reqId, this);
603 /// Sends the bulk insert request to the provider application.
605 /// <remarks>The OnBulkInsertResult will recieve the result of this API.</remarks>
606 /// <param name="insertData">The bulk insert data.</param>
607 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
608 /// <exception cref="UnauthorizedAccessException">Thrown in case oif a permission is denied.</exception>
609 /// <exception cref="ArgumentOutOfRangeException">Thrown when the message has exceeded the maximum limit (1MB).</exception>
610 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
611 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
612 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
613 /// <since_tizen> 3 </since_tizen>
614 public void BulkInsert(BulkData insertData)
619 if (insertData == null || insertData.SafeBulkDataHandle.IsInvalid)
621 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
625 ret = Interop.DataControl.BulkInsert(_handle, insertData.SafeBulkDataHandle, out reqId);
626 _lock.ReleaseMutex();
627 if (ret != ResultType.Success)
629 ErrorFactory.ThrowException(ret, false, "BulkInsert");
632 CallbackManager.RegisterReqId(reqId, this);
636 /// Sends the map add request to the provider application.
638 /// <remarks>The OnMapAddResult will recieve the result of this API.</remarks>
639 /// <param name="key">The key of the value to add.</param>
640 /// <param name="value">The value to add.</param>
641 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
642 /// <exception cref="UnauthorizedAccessException">Thrown in case of if a permission is denied.</exception>
643 /// <exception cref="ArgumentOutOfRangeException">Thrown when the message has exceeded the maximum limit (1MB).</exception>
644 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
645 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
646 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
647 /// <since_tizen> 3 </since_tizen>
648 public void MapAdd(string key, string value)
653 if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
655 ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
659 ret = Interop.DataControl.MapAdd(_handle, key, value, out reqId);
660 _lock.ReleaseMutex();
661 if (ret != ResultType.Success)
663 ErrorFactory.ThrowException(ret, false, "MapAdd");
666 CallbackManager.RegisterReqId(reqId, this);
670 /// Sends the map get request to the provider application.
672 /// <remarks>The OnMapGetResult will recieve the result of this API.</remarks>
673 /// <param name="key">The key of the value list to obtain.</param>
674 /// <param name="pageNumber">The page number of the value set.</param>
675 /// <param name="countPerPage">The desired maximum count of the data items per page.</param>
676 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
677 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
678 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
679 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
680 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
681 /// <since_tizen> 3 </since_tizen>
682 public void MapGet(string key, int pageNumber = 1, int countPerPage = 20)
687 if (string.IsNullOrEmpty(key) || pageNumber <= 0 || countPerPage <= 0)
689 ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
693 ret = Interop.DataControl.MapGet(_handle, key, out reqId, pageNumber, countPerPage);
694 _lock.ReleaseMutex();
695 if (ret != ResultType.Success)
697 ErrorFactory.ThrowException(ret, false, "MapGet");
700 CallbackManager.RegisterReqId(reqId, this);
704 /// Sends the map remove request to the provider application.
706 /// <remarks>The OnMapRemoveResult will recieve the result of this API.</remarks>
707 /// <param name="key">The key of the value to remove.</param>
708 /// <param name="value">The value to remove.</param>
709 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
710 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
711 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
712 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
713 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
714 /// <since_tizen> 3 </since_tizen>
715 public void MapRemove(string key, string value)
720 if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
722 ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
726 ret = Interop.DataControl.MapRemove(_handle, key, value, out reqId);
727 _lock.ReleaseMutex();
728 if (ret != ResultType.Success)
730 ErrorFactory.ThrowException(ret, false, "MapRemove");
733 CallbackManager.RegisterReqId(reqId, this);
737 /// Sends the map set request to the provider application.
739 /// <remarks>The OnMapSetResult will recieve the result of this API.</remarks>
740 /// <param name="key">The key of the value to replace.</param>
741 /// <param name="oldValue">The value to be replaced.</param>
742 /// <param name="newValue"> The new value that replaces the existing value.</param>
743 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
744 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
745 /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit (1MB).</exception>
746 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
747 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
748 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
749 /// <since_tizen> 3 </since_tizen>
750 public void MapSet(string key, string oldValue, string newValue)
755 if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(oldValue) || string.IsNullOrEmpty(newValue))
757 ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
761 ret = Interop.DataControl.MapSet(_handle, key, oldValue, newValue, out reqId);
762 _lock.ReleaseMutex();
763 if (ret != ResultType.Success)
765 ErrorFactory.ThrowException(ret, false, "MapSet");
768 CallbackManager.RegisterReqId(reqId, this);
772 /// Sends the map bulk add request to the provider application.
774 /// <remarks>The OnMapBulkAddResult will recieve the result of this API.</remarks>
775 /// <param name="addData">The map bulk add data.</param>
776 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
777 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
778 /// <exception cref="ArgumentOutOfRangeException">Thrown when the message has exceeded the maximum limit (1MB).</exception>
779 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
780 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
781 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
782 /// <since_tizen> 3 </since_tizen>
783 public void MapBulkAdd(BulkData addData)
788 if (addData == null || addData.SafeBulkDataHandle.IsInvalid)
790 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "addData");
794 ret = Interop.DataControl.BulkAdd(_handle, addData.SafeBulkDataHandle, out reqId);
795 _lock.ReleaseMutex();
796 if (ret != ResultType.Success)
798 ErrorFactory.ThrowException(ret, false, "BulkAdd");
801 CallbackManager.RegisterReqId(reqId, this);
804 private void DataChange(IntPtr handle, ChangeType type, IntPtr data, IntPtr userData)
806 OnDataChange(type, new Bundle(new SafeBundleHandle(data, false)));
809 private void DataChangeListenResult(IntPtr handle, ResultType type, int callbackId, IntPtr userData)
811 OnDataChangeListenResult(new DataChangeListenResult(type));
815 /// Listens the DataChange event.
817 /// <remarks>The OnDataChangeListenResult will recieve the result of this API.</remarks>
818 /// <remarks>If success, the OnDataChange will recieve the DataChange event.</remarks>
819 /// <exception cref="UnauthorizedAccessException">Thrown in case if a permission is denied.</exception>
820 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
821 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
822 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
823 /// <since_tizen> 3 </since_tizen>
824 public void DataChangeListen()
828 /* Only one callback is allowed for every obejct */
829 if (_changeCallbackID > 0)
831 _lock.ReleaseMutex();
834 _dataChangeCallback = new Interop.DataControl.DataChangeCallback(DataChange);
835 _addCallbackResultCallback = new Interop.DataControl.AddCallbackResultCallback(DataChangeListenResult);
836 ret = Interop.DataControl.AddDataChangeCallback(_handle, _dataChangeCallback, IntPtr.Zero,
837 _addCallbackResultCallback , IntPtr.Zero, out _changeCallbackID);
838 _lock.ReleaseMutex();
839 if (ret != ResultType.Success)
841 ErrorFactory.ThrowException(ret, false, "DataChangeListen");
846 /// Initializes the Consumer class with the providerId and the ataId.
848 /// <param name="providerId">The DataControl Provider ID.</param>
849 /// <param name="dataId">The DataControl Data ID.</param>
850 /// <exception cref="ArgumentException">Thrown in case of an invalid parmaeter.</exception>
851 /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
852 /// <since_tizen> 3 </since_tizen>
853 public Consumer(string providerId, string dataId)
857 if (string.IsNullOrEmpty(providerId))
859 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "providerId");
862 if (string.IsNullOrEmpty(dataId))
864 ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "dataId");
867 ret = Interop.DataControl.DataControlCreate(out _handle);
868 if (ret != ResultType.Success)
870 ErrorFactory.ThrowException(ret, false, "Creating data control handle is failed");
873 Interop.DataControl.DataControlSetProviderId(_handle, providerId);
874 Interop.DataControl.DataControlSetDataId(_handle, dataId);
875 CallbackManager.RegisterCallback(_handle, providerId);
877 _providerID = providerId;
881 /// Destructor of the Consumer class.
889 /// Overrides this method if you want to handle the behavior when the DataChangeListen result is received.
891 /// <since_tizen> 3 </since_tizen>
892 protected virtual void OnDataChangeListenResult(DataChangeListenResult result)
894 Log.Info(LogTag, "The OnDataChangeListenResult is not implemented.");
898 /// Overrides this method if you want to handle the behavior when the data change event is received.
900 /// <since_tizen> 3 </since_tizen>
901 protected virtual void OnDataChange(ChangeType type, Bundle data)
903 Log.Info(LogTag, "The OnDataChange is not implemented.");
907 /// Overrides this method if you want to handle the behavior when the select response is received.
909 /// <since_tizen> 3 </since_tizen>
910 protected abstract void OnSelectResult(SelectResult result);
913 /// Overrides this method if you want to handle the behavior when the insert response is received.
915 /// <since_tizen> 3 </since_tizen>
916 protected abstract void OnInsertResult(InsertResult result);
919 /// Overrides this method if you want to handle the behavior when the update response is received.
921 /// <since_tizen> 3 </since_tizen>
922 protected abstract void OnUpdateResult(UpdateResult result);
925 /// Overrides this method if want to handle the behavior when the delete response is received.
927 /// <since_tizen> 3 </since_tizen>
928 protected abstract void OnDeleteResult(DeleteResult result);
930 /// Overrides this method if you want to handle the behavior when the BulkInsert response is received.
932 /// <since_tizen> 3 </since_tizen>
933 protected virtual void OnBulkInsertResult(BulkInsertResult result)
935 Log.Info(LogTag, "The OnBulkInsertResult is not implemented.");
939 /// Overrides this method if you want to handle the behavior when the map get response is received.
941 /// <since_tizen> 3 </since_tizen>
942 protected virtual void OnMapGetResult(MapGetResult result)
944 Log.Info(LogTag, "The OnMapGetResult is not implemented.");
948 /// Overrides this method if you want to handle the behavior when the map add response is received.
950 /// <since_tizen> 3 </since_tizen>
951 protected virtual void OnMapAddResult(MapAddResult result)
953 Log.Info(LogTag, "The OnMapAddResult is not implemented.");
957 /// Overrides this method if you want to handle the behavior when the map set response is received.
959 /// <since_tizen> 3 </since_tizen>
960 protected virtual void OnMapSetResult(MapSetResult result)
962 Log.Info(LogTag, "The OnMapSetResult is not implemented.");
966 /// Overrides this method if you want to handle the behavior when the map remove response is received.
968 /// <since_tizen> 3 </since_tizen>
969 protected virtual void OnMapRemoveResult(MapRemoveResult result)
971 Log.Info(LogTag, "The OnMapRemoveResult is not implemented.");
975 /// Overrides this method if you want to handle the behavior when the BulkAdd response is received.
977 /// <since_tizen> 3 </since_tizen>
978 protected virtual void OnMapBulkAddResult(MapBulkAddResult result)
980 Log.Info(LogTag, "The OnMapBulkAddResult is not implemented.");
984 /// Releases the unmanaged resources used by the Consumer class specifying whether to perform a normal dispose operation.
986 /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
987 /// <since_tizen> 3 </since_tizen>
988 protected virtual void Dispose(bool disposing)
992 if (_changeCallbackID > 0)
994 Interop.DataControl.RemoveDataChangeCallback(_handle, _changeCallbackID);
997 CallbackManager.UnregisterCallback(_handle, _providerID);
1004 GC.SuppressFinalize(this);
1009 /// Releases all resources used by the Consumer class.
1011 /// <since_tizen> 3 </since_tizen>
1012 public void Dispose()