--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using Tizen.Applications;
+using Tizen;
+using Tizen.Applications.DataControl;
+
+internal static partial class Interop
+{
+ internal static partial class DataControl
+ {
+
+ internal enum NativeResultType : int
+ {
+ Success = Tizen.Internals.Errors.ErrorCode.None,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ MaxExceed = -0x01190000 | 0x01,
+ }
+
+ internal sealed class SafeBulkDataHandle : SafeHandle
+ {
+ internal SafeBulkDataHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeBulkDataHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ DataControl.BulkFree(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeBulkResultDataHandle : SafeHandle
+ {
+ internal SafeBulkResultDataHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeBulkResultDataHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ DataControl.BulkResultFree(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeCursorHandle : SafeHandle
+ {
+ internal SafeCursorHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeCursorHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ internal sealed class SafeDataControlHandle : SafeHandle
+ {
+ internal SafeDataControlHandle()
+ : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal SafeDataControlHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ DataControl.Destroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_create")]
+ internal static extern ResultType DataControlCreate(out SafeDataControlHandle handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_destroy")]
+ internal static extern ResultType Destroy(IntPtr handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_provider_id")]
+ internal static extern ResultType DataControlGetProviderId(SafeDataControlHandle handle, out string providerId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_set_provider_id")]
+ internal static extern ResultType DataControlSetProviderId(SafeDataControlHandle handle, string providerId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_set_data_id")]
+ internal static extern ResultType DataControlSetDataId(SafeDataControlHandle handle, string dataId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_data_id")]
+ internal static extern ResultType DataControlGetDataId(SafeDataControlHandle handle, out string dataId);
+
+ internal delegate void MapGetResponseCallback(int requestID,
+ IntPtr provider, string[] resultValueList, int resultValueCount, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapSetResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapAddResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapRemoveResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void MapBulkAddResponseCallback(int requestID,
+ IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct MapResponseCallbacks
+ {
+ public MapGetResponseCallback Get;
+ public MapSetResponseCallback Set;
+ public MapAddResponseCallback Add;
+ public MapRemoveResponseCallback Remove;
+ }
+
+ internal delegate void SqlSelectResponseCallback(int requestID,
+ IntPtr provider, IntPtr cursor, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlInsertResponseCallback(int requestID,
+ IntPtr provider, long inserted_row_id, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlUpdateResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlDeleteResponseCallback(int requestID,
+ IntPtr provider, bool providerResult, string error, IntPtr userData);
+ internal delegate void SqlBulkInsertResponseCallback(int requestID,
+ IntPtr provider, IntPtr bulk_results, bool providerResult, string error, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct SqlResponseCallbacks
+ {
+ public SqlSelectResponseCallback Select;
+ public SqlInsertResponseCallback Insert;
+ public SqlUpdateResponseCallback Update;
+ public SqlDeleteResponseCallback Delete;
+ }
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_register_response_cb")]
+ internal static extern ResultType RegisterMapResponse(SafeDataControlHandle provider, ref MapResponseCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_unregister_response_cb")]
+ internal static extern ResultType UnregisterMapResponse(SafeDataControlHandle provider);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_register_add_bulk_data_response_cb")]
+ internal static extern ResultType RegisterMapBulkResponseCallback(SafeDataControlHandle provider, MapBulkAddResponseCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_unregister_add_bulk_data_response_cb")]
+ internal static extern ResultType UnregisterMapBulkResponseCallback(SafeDataControlHandle provider);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_register_response_cb")]
+ internal static extern ResultType RegisterSqlResponseCallback(SafeDataControlHandle provider, ref SqlResponseCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_unregister_response_cb")]
+ internal static extern ResultType UnregisterSqlResponseCallback(SafeDataControlHandle provider);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_register_insert_bulk_data_response_cb")]
+ internal static extern ResultType RegisterSqlBulkResponseCallback(SafeDataControlHandle provider, SqlBulkInsertResponseCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_unregister_insert_bulk_data_response_cb")]
+ internal static extern ResultType UnregisterSqlBulkResponseCallback(SafeDataControlHandle provider);
+
+ internal delegate void MapGetRequestCallback(int requestID,
+ IntPtr provider, string key, IntPtr userData);
+ internal delegate void MapSetRequestCallback(int requestID,
+ IntPtr provider, string key, string oldValue, string newValue, IntPtr userData);
+ internal delegate void MapAddRequestCallback(int requestID,
+ IntPtr provider, string key, string value, IntPtr userData);
+ internal delegate void MapRemoveRequestCallback(int requestID,
+ IntPtr provider, string key, string value, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MapBulkAddRequestCallback(int requestID,
+ IntPtr provider, IntPtr bulkData, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct MapRequestCallbacks
+ {
+ public MapGetRequestCallback Get;
+ public MapSetRequestCallback Set;
+ public MapAddRequestCallback Add;
+ public MapRemoveRequestCallback Remove;
+ }
+
+ internal delegate void SqlInsertRequestCallback(int requestID,
+ IntPtr provider, IntPtr insertData, IntPtr userData);
+ internal delegate void SqlSelectRequestCallback(int requestID,
+ IntPtr provider, IntPtr columnList, int columnCount, string where, string order, IntPtr userData);
+ internal delegate void SqlUpdateRequestCallback(int requestID,
+ IntPtr provider, IntPtr updateData, string where, IntPtr userData);
+ internal delegate void SqlDeleteRequestCallback(int requestID,
+ IntPtr provider, string where, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void SqlBulkInsertRequestCallback(int requestID,
+ IntPtr provider, IntPtr bulk_data, IntPtr userData);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct SqlRequestCallbacks
+ {
+ public SqlInsertRequestCallback Insert;
+ public SqlSelectRequestCallback Select;
+ public SqlUpdateRequestCallback Update;
+ public SqlDeleteRequestCallback Delete;
+ }
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_map_register_cb")]
+ internal static extern ResultType RegisterMapRequest(ref MapRequestCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_sql_register_cb")]
+ internal static extern ResultType RegisterSqlRequest(ref SqlRequestCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_sql_register_insert_bulk_data_request_cb")]
+ internal static extern ResultType RegisterSqlBulkRequest(SqlBulkInsertRequestCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_sql_unregister_insert_bulk_data_request_cb")]
+ internal static extern ResultType UnregisterSqlBulkRequest();
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_map_register_add_bulk_data_request_cb")]
+ internal static extern ResultType RegisterMapBulkRequest(MapBulkAddRequestCallback callback, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_map_unregister_add_bulk_data_request_cb")]
+ internal static extern ResultType UnregisterMapBulkRequest();
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_map_result")]
+ internal static extern ResultType SendMapResult(int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_map_get_value_result")]
+ internal static extern ResultType SendMapGetResult(int requestID, string[] valueList, int valueCount);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_insert_result")]
+ internal static extern ResultType SendInsertResult(int requestID, long rowId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_update_result")]
+ internal static extern ResultType SendUpdateResult(int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_delete_result")]
+ internal static extern ResultType SendDeleteResult(int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "datacontrol_provider_send_select_result_without_data")]
+ internal static extern ResultType SendSelectResult(int requestID, out int fd);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_error")]
+ internal static extern ResultType SendError(int requestID, string error);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_insert")]
+ internal static extern ResultType Insert(SafeDataControlHandle provider, SafeBundleHandle insertData, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_select_with_page")]
+ internal static extern ResultType Select(SafeDataControlHandle provider, string[] columnList, int columnCount, string where, string order, int pageNumber,
+ int countPerPage, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_delete")]
+ internal static extern ResultType Delete(SafeDataControlHandle provider, string where, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_update")]
+ internal static extern ResultType Update(SafeDataControlHandle provider, SafeBundleHandle updatetData, string where, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_insert_bulk_data")]
+ internal static extern ResultType BulkInsert(SafeDataControlHandle provider, SafeBulkDataHandle insertData, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_add")]
+ internal static extern ResultType MapAdd(SafeDataControlHandle provider, string key, string value, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_set")]
+ internal static extern ResultType MapSet(SafeDataControlHandle provider, string key, string oldValue, string newValue, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_remove")]
+ internal static extern ResultType MapRemove(SafeDataControlHandle provider, string key, string value, out int requestId);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_get_with_page")]
+ internal static extern ResultType MapGet(SafeDataControlHandle provider, string key, out int requestId, int pageNumber,
+ int countPerPage);
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_map_add_bulk_data")]
+ internal static extern ResultType BulkAdd(SafeDataControlHandle provider, SafeBulkDataHandle insertData, out int requestID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_create_insert_statement")]
+ internal static extern string CreateInsertStatement(SafeDataControlHandle provider, SafeBundleHandle insertData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_create_delete_statement")]
+ internal static extern string CreateDeleteStatement(SafeDataControlHandle provider, string where);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_create_update_statement")]
+ internal static extern string CreateUpdateStatement(SafeDataControlHandle provider, SafeBundleHandle updateData, string where);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "datacontrol_provider_get_select_page_info")]
+ internal static extern ResultType GetSelectPageInfo(int requestId, out int pageNum, out int countPerPage);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "datacontrol_provider_write_socket")]
+ internal static extern unsafe ResultType WriteSelectResult(int socketFd, byte* buffer, uint nbytes, out uint bytesWrite);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_data_change_noti")]
+ internal static extern ResultType SendDataChange(IntPtr handle, ChangeType type, SafeBundleHandle data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_next")]
+ internal static extern ResultType Next(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_last")]
+ internal static extern ResultType Last(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_first")]
+ internal static extern ResultType First(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_step_previous")]
+ internal static extern ResultType Prev(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_count")]
+ internal static extern int GetColumnCount(SafeCursorHandle cursor);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_name")]
+ internal static extern ResultType GetColumnName(SafeCursorHandle cursor, int idx, StringBuilder name);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_item_size")]
+ internal static extern int GetItemSize(SafeCursorHandle cursor, int idx);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_column_item_type")]
+ internal static extern ResultType GetItemType(SafeCursorHandle cursor, int idx, out int type);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_blob_data")]
+ internal static extern ResultType GetBlob(SafeCursorHandle cursor, int idx, byte[] buffer, int size);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_int_data")]
+ internal static extern ResultType GetInt(SafeCursorHandle cursor, int idx, out int data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_int64_data")]
+ internal static extern ResultType GetInt64(SafeCursorHandle cursor, int idx, out long data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_double_data")]
+ internal static extern ResultType Getdouble(SafeCursorHandle cursor, int idx, out double data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_sql_get_text_data")]
+ internal static extern unsafe ResultType GetText(SafeCursorHandle cursor, int idx, byte[] data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_create")]
+ internal static extern ResultType BulkCreate(out SafeBulkDataHandle handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_add")]
+ internal static extern ResultType BulkAdd(SafeBulkDataHandle handle, SafeBundleHandle data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_get_count")]
+ internal static extern ResultType BulkGetCount(SafeBulkDataHandle handle, out int count);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_destroy")]
+ internal static extern ResultType BulkFree(IntPtr handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_data_get_data")]
+ internal static extern ResultType BulkGetData(SafeBulkDataHandle handle, int idx, out IntPtr data);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_create")]
+ internal static extern ResultType BulkResultCreate(out SafeBulkResultDataHandle handle);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_add")]
+ internal static extern ResultType BulkResultAdd(SafeBulkResultDataHandle handle, SafeBundleHandle data, int result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_get_count")]
+ internal static extern ResultType BulkResultGetCount(SafeBulkResultDataHandle handle, out int count);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_get_result_data")]
+ internal static extern ResultType BulkResultGetData(SafeBulkResultDataHandle handle, int idx, out IntPtr data, out int result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_get_result_data")]
+ internal static extern ResultType BulkResultGetResult(SafeBulkResultDataHandle handle, int idx, out IntPtr data, out int result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_bulk_result_data_destroy")]
+ internal static extern ResultType BulkResultFree(IntPtr handle);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void AddCallbackResultCallback(IntPtr handle, ResultType type, int callbackID, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void DataChangeCallback(IntPtr handle, ChangeType type, IntPtr data, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_add_data_change_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern ResultType AddDataChangeCallback(SafeDataControlHandle provider, DataChangeCallback callback,
+ IntPtr userData, AddCallbackResultCallback resultCallback, IntPtr resultCbUserData, out int callbackID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_remove_data_change_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern ResultType RemoveDataChangeCallback(SafeDataControlHandle provider, int callbackID);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool DataChangeConsumerFilterCb(IntPtr handle, string consumerAppid, IntPtr userData);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_add_data_change_consumer_filter_cb", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern ResultType AddDataChangeConsumerFilterCallback(DataChangeConsumerFilterCb callback,
+ IntPtr userData,
+ out int callbackID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_remove_data_change_consumer_filter_cb")]
+ internal static extern int RemoveDataChangeConsumerFilterCallback(int callbackID);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_bulk_insert_result")]
+ internal static extern ResultType SendBulkInsertResult(int requestId, SafeBulkResultDataHandle result);
+
+ [DllImport(Libraries.DataControl, EntryPoint = "data_control_provider_send_map_bulk_add_result")]
+ internal static extern ResultType SendMapBulkAddResult(int requestId, SafeBulkResultDataHandle result);
+
+ internal static class UnsafeCode
+ {
+ internal static unsafe ResultType WriteResult(int socketFd, byte[] value, int nbytes, out uint bytesWrite)
+ {
+ fixed (byte* pointer = value)
+ {
+ return WriteSelectResult(socketFd, pointer, (uint)nbytes, out bytesWrite);
+ }
+ }
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string DataControl = "libdata-control.so.0";
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Tizen.Applications.DataControl.Core
+{
+ internal class CloneCursorCore : ICursor
+ {
+ internal const int MaxColumnNameSize = 1024;
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private long _rowCount;
+ private int _columnCount;
+ private const int ResultNoData = -1;
+ private Interop.DataControl.SafeCursorHandle _cursor;
+ internal CloneCursorCore(Interop.DataControl.SafeCursorHandle cursor)
+ {
+ _cursor = cursor;
+ _columnCount = Interop.DataControl.GetColumnCount(cursor);
+
+ if (_columnCount == ResultNoData)
+ {
+ _rowCount = 0;
+ return;
+ }
+
+ Interop.DataControl.First(cursor);
+
+ do
+ {
+ _rowCount++;
+ }
+ while (Interop.DataControl.Next(cursor) == (int)ResultType.Success);
+ Interop.DataControl.First(cursor);
+ }
+
+ public int GetColumnCount()
+ {
+ return Interop.DataControl.GetColumnCount(_cursor);
+ }
+
+ public ColumnType GetColumnType(int index)
+ {
+ int type;
+ ResultType ret;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.GetItemType(_cursor, index, out type);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return (ColumnType)type;
+ }
+
+ public string GetColumnName(int index)
+ {
+ string retStr;
+ ResultType ret;
+ StringBuilder columnName = new StringBuilder();
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ columnName.Length = MaxColumnNameSize;
+ ret = Interop.DataControl.GetColumnName(_cursor, index, columnName);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ retStr = columnName.ToString();
+ columnName.Clear();
+ columnName = null;
+
+ return retStr;
+ }
+
+ public long GetRowCount()
+ {
+ return _rowCount;
+ }
+
+ public bool Next()
+ {
+ ResultType type = Interop.DataControl.Next(_cursor);
+
+ if (type != ResultType.Success)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool Prev()
+ {
+ ResultType type = Interop.DataControl.Prev(_cursor);
+
+ if (type != ResultType.Success)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool Reset()
+ {
+ ResultType type = Interop.DataControl.First(_cursor);
+
+ if (type != ResultType.Success)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int GetIntValue(int index)
+ {
+ ResultType ret;
+ int value;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.GetInt(_cursor, index, out value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return value;
+ }
+
+ public Int64 GetInt64Value(int index)
+ {
+ ResultType ret;
+ Int64 value;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.GetInt64(_cursor, index, out value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return value;
+ }
+
+ public double GetDoubleValue(int index)
+ {
+ ResultType ret;
+ double value;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ ret = Interop.DataControl.Getdouble(_cursor, index, out value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Column Index " + index.ToString());
+ }
+
+ return value;
+ }
+
+ public string GetStringValue(int index)
+ {
+ ResultType ret;
+ int size;
+ byte[] value;
+ string text;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ size = Interop.DataControl.GetItemSize(_cursor, index);
+ if (size < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, false, "Invalid size");
+ }
+
+ value = new byte[size + 1];
+ ret = Interop.DataControl.GetText(_cursor, index, value);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ text = Encoding.UTF8.GetString(value);
+
+ return text;
+ }
+
+ public byte[] GetBlobValue(int index)
+ {
+ ResultType ret;
+ int size;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnCount)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ size = Interop.DataControl.GetItemSize(_cursor, index);
+ if (size < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, false, "Invalid size");
+ }
+
+ byte_array = new byte[size];
+ ret = Interop.DataControl.GetBlob(_cursor, index, byte_array, size);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ return byte_array;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <Version>1.0.7</Version>
+ <Authors>Samsung Electronics</Authors>
+ <Copyright>© Samsung Electronics Co., Ltd All Rights Reserved</Copyright>
+ <Description>Provides the Data Control API for Tizen .NET</Description>
+ <PackageProjectUrl>https://www.tizen.org/</PackageProjectUrl>
+ <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
+ <PackageIconUrl>https://developer.tizen.org/sites/default/files/images/tizen-pinwheel-on-light-rgb_64_64.png</PackageIconUrl>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.3</TargetFramework>
+ <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>Tizen.Applications.DataControl.snk</AssemblyOriginatorKeyFile>
+ <PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.Diagnostics.Process" Version="4.3.0" PrivateAssets="All" />
+ <PackageReference Include="System.Threading.Thread" Version="4.3.0" PrivateAssets="All" />
+ <PackageReference Include="Tizen" Version="1.0.5" />
+ <PackageReference Include="Tizen.Applications.Common" Version="1.5.8" />
+ </ItemGroup>
+
+</Project>
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents BulkData class for DataControl bulk request.
+ /// </summary>
+ public class BulkData : IDisposable
+ {
+ private bool _disposed = false;
+ private Interop.DataControl.SafeBulkDataHandle _handle;
+
+ /// <summary>
+ /// Initializes BulkData class.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public BulkData()
+ {
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkCreate");
+ }
+
+ }
+
+ internal BulkData(Interop.DataControl.SafeBulkDataHandle handle)
+ {
+ ResultType ret;
+ int count, i;
+
+ ret = Interop.DataControl.BulkCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkCreate");
+ }
+
+ ret = Interop.DataControl.BulkGetCount(handle, out count);
+ for ( i = 0; i < count; i++)
+ {
+ IntPtr bundleHandle;
+ Bundle bundle;
+
+ ret = Interop.DataControl.BulkGetData(handle, i, out bundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundleHandle, false));
+ ret = Interop.DataControl.BulkAdd(_handle, bundle.SafeBundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkAdd");
+ }
+ }
+ }
+
+ internal Interop.DataControl.SafeBulkDataHandle SafeBulkDataHandle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Adds bulk data.
+ /// </summary>
+ /// <param name="data">Bulk data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public void Add(Bundle data)
+ {
+ ResultType ret;
+
+ if (data == null || data.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "data");
+ }
+
+ ret = Interop.DataControl.BulkAdd(_handle, data.SafeBundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkAdd");
+ }
+ }
+
+ /// <summary>
+ /// Gets current data count.
+ /// </summary>
+ public int GetCount()
+ {
+ int count;
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkGetCount(_handle, out count);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkGetCount");
+ }
+
+ return count;
+ }
+
+ /// <summary>
+ /// Returns the data at the given zero-based data index.
+ /// </summary>
+ /// <param name="index">Target data index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Bundle GetData(int index)
+ {
+ IntPtr bundlePtr;
+ Bundle bundle;
+ ResultType ret;
+
+ if (index < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "index");
+ }
+
+ ret = Interop.DataControl.BulkGetData(_handle, index, out bundlePtr);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundlePtr, false));
+ return bundle;
+ }
+
+ /// <summary>
+ /// Releases all resources used by the BulkData class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null && !_handle.IsInvalid)
+ {
+ _handle.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+
+ ~BulkData()
+ {
+ Dispose(false);
+ }
+ }
+
+ /// <summary>
+ /// Represents BulkResultData class for DataControl bulk request.
+ /// </summary>
+ public class BulkResultData : IDisposable
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private bool _disposed = false;
+ private Interop.DataControl.SafeBulkResultDataHandle _handle;
+ /// <summary>
+ /// Initializes BulkResultData class.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public BulkResultData()
+ {
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkResultCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true,"BulkResultCreate");
+ }
+ }
+
+ internal BulkResultData(Interop.DataControl.SafeBulkResultDataHandle handle)
+ {
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkResultCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true,"BulkResultCreate");
+ }
+
+ int count;
+ ret = Interop.DataControl.BulkResultGetCount(handle, out count);
+ for (int i = 0; i < count; i++)
+ {
+ IntPtr bundleHandle;
+ Bundle bundle;
+ int result;
+
+ ret = Interop.DataControl.BulkResultGetData(handle, i, out bundleHandle, out result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundleHandle, false));
+ ret = Interop.DataControl.BulkResultAdd(_handle, bundle.SafeBundleHandle, result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultAdd");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds bulk operation result data.
+ /// </summary>
+ /// <param name="data">Result data</param>
+ /// <param name="result">Result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public void Add(Bundle data, int result)
+ {
+ ResultType ret;
+
+ if (data == null || data.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "data");
+ }
+
+ ret = Interop.DataControl.BulkResultAdd(_handle, data.SafeBundleHandle, result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultAdd");
+ }
+ }
+
+ internal Interop.DataControl.SafeBulkResultDataHandle SafeBulkDataHandle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Gets current result data count.
+ /// </summary>
+ public int GetCount()
+ {
+ int count;
+ ResultType ret;
+
+ ret = Interop.DataControl.BulkResultGetCount(_handle, out count);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true,"BulkResultGetCount");
+ }
+
+ return count;
+ }
+
+ /// <summary>
+ /// Returns the result data at the given zero-based data index.
+ /// </summary>
+ /// <param name="index">Target result data index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Bundle GetData(int index)
+ {
+ IntPtr bundlePtr;
+ Bundle bundle;
+ ResultType ret;
+ int result;
+
+ if (index < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "index");
+ }
+
+ ret = Interop.DataControl.BulkResultGetData(_handle, index, out bundlePtr, out result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultGetData");
+ }
+
+ bundle = new Bundle(new SafeBundleHandle(bundlePtr, false));
+ return bundle;
+ }
+
+ /// <summary>
+ /// Returns the result at the given zero-based data index.
+ /// </summary>
+ /// <param name="index">Target result index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public int GetResult(int index)
+ {
+ IntPtr bundlePtr;
+ ResultType ret;
+ int result;
+
+ if (index < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "index");
+ }
+
+ ret = Interop.DataControl.BulkResultGetData(_handle, index, out bundlePtr, out result);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, true, "BulkResultGetData");
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Releases all resources used by the BulkResultData class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_handle != null && !_handle.IsInvalid)
+ {
+ _handle.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+
+ ~BulkResultData()
+ {
+ Dispose(false);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Tizen.Applications.DataControl.Core;
+using System.Threading;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents Consumer class for DataControl consumer application.
+ /// </summary>
+ public abstract class Consumer : IDisposable
+ {
+
+ private Interop.DataControl.SafeDataControlHandle _handle;
+ private string _dataID, _providerID;
+ private int _changeCallbackID = 0;
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private bool _disposed = false;
+ private static Mutex _lock = new Mutex();
+ private Interop.DataControl.DataChangeCallback _dataChangeCallback;
+ private Interop.DataControl.AddCallbackResultCallback _addCallbackResultCallback;
+
+ private static class CallbackManager
+ {
+ private static IDictionary<string, Interop.DataControl.MapResponseCallbacks> _mapResponseCallbacks = new Dictionary<string, Interop.DataControl.MapResponseCallbacks>();
+ private static IDictionary<string, Interop.DataControl.MapBulkAddResponseCallback> _mapBulkResponseCallback = new Dictionary<string, Interop.DataControl.MapBulkAddResponseCallback>();
+ private static IDictionary<string, Interop.DataControl.SqlResponseCallbacks> _sqlResponseCallbacks = new Dictionary<string, Interop.DataControl.SqlResponseCallbacks>();
+ private static IDictionary<string, Interop.DataControl.SqlBulkInsertResponseCallback> _sqlBulkResponseCallback = new Dictionary<string, Interop.DataControl.SqlBulkInsertResponseCallback>();
+ private static IDictionary<int, Consumer> _reqConsumerDictionary = new Dictionary<int, Consumer>();
+ private static IDictionary<string, int> _reqProviderList = new Dictionary<string, int>();
+ private static void InsertResponse(int reqId, IntPtr provider, long insertedRowId, bool providerResult, string error, IntPtr userData)
+ {
+ Log.Debug(LogTag, $"InsertResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}, rowID : {insertedRowId.ToString()}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnInsertResult(new InsertResult(insertedRowId, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void BulkInsertResponse(int reqId, IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData)
+ {
+ BulkResultData brd;
+ Log.Debug(LogTag, $"BulkInsertResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (bulkResults != IntPtr.Zero)
+ {
+ brd = new BulkResultData(new Interop.DataControl.SafeBulkResultDataHandle(bulkResults, false));
+ }
+ else
+ {
+ brd = new BulkResultData();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, bulkResults is null");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnBulkInsertResult(new BulkInsertResult(brd, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void SelectResponse(int reqId, IntPtr provider, IntPtr cursor, bool providerResult, string error, IntPtr userData)
+ {
+ MatrixCursor dmc;
+ Log.Debug(LogTag, $"SelectResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (cursor != IntPtr.Zero)
+ {
+ try
+ {
+ dmc = CloneCursor(new CloneCursorCore(new Interop.DataControl.SafeCursorHandle(cursor, true)));
+ }
+ catch (Exception ex)
+ {
+ dmc = new MatrixCursor();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, {ex.ToString()}");
+ }
+ }
+ else
+ {
+ dmc = new MatrixCursor();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, cursor is null");
+ }
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnSelectResult(new SelectResult(dmc, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void UpdateResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnUpdateResult(new UpdateResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void DeleteResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnDeleteResult(new DeleteResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapGetResponse(int reqId, IntPtr provider, string[] valueList, int valueCount, bool providerResult, string error, IntPtr userData)
+ {
+ MapGetResult mgr;
+ Log.Debug(LogTag, $"MapGetResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (valueList !=null)
+ {
+ mgr = new MapGetResult(valueList, providerResult);
+ }
+ else
+ {
+ mgr = new MapGetResult(new string[0], providerResult);
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, valueList is null");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapGetResult(mgr);
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapBulkAddResponse(int reqId, IntPtr provider, IntPtr bulkResults, bool providerResult, string error, IntPtr userData)
+ {
+ BulkResultData brd;
+ Log.Debug(LogTag, $"MapBulkAddResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ if (bulkResults != IntPtr.Zero)
+ {
+ brd = new BulkResultData(new Interop.DataControl.SafeBulkResultDataHandle(bulkResults, false));
+ }
+ else
+ {
+ brd = new BulkResultData();
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, bulkResults is null");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapBulkAddResult(new MapBulkAddResult(brd, providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapAddResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ Log.Debug(LogTag, $"MapAddResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapAddResult(new MapAddResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapSetResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ Log.Debug(LogTag, $"MapSetResponse {reqId.ToString()}");
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapSetResult(new MapSetResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static void MapRemoveResponse(int reqId, IntPtr provider, bool providerResult, string error, IntPtr userData)
+ {
+ if (!_reqConsumerDictionary.ContainsKey(reqId))
+ {
+ Log.Error(LogTag, $"Invalid reqId {reqId.ToString()}");
+ return;
+ }
+
+ if (!providerResult)
+ {
+ Log.Error(LogTag, $"reqId {reqId.ToString()}, error : {error}");
+ }
+
+ Consumer consumer = _reqConsumerDictionary[reqId];
+ consumer.OnMapRemoveResult(new MapRemoveResult(providerResult));
+ _reqConsumerDictionary.Remove(reqId);
+ }
+
+ private static MatrixCursor CloneCursor(CloneCursorCore coreCursor)
+ {
+ int size = coreCursor.GetColumnCount();
+ int i;
+ string[] name = new string[size];
+ object[] newRow = new object[size];
+ ColumnType[] type = new ColumnType[size];
+
+ for (i = 0; i < size; i++)
+ {
+ name[i] = coreCursor.GetColumnName(i);
+ type[i] = coreCursor.GetColumnType(i);
+ }
+
+ MatrixCursor dmc = new MatrixCursor(name, type);
+
+ if (coreCursor.GetRowCount() <= 0)
+ {
+ return dmc;
+ }
+
+ coreCursor.Reset();
+ do
+ {
+ for (i = 0; i < size; i++)
+ {
+ switch (type[i])
+ {
+ case ColumnType.ColumnTypeInt:
+ newRow[i] = coreCursor.GetInt64Value(i);
+ break;
+ case ColumnType.ColumnTypeDouble:
+ newRow[i] = coreCursor.GetDoubleValue(i);
+ break;
+ case ColumnType.ColumnTypeBlob:
+ newRow[i] = coreCursor.GetBlobValue(i);
+ break;
+ case ColumnType.ColumnTypeString:
+ newRow[i] = coreCursor.GetStringValue(i);
+ break;
+ }
+ }
+
+ dmc.AddRow(newRow);
+ }
+ while (coreCursor.Next());
+
+ return dmc;
+ }
+
+ internal static void RegisterReqId(int reqId, Consumer consumer)
+ {
+ _lock.WaitOne();
+ _reqConsumerDictionary.Add(reqId, consumer);
+ _lock.ReleaseMutex();
+ }
+
+ internal static void RegisterCallback(Interop.DataControl.SafeDataControlHandle handle, string providerId)
+ {
+ ResultType ret;
+ Interop.DataControl.SqlResponseCallbacks sqlCallbacks;
+ Interop.DataControl.SqlBulkInsertResponseCallback sqlBulkCallbacks;
+ Interop.DataControl.MapResponseCallbacks mapCallbacks;
+ Interop.DataControl.MapBulkAddResponseCallback mapBulkCallbacks;
+ bool sqlRegistered = false;
+ bool mapRegistered = false;
+
+ if (_reqProviderList.ContainsKey(providerId))
+ {
+ _reqProviderList[providerId]++;
+ Log.Error(LogTag, "The data control is already set");
+ return;
+ }
+
+ sqlCallbacks.Insert = new Interop.DataControl.SqlInsertResponseCallback(InsertResponse);
+ sqlCallbacks.Select = new Interop.DataControl.SqlSelectResponseCallback(SelectResponse);
+ sqlCallbacks.Update = new Interop.DataControl.SqlUpdateResponseCallback(UpdateResponse);
+ sqlCallbacks.Delete = new Interop.DataControl.SqlDeleteResponseCallback(DeleteResponse);
+ ret = Interop.DataControl.RegisterSqlResponseCallback(handle, ref sqlCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the sql callback function is failed : " + ret);
+ }
+ else
+ {
+ _sqlResponseCallbacks.Add(providerId, sqlCallbacks);
+ sqlRegistered = true;
+ }
+
+ sqlBulkCallbacks = new Interop.DataControl.SqlBulkInsertResponseCallback(BulkInsertResponse);
+ ret = Interop.DataControl.RegisterSqlBulkResponseCallback(handle, sqlBulkCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the sql bulk callback function is failed : " + ret);
+ }
+ else
+ {
+ _sqlBulkResponseCallback.Add(providerId, sqlBulkCallbacks);
+ }
+
+ mapCallbacks.Add = new Interop.DataControl.MapAddResponseCallback(MapAddResponse);
+ mapCallbacks.Set = new Interop.DataControl.MapSetResponseCallback(MapSetResponse);
+ mapCallbacks.Get = new Interop.DataControl.MapGetResponseCallback(MapGetResponse);
+ mapCallbacks.Remove = new Interop.DataControl.MapRemoveResponseCallback(MapRemoveResponse);
+ ret = Interop.DataControl.RegisterMapResponse(handle, ref mapCallbacks, IntPtr.Zero);
+
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the map callback function is failed : " + ret);
+ }
+ else
+ {
+ _mapResponseCallbacks.Add(providerId, mapCallbacks);
+ mapRegistered = true;
+ }
+
+ mapBulkCallbacks = new Interop.DataControl.MapBulkAddResponseCallback(MapBulkAddResponse);
+ ret = Interop.DataControl.RegisterMapBulkResponseCallback(handle, mapBulkCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Registering the map bulk callback function is failed : " + ret);
+ }
+ else
+ {
+ _mapBulkResponseCallback.Add(providerId, mapBulkCallbacks);
+ }
+
+ if (!mapRegistered && !sqlRegistered)
+ {
+ ErrorFactory.ThrowException(ret, true, "Registering the response callback function is failed");
+ }
+
+ _reqProviderList.Add(providerId, 1);
+ }
+
+ internal static void UnregisterCallback(Interop.DataControl.SafeDataControlHandle handle, string providerId)
+ {
+ int count;
+
+ _reqProviderList[providerId]--;
+ count = _reqProviderList[providerId];
+ if (count <= 0)
+ {
+ _reqProviderList.Remove(providerId);
+
+ _mapResponseCallbacks.Remove(providerId);
+ Interop.DataControl.UnregisterMapResponse(handle);
+
+ _mapBulkResponseCallback.Remove(providerId);
+ Interop.DataControl.UnregisterMapBulkResponseCallback(handle);
+
+ _sqlResponseCallbacks.Remove(providerId);
+ Interop.DataControl.UnregisterSqlResponseCallback(handle);
+
+ _sqlBulkResponseCallback.Remove(providerId);
+ Interop.DataControl.UnregisterSqlBulkResponseCallback(handle);
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Sends insert request to provider application.
+ /// </summary>
+ /// <remarks>OnInsertResult will recieve result of this API</remarks>
+ /// <param name="insertData">Insert data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Insert(Bundle insertData)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (insertData == null || insertData.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Insert(_handle, insertData.SafeBundleHandle, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Insert");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends select request to provider application.
+ /// </summary>
+ /// <remarks>OnSelectResult will recieve result of this API</remarks>
+ /// <param name="columnList">Select target column list</param>
+ /// <param name="where">Where statement for select query</param>
+ /// <param name="order">Order statement for select query</param>
+ /// <param name="pageNumber">Select target page number</param>
+ /// <param name="countPerPage">Select row count per page</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Select(string[] columnList, string where, string order, int pageNumber = 1, int countPerPage = 20)
+ {
+ int reqId, i;
+ ResultType ret;
+ if (columnList == null || columnList.Length == 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column_list");
+ }
+
+ for (i = 0; i < columnList.Length; i++)
+ {
+ if (string.IsNullOrEmpty(columnList[i]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column_list index " + i.ToString());
+ }
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Select(_handle, columnList, columnList.Length, where, order, pageNumber, countPerPage, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Select");
+ }
+ Log.Info(LogTag, "select end. " + reqId.ToString());
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends delete request to provider application.
+ /// </summary>
+ /// <remarks>OnDeleteResult will recieve result of this API</remarks>
+ /// <param name="where">Where statement for delete query</param>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Delete(string where)
+ {
+ int reqId;
+ ResultType ret;
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Delete(_handle, where, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Delete");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends update request to provider application.
+ /// </summary>
+ /// <remarks>OnUpdateResult will recieve result of this API</remarks>
+ /// <param name="updateData">Update data</param>
+ /// <param name="where">Where statement for query</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void Update(Bundle updateData, string where)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (updateData == null || updateData.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
+ }
+
+ if (string.IsNullOrEmpty(where))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "where");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.Update(_handle, updateData.SafeBundleHandle, where, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Update");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends bulk insert request to provider application.
+ /// </summary>
+ /// <remarks>OnBulkInsertResult will recieve result of this API</remarks>
+ /// <param name="insertData">Bulk insert data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void BulkInsert(BulkData insertData)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (insertData == null || insertData.SafeBulkDataHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "insertData");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.BulkInsert(_handle, insertData.SafeBulkDataHandle, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "BulkInsert");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map add request to provider application.
+ /// </summary>
+ /// <remarks>OnMapAddResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value to add</param>
+ /// <param name="value">The value to add</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapAdd(string key, string value)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapAdd(_handle, key, value, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapAdd");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map get request to provider application.
+ /// </summary>
+ /// <remarks>OnMapGetResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value list to obtain</param>
+ /// <param name="pageNumber">The page number of the value set</param>
+ /// <param name="countPerPage">The desired maximum count of the data items per page</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapGet(string key, int pageNumber = 1, int countPerPage = 20)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || pageNumber <= 0 || countPerPage <= 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapGet(_handle, key, out reqId, pageNumber, countPerPage);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapGet");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map remove request to provider application.
+ /// </summary>
+ /// <remarks>OnMapRemoveResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value to remove</param>
+ /// <param name="value">The value to remove</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapRemove(string key, string value)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapRemove(_handle, key, value, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapRemove");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map set request to provider application.
+ /// </summary>
+ /// <remarks>OnMapSetResult will recieve result of this API</remarks>
+ /// <param name="key">The key of the value to replace</param>
+ /// <param name="oldValue">The value to be replaced</param>
+ /// <param name="newValue"> The new value that replaces the existing value</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapSet(string key, string oldValue, string newValue)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(oldValue) || string.IsNullOrEmpty(newValue))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.MapSet(_handle, key, oldValue, newValue, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "MapSet");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ /// <summary>
+ /// Sends map bulk add request to provider application.
+ /// </summary>
+ /// <remarks>OnMapBulkAddResult will recieve result of this API</remarks>
+ /// <param name="addData">Map bulk add data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(1MB)</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void MapBulkAdd(BulkData addData)
+ {
+ int reqId;
+ ResultType ret;
+
+ if (addData == null || addData.SafeBulkDataHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "addData");
+ }
+
+ _lock.WaitOne();
+ ret = Interop.DataControl.BulkAdd(_handle, addData.SafeBulkDataHandle, out reqId);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "BulkAdd");
+ }
+
+ CallbackManager.RegisterReqId(reqId, this);
+ }
+
+ private void DataChange(IntPtr handle, ChangeType type, IntPtr data, IntPtr userData)
+ {
+ OnDataChange(type, new Bundle(new SafeBundleHandle(data, false)));
+ }
+
+ private void DataChangeListenResult(IntPtr handle, ResultType type, int callbackId, IntPtr userData)
+ {
+ OnDataChangeListenResult(new DataChangeListenResult(type));
+ }
+
+ /// <summary>
+ /// Listen DataChange event
+ /// </summary>
+ /// <remarks>OnDataChangeListenResult will recieve result of this API</remarks>
+ /// <remarks>If success, OnDataChange will recieve DataChange event</remarks>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ public void DataChangeListen()
+ {
+ ResultType ret;
+ _lock.WaitOne();
+ /* Only one callback is allowed for every obejct */
+ if (_changeCallbackID > 0)
+ {
+ _lock.ReleaseMutex();
+ return;
+ }
+ _dataChangeCallback = new Interop.DataControl.DataChangeCallback(DataChange);
+ _addCallbackResultCallback = new Interop.DataControl.AddCallbackResultCallback(DataChangeListenResult);
+ ret = Interop.DataControl.AddDataChangeCallback(_handle, _dataChangeCallback, IntPtr.Zero,
+ _addCallbackResultCallback , IntPtr.Zero, out _changeCallbackID);
+ _lock.ReleaseMutex();
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "DataChangeListen");
+ }
+ }
+
+ /// <summary>
+ /// Initializes Consumer class with providerId and dataId.
+ /// </summary>
+ /// <param name="providerId">DataControl Provider ID</param>
+ /// <param name="dataId">DataControl Data ID</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public Consumer(string providerId, string dataId)
+ {
+ ResultType ret;
+
+ if (string.IsNullOrEmpty(providerId))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "providerId");
+ }
+
+ if (string.IsNullOrEmpty(dataId))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "dataId");
+ }
+
+ ret = Interop.DataControl.DataControlCreate(out _handle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false, "Creating data control handle is failed");
+ }
+
+ Interop.DataControl.DataControlSetProviderId(_handle, providerId);
+ Interop.DataControl.DataControlSetDataId(_handle, dataId);
+ CallbackManager.RegisterCallback(_handle, providerId);
+ _dataID = dataId;
+ _providerID = providerId;
+ }
+
+ ~Consumer()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the DataChangeListen result is received.
+ /// </summary>
+ protected virtual void OnDataChangeListenResult(DataChangeListenResult result)
+ {
+ Log.Info(LogTag, "The OnDataChangeListenResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the data change event is received.
+ /// </summary>
+ protected virtual void OnDataChange(ChangeType type, Bundle data)
+ {
+ Log.Info(LogTag, "The OnDataChange is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the select response is received.
+ /// </summary>
+ protected abstract void OnSelectResult(SelectResult result);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the insert response is received.
+ /// </summary>
+ protected abstract void OnInsertResult(InsertResult result);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the update response is received.
+ /// </summary>
+ protected abstract void OnUpdateResult(UpdateResult result);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the delete response is received.
+ /// </summary>
+ protected abstract void OnDeleteResult(DeleteResult result);
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the BulkInsert response is received.
+ /// </summary>
+ protected virtual void OnBulkInsertResult(BulkInsertResult result)
+ {
+ Log.Info(LogTag, "The OnBulkInsertResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map get response is received.
+ /// </summary>
+ protected virtual void OnMapGetResult(MapGetResult result)
+ {
+ Log.Info(LogTag, "The OnMapGetResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map add response is received.
+ /// </summary>
+ protected virtual void OnMapAddResult(MapAddResult result)
+ {
+ Log.Info(LogTag, "The OnMapAddResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map set response is received.
+ /// </summary>
+ protected virtual void OnMapSetResult(MapSetResult result)
+ {
+ Log.Info(LogTag, "The OnMapSetResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map remove response is received.
+ /// </summary>
+ protected virtual void OnMapRemoveResult(MapRemoveResult result)
+ {
+ Log.Info(LogTag, "The OnMapRemoveResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the BulkAdd response is received.
+ /// </summary>
+ protected virtual void OnMapBulkAddResult(MapBulkAddResult result)
+ {
+ Log.Info(LogTag, "The OnMapBulkAddResult is not implemented.");
+ }
+
+ /// <summary>
+ /// Releases the unmanaged resourced used by the Consumer class specifying whether to perform a normal dispose operation.
+ /// </summary>
+ /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (_changeCallbackID > 0)
+ {
+ Interop.DataControl.RemoveDataChangeCallback(_handle, _changeCallbackID);
+ }
+
+ CallbackManager.UnregisterCallback(_handle, _providerID);
+ _handle.Dispose();
+ _disposed = true;
+ }
+
+ if (disposing)
+ {
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Consumer class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Tizen.Applications.DataControl
+{
+ internal static class ErrorFactory
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+
+ internal static void ThrowException(ResultType errorCode, bool ignoreType, string errorMessage = null,
+ [CallerMemberName] string memberName = "", [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0)
+ {
+ Log.Error(LogTag, $"{memberName}({lineNumber.ToString()}) : {filePath}");
+ if (ignoreType)
+ {
+ throw new InvalidOperationException(string.IsNullOrEmpty(errorMessage) ? "error code : " + errorCode.ToString() :
+ $"{errorMessage} - {errorCode}");
+ }
+
+ switch (errorCode)
+ {
+ case ResultType.Success:
+ return;
+ case ResultType.OutOfMemory:
+ case ResultType.IoError:
+ throw new InvalidOperationException(string.IsNullOrEmpty(errorMessage) ? "error code : " + errorCode.ToString() :
+ $"{errorMessage} - {errorCode}");
+ case ResultType.InvalidParameter:
+ Log.Error(LogTag, "Invalid parameter : " + errorMessage);
+ throw new ArgumentException(string.IsNullOrEmpty(errorMessage) ? "Invalid parameter" : "Invalid parameter : " + errorMessage);
+ case ResultType.PermissionDenied:
+ Log.Error(LogTag, "Permission denied : " + errorMessage);
+ throw new UnauthorizedAccessException(string.IsNullOrEmpty(errorMessage) ? "Permission denied" : "Permission denied : " + errorMessage);
+ case ResultType.MaxExceed:
+ Log.Error(LogTag, "Too long argument : " + errorMessage);
+ throw new ArgumentOutOfRangeException(string.IsNullOrEmpty(errorMessage) ? "Too long argument" : "Too long argument : " + errorMessage);
+ default:
+ Log.Error(LogTag, $"Unknown error : {errorMessage} - {errorCode}");
+ throw new InvalidOperationException(string.IsNullOrEmpty(errorMessage) ? "Unknown error : " + errorCode.ToString() :
+ $"Unknown error : {errorMessage} - {errorCode}");
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// This interface is for DataControl cursor.
+ /// </summary>
+ public interface ICursor
+ {
+ /// <summary>
+ /// Gets a column count.
+ /// </summary>
+ int GetColumnCount();
+ /// <summary>
+ /// Gets a column type.
+ /// </summary>
+ /// <param name="index">The index of column.</param>
+ ColumnType GetColumnType(int index);
+ /// <summary>
+ /// Gets a column name.
+ /// </summary>
+ /// <param name="index">The index of column.</param>
+ string GetColumnName(int index);
+ /// <summary>
+ /// Gets the numbers of rows in the cursor.
+ /// </summary>
+ long GetRowCount();
+ /// <summary>
+ /// Gets a next row.
+ /// </summary>
+ bool Next();
+ /// <summary>
+ /// Gets a prev row.
+ /// </summary>
+ bool Prev();
+ /// <summary>
+ /// Gets a first row.
+ /// </summary>
+ bool Reset();
+ /// <summary>
+ /// / Gets an int value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ int GetIntValue(int index);
+ /// <summary>
+ /// / Gets an int64 value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ Int64 GetInt64Value(int index);
+ /// <summary>
+ /// Gets an double value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ double GetDoubleValue(int index);
+ /// <summary>
+ /// Gets an string value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ string GetStringValue(int index);
+ /// <summary>
+ /// Gets a blob value.
+ /// </summary>
+ /// <param name="index">The index of row.</param>
+ byte[] GetBlobValue(int index);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+using System.Threading;
+using System.Diagnostics;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents MatrixCursor class for DataControl provider's matrix cursor.
+ /// </summary>
+ public class MatrixCursor : IDisposable, ICursor
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private FileStream _fs;
+ private bool _disposed = false;
+ private string _cursorPath;
+ private long _rowCount = 0;
+ private long _rowCountPosition = 0;
+ private int _currentRowIndex = 0;
+ private IList<long> _rowFieldOffset = new List<long>();
+ private string[] _columnNames;
+ private ColumnType[] _columnTypes;
+ private const int ColumnTypeNull = 5;
+
+ private byte[] GetValue(int index)
+ {
+ byte[] int_tmp = new byte[sizeof(int)];
+ byte[] ret_array;
+ ColumnType type;
+ int size, read_len;
+
+ MoveToColumn(index);
+
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column Type " + index.ToString());
+ }
+
+ type = (ColumnType)BitConverter.ToInt32(int_tmp, 0);
+
+ if (type != _columnTypes[index])
+ {
+ if ((int)type == ColumnTypeNull &&
+ (_columnTypes[index] == ColumnType.ColumnTypeBlob || _columnTypes[index] == ColumnType.ColumnTypeString))
+ {
+ return null; /* null type */
+ }
+
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Type mismatch " + index.ToString());
+ }
+
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column size " + index.ToString());
+ }
+
+ size = BitConverter.ToInt32(int_tmp, 0);
+
+ if (size < 0)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Invalid data size " + index.ToString());
+ }
+
+ ret_array = new byte[size];
+ read_len = _fs.Read(ret_array, 0, ret_array.Length);
+ if (read_len != ret_array.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column value size " + index.ToString());
+ return null;
+ }
+
+ return ret_array;
+ }
+
+ private void MoveToColumn(int ColumnIndex)
+ {
+ int i, tmp_position;
+ byte[] int_tmp = new byte[sizeof(int)];
+ int read_len;
+ long seek_len;
+
+ seek_len = _fs.Seek(_rowFieldOffset[_currentRowIndex], SeekOrigin.Begin);
+ if (seek_len != _rowFieldOffset[_currentRowIndex])
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Row index " + _currentRowIndex.ToString());
+ }
+
+ for (i = 0; i < ColumnIndex; i++)
+ {
+ /* type(int) size(int) value */
+ switch (_columnTypes[i])
+ {
+ case ColumnType.ColumnTypeInt:
+ tmp_position = sizeof(int) * 2 + sizeof(Int64);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ break;
+ case ColumnType.ColumnTypeDouble:
+ tmp_position = sizeof(int) * 2 + sizeof(double);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ break;
+ case ColumnType.ColumnTypeString:
+ tmp_position = sizeof(int);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column Index " + ColumnIndex.ToString());
+ }
+
+ tmp_position = BitConverter.ToInt32(int_tmp, 0);
+
+ if (tmp_position > 0)
+ {
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ }
+
+ break;
+ case ColumnType.ColumnTypeBlob:
+ tmp_position = sizeof(int);
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+
+ read_len = _fs.Read(int_tmp, 0, int_tmp.Length);
+ if (read_len != int_tmp.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.IoError, true, "Column Index " + ColumnIndex.ToString());
+ }
+
+ tmp_position = BitConverter.ToInt32(int_tmp, 0);
+
+ if (tmp_position > 0)
+ {
+ _fs.Seek(tmp_position, SeekOrigin.Current);
+ }
+
+ break;
+ }
+ }
+
+ }
+
+ internal FileStream GetFileStream()
+ {
+ return _fs;
+ }
+
+ /// <summary>
+ /// Gets column count of MatrixCursor.
+ /// </summary>
+ public int GetColumnCount()
+ {
+ return _columnTypes.Length;
+ }
+
+ /// <summary>
+ /// Returns the column type at the given zero-based column index.
+ /// </summary>
+ /// <param name="index">Target column index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public ColumnType GetColumnType(int index)
+ {
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ return _columnTypes[index];
+ }
+
+ /// <summary>
+ /// Returns the column name at the given zero-based column index.
+ /// </summary>
+ /// <param name="index">Target column index</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public string GetColumnName(int index)
+ {
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ return _columnNames[index];
+ }
+
+ /// <summary>
+ /// Gets MatrixCursor's row count.
+ /// </summary>
+ public long GetRowCount()
+ {
+ return _rowCount;
+ }
+
+ /// <summary>
+ /// Move the MatrixCursor to the next row.
+ /// </summary>
+ public bool Next()
+ {
+ if (_currentRowIndex >= _rowCount - 1)
+ {
+ return false;
+ }
+
+ _currentRowIndex++;
+ return true;
+ }
+
+ /// <summary>
+ /// Move the MatrixCursor to the previous row.
+ /// </summary>
+ public bool Prev()
+ {
+ if (_currentRowIndex <= 0)
+ {
+ return false;
+ }
+
+ _currentRowIndex--;
+ return true;
+ }
+
+ /// <summary>
+ /// Move the MatrixCursor to the first row.
+ /// </summary>
+ public bool Reset()
+ {
+ _currentRowIndex = 0;
+ return true;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a int.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public int GetIntValue(int index)
+ {
+ int ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ if (byte_array == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+ ret = BitConverter.ToInt32(byte_array, 0);
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a int64.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Int64 GetInt64Value(int index)
+ {
+ Int64 ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ if (byte_array == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+ ret = BitConverter.ToInt64(byte_array, 0);
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a double.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public double GetDoubleValue(int index)
+ {
+ double ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ if (byte_array == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+ ret = BitConverter.ToDouble(byte_array, 0);
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a string.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public string GetStringValue(int index)
+ {
+ string ret;
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+
+ if (byte_array == null)
+ {
+ return null;
+ }
+
+ ret = Encoding.UTF8.GetString(byte_array).TrimEnd('\0');
+ return ret;
+
+ }
+
+ /// <summary>
+ /// Returns the value of the requested column as a blob.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public byte[] GetBlobValue(int index)
+ {
+ byte[] byte_array;
+
+ if (index < 0 || index >= _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ byte_array = GetValue(index);
+ return byte_array;
+ }
+
+ private static class FileManager
+ {
+ private static readonly string DATACONTROL_DIRECTORY = "/tmp/";
+ private static Dictionary<int, int> fileTable = new Dictionary<int, int>();
+ public static string OpenFileStream(int threadID)
+ {
+ string path;
+ int index;
+
+ if (threadID < 0)
+ {
+ Log.Error(LogTag, "threadID is " + threadID.ToString());
+ return null;
+ }
+
+ if (fileTable.ContainsKey(threadID) == false)
+ {
+ fileTable.Add(threadID, 0);
+ }
+
+ index = fileTable[threadID];
+ index++;
+ fileTable[threadID] = index;
+
+ path = DATACONTROL_DIRECTORY + Application.Current.ApplicationInfo.ApplicationId + "_" + Process.GetCurrentProcess().Id.ToString() + "_" + threadID.ToString() + "_" + index.ToString();
+
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Initializes MatrixCursor class with columnNames and columnTypes.
+ /// </summary>
+ /// <param name="columnNames">MatrixCursor's column name list</param>
+ /// <param name="columnTypes">MatrixCursor's column type list</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ public MatrixCursor(string[] columnNames, ColumnType[] columnTypes)
+ {
+ byte[] byte_tmp, length_tmp, string_tmp;
+ int i, total_len_of_column_names = 0;
+
+ if (columnNames == null || columnTypes == null ||
+ (columnNames.Length != columnTypes.Length) || columnNames.Length < 1)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ for (i = 0; i < columnNames.Length; i++)
+ {
+ if (string.IsNullOrEmpty(columnNames[i]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "columnNames index " + i.ToString());
+ }
+ }
+
+ for (i = 0; i < columnTypes.Length; i++)
+ {
+ if ( columnTypes[i] < ColumnType.ColumnTypeInt || columnTypes[i] > ColumnType.ColumnTypeBlob)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "columnTypes index" + i.ToString());
+ }
+ }
+
+ _columnNames = columnNames;
+ _columnTypes = columnTypes;
+
+ _cursorPath = FileManager.OpenFileStream(Thread.CurrentThread.ManagedThreadId);
+ if (_cursorPath == null)
+ {
+ Log.Error(LogTag, "Unable to create a cursor file : " + _cursorPath);
+ ErrorFactory.ThrowException(ResultType.IoError, true);
+ }
+
+ _fs = new FileStream(_cursorPath, FileMode.Create);
+ /* column count */
+ byte_tmp = BitConverter.GetBytes(columnNames.Length);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+
+ /* column type */
+ for (i = 0; i < columnTypes.Length; i++)
+ {
+ byte_tmp = BitConverter.GetBytes((int)_columnTypes[i]);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+ }
+
+ /* column name */
+ for (i = 0; i < columnTypes.Length; i++)
+ {
+ string_tmp = Encoding.UTF8.GetBytes(columnNames[i]);
+ byte_tmp = new byte[string_tmp.Length + 1];/*insert null */
+
+ string_tmp.CopyTo(byte_tmp, 0);
+
+ length_tmp = BitConverter.GetBytes(byte_tmp.Length);
+ total_len_of_column_names += length_tmp.Length;
+
+ _fs.Write(length_tmp, 0, length_tmp.Length);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+ }
+
+ /* total length of column names */
+ byte_tmp = BitConverter.GetBytes(total_len_of_column_names);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+
+ _rowCountPosition = _fs.Position;
+ /* row count */
+ byte_tmp = BitConverter.GetBytes(_rowCount);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+ _fs.Flush();
+ }
+
+ internal MatrixCursor()
+ {
+ _columnNames = new string[0];
+ _columnTypes = new ColumnType[0];
+ _fs = null;
+ _cursorPath = null;
+ }
+
+ /// <summary>
+ /// Adds a new row to the end with the given column values.
+ /// </summary>
+ /// <param name="columnValues">New column values</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public void AddRow(object[] columnValues)
+ {
+ int i, size = 0;
+ byte[] type_array, length_array, value_array = null, string_array, byte_tmp;
+
+ if (columnValues == null || columnValues.Length <= 0 || columnValues.Length != _columnTypes.Length)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false);
+ }
+
+ using (MemoryStream ms = new MemoryStream())
+ {
+ for (i = 0; i < _columnTypes.Length; i++)
+ {
+ type_array = BitConverter.GetBytes((int)_columnTypes[i]);
+ switch (_columnTypes[i])
+ {
+ case ColumnType.ColumnTypeInt:
+ if (!(columnValues[i] is Int64) && !(columnValues[i] is Int32))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ value_array = BitConverter.GetBytes(Convert.ToUInt64(columnValues[i]));
+ size = value_array.Length;
+ break;
+ case ColumnType.ColumnTypeDouble:
+ if (!(columnValues[i] is Double))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ value_array = BitConverter.GetBytes(Convert.ToDouble(columnValues[i]));
+ size = value_array.Length;
+ break;
+ case ColumnType.ColumnTypeString:
+ if (columnValues[i] == null)
+ {
+ type_array = BitConverter.GetBytes(ColumnTypeNull);
+ size = 0;
+ break;
+ }
+
+ if (!(columnValues[i] is string))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ string_array = Encoding.UTF8.GetBytes(Convert.ToString(columnValues[i]));
+ value_array = new byte[string_array.Length + 1];/*insert null */
+ string_array.CopyTo(value_array, 0);
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeBlob:
+ if (columnValues[i] == null)
+ {
+ type_array = BitConverter.GetBytes(ColumnTypeNull);
+ size = 0;
+ break;
+ }
+
+ if (!(columnValues[i] is byte[]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "Type mismatch :Index " + i.ToString());
+ }
+
+ value_array = (byte[])columnValues[i];
+ size = value_array.Length;
+ break;
+ }
+
+ ms.Write(type_array, 0, type_array.Length);
+
+ length_array = BitConverter.GetBytes(size);
+ ms.Write(length_array, 0, length_array.Length);
+ if (size > 0)
+ {
+ ms.Write(value_array, 0, value_array.Length);
+ }
+ }
+
+ /* update row count */
+ _rowCount++;
+ byte_tmp = BitConverter.GetBytes(_rowCount);
+ _fs.Seek(_rowCountPosition, SeekOrigin.Begin);
+ _fs.Write(byte_tmp, 0, byte_tmp.Length);
+
+ _fs.Seek(0, SeekOrigin.End);
+
+ _rowFieldOffset.Add(_fs.Position);
+ ms.WriteTo(_fs);/* row data */
+ _fs.Flush();
+
+ Log.Debug(LogTag, "_fs pos = " + _fs.Position.ToString());
+ Log.Debug(LogTag, "_fs len = " + _fs.Length.ToString());
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the MatrixCursor class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (!string.IsNullOrEmpty(_cursorPath))
+ {
+ FileInfo fi = new FileInfo(_cursorPath);
+
+ if (_fs != null)
+ {
+ _fs.Dispose();
+ }
+
+ if (fi.Exists)
+ {
+ fi.Delete();
+ }
+ }
+
+ _disposed = true;
+ }
+
+ if (disposing)
+ {
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ ~MatrixCursor()
+ {
+ Dispose(false);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+using Tizen.Applications.DataControl;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// Represents Provider class for DataControl provider application.
+ /// </summary>
+ public abstract class Provider : IDisposable
+ {
+ private const string LogTag = "Tizen.Applications.DataControl";
+ private static IDictionary<string, Provider> _providerDict = new Dictionary<string, Provider>();
+ private static Interop.DataControl.SqlRequestCallbacks _sqlRequestCallbacks;
+ private static Interop.DataControl.MapRequestCallbacks _mapRequestCallbacks;
+ private IntPtr _nativeHandle;
+ private static Interop.DataControl.DataChangeConsumerFilterCb _filterCallback;
+ private static int _filterCallbackID;
+ private static bool _filterRegistered;
+ private static Interop.DataControl.SqlBulkInsertRequestCallback _sqlBulkCallback;
+ private static Interop.DataControl.MapBulkAddRequestCallback _mapBulkCallback;
+ private static Mutex _lock = new Mutex();
+ private bool _disposed = false;
+ private bool _isRunning = false;
+
+ /// <summary>
+ /// Gets the data ID
+ /// </summary>
+ public string DataID
+ {
+ get;
+ private set;
+ }
+
+ private static bool DataChangeListenFilter(IntPtr handlePtr, string consumerAppid, IntPtr userData)
+ {
+ Provider provider;
+ DataChangeListenResult result;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return false;
+ }
+
+ result = provider.OnDataChangeListenRequest(consumerAppid);
+ if (result == null || result.Result != ResultType.Success)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ private enum OperationType : short
+ {
+ Select,
+ Update,
+ Insert,
+ Delete
+ }
+
+ private static string CreateSelectQuery(IntPtr handlePtr, string[] columnList, int columnCount, string where, string order, int pageNum, int countPerPage)
+ {
+ Interop.DataControl.SafeDataControlHandle handle = new Interop.DataControl.SafeDataControlHandle(handlePtr, false);
+ string query = "SELECT";
+ string dataId;
+ if (columnList == null)
+ {
+ query += " * ";
+ }
+ else
+ {
+ for (int i = 0; i < columnCount; i++)
+ {
+ if (i != 0)
+ {
+ query += ",";
+ }
+
+ query += " " + columnList[i];
+ }
+ }
+
+ Interop.DataControl.DataControlGetDataId(handle, out dataId);
+ query += " FROM " + dataId;
+ if (where != null)
+ {
+ query += " WHERE " + where;
+ }
+
+ if (order != null)
+ {
+ query += " ORDER BY " + order;
+ }
+
+ if (pageNum != 0)
+ {
+ query += " LIMIT " + countPerPage + " OFFSET " + (countPerPage * (pageNum - 1));
+ }
+ handle.Dispose();
+ return query;
+ }
+
+ private static void InsertRequest(int requestId, IntPtr handlePtr, IntPtr insertData, IntPtr userData)
+ {
+ Provider provider;
+ InsertResult result;
+ SafeBundleHandle sbh = new SafeBundleHandle(insertData, false);
+ string query = GetQuery(handlePtr, sbh, null, OperationType.Update);
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnInsert(query, new Bundle(sbh));
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendInsertResult(requestId, result.RowID);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendInsertResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"InsertResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void BulkInsertRequest(int requestId, IntPtr handlePtr, IntPtr bulk_data, IntPtr userData)
+ {
+ Provider provider;
+ BulkInsertResult result;
+ BulkData bulkData = new BulkData(new Interop.DataControl.SafeBulkDataHandle(bulk_data, false));
+ Interop.DataControl.SafeBulkDataHandle sbdh = bulkData.SafeBulkDataHandle;
+ IntPtr bundleHandel;
+ ResultType ret;
+
+ int count = bulkData.GetCount();
+ List<string> queryList = new List<string>();
+
+ for (int i = 0; i < count; i++)
+ {
+ Interop.DataControl.BulkGetData(sbdh, i, out bundleHandel);
+ queryList.Add(GetQuery(handlePtr, new SafeBundleHandle(bundleHandel, false), null, OperationType.Insert));
+ }
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnBulkInsert(queryList, bulkData);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendBulkInsertResult(requestId, result.BulkResultData.SafeBulkDataHandle);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendBulkInsertResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+
+ if (result.BulkResultData != null)
+ {
+ result.BulkResultData.Dispose();
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"BulkInsertResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void SendNativeProtocol(int socketFd, ICursor cursor, int requestId)
+ {
+ uint write_len;
+ int DATACONTROL_RESULT_NO_DATA = -1;
+ int COLUMN_TYPE_NULL = 5;
+ int column_count, i, rowcount, size = 0, total_len_of_column_names = 0;
+ byte[] type_array, length_array, string_array, int_tmp, value_array = null;
+ string txt;
+ ResultType result;
+ MemoryStream ms;
+
+ if (cursor.Reset() == false)
+ {
+ Log.Error(LogTag, "Reset is failed : " + requestId.ToString());
+ return;
+ }
+
+ if (cursor.GetRowCount() <= 0)
+ {
+ Log.Error(LogTag, "The DB does not have another row : " + requestId.ToString());
+ int_tmp = BitConverter.GetBytes(DATACONTROL_RESULT_NO_DATA);
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, int_tmp, int_tmp.Length, out write_len);
+ return;
+ }
+
+ /* 1. column count */
+ column_count = cursor.GetColumnCount();
+ int_tmp = BitConverter.GetBytes(column_count);
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, int_tmp, int_tmp.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a column_count to a file descriptor is failed.");
+ return;
+ }
+
+ Log.Info(LogTag, "Writing a column_count " + column_count.ToString());
+
+ /* 2.column type x column_count */
+ for (i = 0; i < column_count; i++)
+ {
+ type_array = BitConverter.GetBytes((int)cursor.GetColumnType(i));
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, type_array, type_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a type to a file descriptor is failed.");
+ return;
+ }
+
+ Log.Info(LogTag, "Writing a column_type " + cursor.GetColumnType(i).ToString());
+ }
+
+ /* 3. column name x column_count */
+ for (i = 0; i < column_count; i++)
+ {
+ Log.Info(LogTag, "Writing a name " + cursor.GetColumnName(i));
+
+ total_len_of_column_names += cursor.GetColumnName(i).Length;
+ string_array = Encoding.UTF8.GetBytes(cursor.GetColumnName(i));
+ value_array = new byte[string_array.Length + 1];/*insert null */
+ string_array.CopyTo(value_array, 0);
+ length_array = BitConverter.GetBytes(value_array.Length);
+
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, length_array, length_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a type to a file descriptor is failed.");
+ return;
+ }
+
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, value_array, value_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a type to a file descriptor is failed.");
+ return;
+ }
+
+ }
+
+ /* 4. total length of column names */
+ length_array = BitConverter.GetBytes(total_len_of_column_names);
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, length_array, length_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a total_len_of_column_names to a file descriptor is failed");
+ return;
+ }
+
+ Log.Info(LogTag, "Writing total length of column namese " + total_len_of_column_names.ToString());
+
+ /* 5. row count */
+ length_array = BitConverter.GetBytes(cursor.GetRowCount());
+ Log.Error(LogTag, "=========================== select rowcount " + cursor.GetRowCount().ToString());
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, length_array, length_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a row count to a file descriptor is failed");
+ return;
+ }
+
+ Log.Error(LogTag, "Writing a row count " + cursor.GetRowCount().ToString());
+
+ rowcount = 0;
+ do
+ {
+ ms = new MemoryStream();
+
+ for (i = 0; i < column_count; i++)
+ {
+ type_array = BitConverter.GetBytes((int)cursor.GetColumnType(i));
+ switch (cursor.GetColumnType(i))
+ {
+ case ColumnType.ColumnTypeInt:
+ value_array = BitConverter.GetBytes(cursor.GetInt64Value(i));
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeDouble:
+ value_array = BitConverter.GetBytes(cursor.GetDoubleValue(i));
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeString:
+ txt = cursor.GetStringValue(i);
+ if (txt == null)
+ {
+ type_array = BitConverter.GetBytes(COLUMN_TYPE_NULL);
+ size = 0;
+ break;
+ }
+
+ string_array = Encoding.UTF8.GetBytes(txt);
+ value_array = new byte[string_array.Length + 1];/*insert null */
+ string_array.CopyTo(value_array, 0);
+ size = value_array.Length;
+ break;
+
+ case ColumnType.ColumnTypeBlob:
+ int_tmp = cursor.GetBlobValue(i);
+ if (int_tmp == null)
+ {
+ type_array = BitConverter.GetBytes(COLUMN_TYPE_NULL);
+ size = 0;
+ break;
+ }
+
+ value_array = int_tmp;
+ size = value_array.Length;
+ break;
+ }
+
+ ms.Write(type_array, 0, type_array.Length);
+
+ length_array = BitConverter.GetBytes(size);
+ ms.Write(length_array, 0, length_array.Length);
+ if (size > 0)
+ {
+ ms.Write(value_array, 0, value_array.Length);
+ }
+ }
+
+ value_array = ms.ToArray();
+
+ result = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, value_array, value_array.Length, out write_len);
+ if (result != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a row to a file descriptor is failed");
+ ms.Dispose();
+ return;
+ }
+
+ ms.Dispose();
+ Log.Info(LogTag, "row_count ~~~~ ", rowcount.ToString());
+
+ }
+ while (cursor.Next());
+ }
+
+ private static void SelectRequest(int requestId,
+ IntPtr handlePtr, IntPtr columnList, int columnCount, string where, string order, IntPtr userData)
+ {
+ Provider provider;
+ SelectResult result;
+ int pageNum = 0;
+ int countPerPage = 0;
+ int MAX_WRITE_SIZE = 1024; /* 1kbyte */
+ string query = null;
+ int socketFd, write_size, i;
+ uint write_len;
+ ResultType ret;
+ string[] _columnList = new string[columnCount];
+ byte[] buffer;
+
+ unsafe
+ {
+ byte** _sbyte_columnList = (byte**)columnList;
+
+ for (i = 0; i < columnCount; i++)
+ {
+ _columnList[i] = Marshal.PtrToStringAnsi((IntPtr)_sbyte_columnList[i]);
+ }
+ }
+
+ Interop.DataControl.GetSelectPageInfo(requestId, out pageNum, out countPerPage);
+ query = CreateSelectQuery(handlePtr, _columnList, _columnList.Length, where, order, pageNum, countPerPage);
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnSelect(query, where, _columnList, _columnList.Length, order, pageNum, countPerPage);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ Interop.DataControl.SendSelectResult(requestId, out socketFd);
+
+ MatrixCursor mc = result.ResultCursor as MatrixCursor;
+
+ if (mc == null)
+ {
+ SendNativeProtocol(socketFd, result.ResultCursor, requestId);
+ }
+ else
+ {
+ FileStream fs = mc.GetFileStream();
+ fs.Seek(0, SeekOrigin.Begin);
+
+ buffer = new byte[MAX_WRITE_SIZE];
+
+ do
+ {
+ write_size = fs.Read(buffer, 0, MAX_WRITE_SIZE);
+
+ if (write_size > 0)
+ {
+ ret = (ResultType)Interop.DataControl.UnsafeCode.WriteResult(socketFd, buffer, write_size, out write_len);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "Writing a row to a file descriptor is failed");
+ mc.Dispose();
+ return;
+ }
+ }
+ }
+ while (write_size > 0);
+ mc.Dispose();
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"SelectResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void UpdateRequest(int requestId,
+ IntPtr handlePtr, IntPtr updateData, string where, IntPtr userData)
+ {
+ Provider provider;
+ UpdateResult result;
+ SafeBundleHandle sbh = new SafeBundleHandle(updateData, false);
+ string query = GetQuery(handlePtr, sbh, where, OperationType.Update);
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnUpdate(query, where, new Bundle(sbh));
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendUpdateResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendUpdateResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"UpdateResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void DeleteRequest(int requestId,
+ IntPtr handlePtr, string where, IntPtr userData)
+ {
+ Provider provider;
+ DeleteResult result;
+ string query = GetQuery(handlePtr, null, where, OperationType.Delete);
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist ");
+ return;
+ }
+
+ result = provider.OnDelete(query, where);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendDeleteResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendDeleteResult fail " + ret.ToString());
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"DeleteResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapAddRequest(int requestId, IntPtr handlePtr, string key, string value, IntPtr userData)
+ {
+ Provider provider;
+ MapAddResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapAdd(key, value);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapAddResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapSetRequest(int requestId, IntPtr handlePtr, string key, string oldValue, string newValue, IntPtr userData)
+ {
+ Provider provider;
+ MapSetResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapSet(key, oldValue, newValue);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapSetResult is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapRemoveRequest(int requestId, IntPtr handlePtr, string key, string value, IntPtr userData)
+ {
+ Provider provider;
+ MapRemoveResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapRemove(key, value);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapResult(requestId);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapResult fail " + ret.ToString());
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestId, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapRemoveRequest is null : {requestId.ToString()}");
+ }
+ }
+
+ private static void MapGetRequest(int requestID, IntPtr handlePtr, string key, IntPtr userData)
+ {
+ Provider provider;
+ MapGetResult result;
+ ResultType ret;
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapGet(key);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ int valueCount = 0;
+ if (result.ValueList != null)
+ valueCount = result.ValueList.Length;
+ ret = Interop.DataControl.SendMapGetResult(requestID, result.ValueList, valueCount);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapGetResult fail " + ret.ToString());
+ }
+
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestID, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapRemoveRequest is null : {requestID.ToString()}");
+ }
+ }
+
+ private static void MapBulkAddRequest(int requestID, IntPtr handlePtr, IntPtr bulkDataPtr, IntPtr userData)
+ {
+ Provider provider;
+ MapBulkAddResult result;
+ BulkData bulkData = new BulkData(new Interop.DataControl.SafeBulkDataHandle(bulkDataPtr, false));
+ Interop.DataControl.SafeBulkDataHandle sbdh = bulkData.SafeBulkDataHandle;
+ IntPtr bundleHandel;
+ int count = bulkData.GetCount();
+ List<string> queryList = new List<string>();
+ ResultType ret;
+
+ for (int i = 0; i < count; i++)
+ {
+ Interop.DataControl.BulkGetData(sbdh, i, out bundleHandel);
+ queryList.Add(GetQuery(handlePtr, new SafeBundleHandle(bundleHandel, false), null, OperationType.Insert));
+ }
+
+ provider = GetProvider(handlePtr);
+ if (provider == null)
+ {
+ Log.Error(LogTag, "Provider not exist");
+ return;
+ }
+
+ result = provider.OnMapBulkAdd(bulkData);
+ if (result != null)
+ {
+ if (result.Result)
+ {
+ ret = Interop.DataControl.SendMapBulkAddResult(requestID, result.BulkResultData.SafeBulkDataHandle);
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendMapBulkAddResult fail " + ret.ToString());
+ }
+ }
+ else
+ {
+ ret = Interop.DataControl.SendError(requestID, result.Result.ToString());
+ if (ret != ResultType.Success)
+ {
+ Log.Error(LogTag, "SendError fail " + ret.ToString());
+ }
+ }
+
+ if (result.BulkResultData != null)
+ {
+ result.BulkResultData.Dispose();
+ }
+ }
+ else
+ {
+ Log.Info(LogTag, $"MapBulkAddRequest is null : {requestID.ToString()}");
+ }
+ }
+
+ private static string GetQuery(IntPtr handlePtr, SafeBundleHandle data, string where, OperationType type)
+ {
+ Interop.DataControl.SafeDataControlHandle handle = new Interop.DataControl.SafeDataControlHandle(handlePtr, false);
+ string query = null;
+
+ switch (type)
+ {
+ case OperationType.Select:
+ break;
+ case OperationType.Update:
+ query = Interop.DataControl.CreateUpdateStatement(handle, data, where);
+ break;
+ case OperationType.Delete:
+ query = Interop.DataControl.CreateDeleteStatement(handle, where);
+ break;
+ case OperationType.Insert:
+ query = Interop.DataControl.CreateInsertStatement(handle, data);
+ break;
+ default:
+ break;
+ }
+ handle.Dispose();
+
+ return query;
+ }
+
+ private static Provider GetProvider(IntPtr handlePtr)
+ {
+ Interop.DataControl.SafeDataControlHandle handle = new Interop.DataControl.SafeDataControlHandle(handlePtr, false);
+ Provider provider = null;
+ string dataID;
+
+ Interop.DataControl.DataControlGetDataId(handle, out dataID);
+ if (dataID != null && _providerDict.ContainsKey(dataID))
+ {
+ provider = _providerDict[dataID];
+ provider._nativeHandle = handlePtr;
+ Log.Info(LogTag, "DataID :" + dataID + ", hash code : " + provider.GetHashCode().ToString());
+ }
+ handle.Dispose();
+
+ return provider;
+ }
+
+ /// <summary>
+ /// Sends a data change notification to consumer applications which have successfully added a data change listen.
+ /// </summary>
+ /// <param name="type">Changed data type</param>
+ /// <param name="changedData">Customized information about changed data</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ public void SendDataChange(ChangeType type, Bundle changedData)
+ {
+ ResultType ret;
+
+ if (changedData == null || changedData.SafeBundleHandle.IsInvalid)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "changedData");
+ }
+
+ if (this._nativeHandle == IntPtr.Zero)
+ {
+ return;
+ }
+
+ ret = Interop.DataControl.SendDataChange(this._nativeHandle, type, changedData.SafeBundleHandle);
+ if (ret != ResultType.Success)
+ {
+ ErrorFactory.ThrowException(ret, false);
+ }
+ }
+
+ /// <summary>
+ /// Initializes Provider class with dataID.
+ /// </summary>
+ /// <param name="dataID">DataControl Data ID</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public Provider(string dataID)
+ {
+ if (string.IsNullOrEmpty(dataID))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "dataID");
+ }
+
+ DataID = dataID;
+ }
+
+ /// <summary>
+ /// Starts Provider service.
+ /// </summary>
+ /// <remarks>Only one Provider service can be ran for each process</remarks>
+ /// <exception cref="UnauthorizedAccessException">Thrown in case of permission denied.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ public void Run()
+ {
+ ResultType ret;
+ _lock.WaitOne();
+ if (_providerDict.ContainsKey(DataID))
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException((ResultType)1, true, "The provider is already running");
+ return;
+ }
+
+ if (_providerDict.Count == 0)
+ {
+ Log.Debug(LogTag, "Provider create");
+
+ _sqlRequestCallbacks.Insert = new Interop.DataControl.SqlInsertRequestCallback(InsertRequest);
+ _sqlRequestCallbacks.Select = new Interop.DataControl.SqlSelectRequestCallback(SelectRequest);
+ _sqlRequestCallbacks.Update = new Interop.DataControl.SqlUpdateRequestCallback(UpdateRequest);
+ _sqlRequestCallbacks.Delete = new Interop.DataControl.SqlDeleteRequestCallback(DeleteRequest);
+
+ ret = Interop.DataControl.RegisterSqlRequest(ref _sqlRequestCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ _sqlBulkCallback = new Interop.DataControl.SqlBulkInsertRequestCallback(BulkInsertRequest);
+ ret = Interop.DataControl.RegisterSqlBulkRequest(_sqlBulkCallback, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ _mapRequestCallbacks.Add = new Interop.DataControl.MapAddRequestCallback(MapAddRequest);
+ _mapRequestCallbacks.Remove = new Interop.DataControl.MapRemoveRequestCallback(MapRemoveRequest);
+ _mapRequestCallbacks.Set = new Interop.DataControl.MapSetRequestCallback(MapSetRequest);
+ _mapRequestCallbacks.Get = new Interop.DataControl.MapGetRequestCallback(MapGetRequest);
+ ret = Interop.DataControl.RegisterMapRequest(ref _mapRequestCallbacks, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ _mapBulkCallback = new Interop.DataControl.MapBulkAddRequestCallback(MapBulkAddRequest);
+ ret = Interop.DataControl.RegisterMapBulkRequest(_mapBulkCallback, IntPtr.Zero);
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+
+ if (_filterRegistered == false)
+ {
+ if (_filterCallback == null)
+ _filterCallback = new Interop.DataControl.DataChangeConsumerFilterCb(DataChangeListenFilter);
+
+ ret = Interop.DataControl.AddDataChangeConsumerFilterCallback(
+ _filterCallback,
+ IntPtr.Zero, out _filterCallbackID);
+
+ if (ret != ResultType.Success)
+ {
+ _lock.ReleaseMutex();
+ ErrorFactory.ThrowException(ret, false);
+ }
+ }
+
+ _filterRegistered = true;
+ }
+
+ _providerDict.Add(DataID, this);
+ Log.Info(LogTag, "DataID :" + DataID + ", hash code : " + this.GetHashCode().ToString());
+ _isRunning = true;
+ _lock.ReleaseMutex();
+ }
+
+ /// <summary>
+ /// Stop Provider service.
+ /// </summary>
+ public void Stop()
+ {
+ if (_isRunning == true)
+ {
+ Log.Info(LogTag, "DataID :" + DataID);
+ _isRunning = false;
+ _providerDict.Remove(DataID);
+ }
+ }
+
+ ~Provider()
+ {
+ Dispose(false);
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the select request is received.
+ /// </summary>
+ protected abstract SelectResult OnSelect(string query, string where, string[] columList, int columnCount, string order, int pageNum, int countPerPage);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the insert request is received.
+ /// </summary>
+ protected abstract InsertResult OnInsert(string query, Bundle insertData);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the update request is received.
+ /// </summary>
+ protected abstract UpdateResult OnUpdate(string query, string where, Bundle updateData);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the delete request is received.
+ /// </summary>
+ protected abstract DeleteResult OnDelete(string query, string where);
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the bulk insert request is received.
+ /// </summary>
+ protected virtual BulkInsertResult OnBulkInsert(IEnumerable<string> query, BulkData bulkInsertData)
+ {
+ Log.Info(LogTag, "The OnBulkInsert is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map get request is received.
+ /// </summary>
+ protected virtual MapGetResult OnMapGet(string key)
+ {
+ Log.Info(LogTag, "The OnMapGet is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the map add request is received.
+ /// </summary>
+ protected virtual MapAddResult OnMapAdd(string key, string value)
+ {
+ Log.Info(LogTag, "The OnMapAdd is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the update request is received.
+ /// </summary>
+ protected virtual MapSetResult OnMapSet(string key, string oldValue, string newValue)
+ {
+ Log.Info(LogTag, "The OnMapSet is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the delete request is received.
+ /// </summary>
+ protected virtual MapRemoveResult OnMapRemove(string key, string value)
+ {
+ Log.Info(LogTag, "The OnMapRemove is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the bulk add request is received.
+ /// </summary>
+ protected virtual MapBulkAddResult OnMapBulkAdd(BulkData bulkAddData)
+ {
+ Log.Info(LogTag, "The OnMapBulkAdd is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle behavior when the data change listen request is received.
+ /// </summary>
+ protected virtual DataChangeListenResult OnDataChangeListenRequest(string requestAppID)
+ {
+ Log.Info(LogTag, "The OnDataChangeListenRequest is not implemented.");
+ return null;
+ }
+
+ /// <summary>
+ /// Releases the unmanaged resourced used by the Provider class specifying whether to perform a normal dispose operation.
+ /// </summary>
+ /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ Stop();
+ _disposed = true;
+ }
+ if (disposing)
+ {
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the Provider class.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications.DataControl
+{
+ /// <summary>
+ /// This class is for containing insert operation result.
+ /// </summary>
+ public class InsertResult
+ {
+ /// <summary>
+ /// Gets the insert data's row id.
+ /// </summary>
+ public long RowID
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the insert operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes InsertResult class with columnNames and columnTypes.
+ /// </summary>
+ /// <param name="rowID">Inserted row ID</param>
+ /// <param name="result">Insert request result</param>
+ public InsertResult(long rowID, bool result)
+ {
+ RowID = rowID;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing bulk insert operation result.
+ /// </summary>
+ public class BulkInsertResult
+ {
+ /// <summary>
+ /// Gets the bulk insert operation result data.
+ /// </summary>
+ public BulkResultData BulkResultData
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the bulk insert operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes InsertResult class with bulkResultData and result.
+ /// </summary>
+ /// <param name="bulkResultData">Bulk insert request result data</param>
+ /// <param name="result">Bulk insert request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public BulkInsertResult(BulkResultData bulkResultData, bool result)
+ {
+ if (result == true && (bulkResultData == null || bulkResultData.SafeBulkDataHandle.IsInvalid))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "bulkResultData");
+ }
+
+ BulkResultData = bulkResultData;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing update operation result.
+ /// </summary>
+ public class UpdateResult
+ {
+ /// <summary>
+ /// Gets the update operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes UpdateResult class with result.
+ /// </summary>
+ /// <param name="result">Update request result</param>
+ public UpdateResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing delete operation result.
+ /// </summary>
+ public class DeleteResult
+ {
+ /// <summary>
+ /// Gets the delete operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes DeleteResult class with result.
+ /// </summary>
+ /// <param name="result">Delete request result</param>
+ public DeleteResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing select operation result.
+ /// </summary>
+ public class SelectResult
+ {
+ /// <summary>
+ /// Gets the select operation result cursor.
+ /// </summary>
+ public ICursor ResultCursor
+ {
+ get;
+ private set;
+ }
+ /// <summary>
+ /// Gets the select operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes SelectResult class with cursor and result.
+ /// </summary>
+ /// <param name="cursor">Cursor with selected data</param>
+ /// <param name="result">Select request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public SelectResult(ICursor cursor, bool result)
+ {
+ int i;
+
+ if (result == true && cursor == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "cursor");
+ }
+
+ if (result == true && (cursor is MatrixCursor) == false)
+ {
+ if (cursor.GetColumnCount() <= 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column count");
+ }
+
+ for (i = 0; i < cursor.GetColumnCount(); i++)
+ {
+ if (string.IsNullOrEmpty(cursor.GetColumnName(i)))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column name index " + i.ToString());
+ }
+
+ if (cursor.GetColumnType(i) < ColumnType.ColumnTypeInt || cursor.GetColumnType(i) > ColumnType.ColumnTypeBlob)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "column type index" + i.ToString());
+ }
+ }
+ }
+
+ ResultCursor = cursor;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapAdd operation result.
+ /// </summary>
+ public class MapAddResult
+ {
+
+ /// <summary>
+ /// Gets the MapAdd operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapAddResult class with result.
+ /// </summary>
+ /// <param name="result">MapAdd request result</param>
+ public MapAddResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapBulkAdd operation result.
+ /// </summary>
+ public class MapBulkAddResult
+ {
+ /// <summary>
+ /// Gets the MapBulkAdd operation result data.
+ /// </summary>
+ public BulkResultData BulkResultData
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the MapBulkAdd operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapBulkAddResult class with bulkResultData and result.
+ /// </summary>
+ /// <param name="bulkResultData">MapBulkAdd request result data</param>
+ /// <param name="result">MapBulkAdd request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public MapBulkAddResult(BulkResultData bulkResultData, bool result)
+ {
+ if (result == true && (bulkResultData == null || bulkResultData.SafeBulkDataHandle.IsInvalid))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "bulkResultData");
+ }
+
+ BulkResultData = bulkResultData;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapSet operation result.
+ /// </summary>
+ public class MapSetResult
+ {
+ /// <summary>
+ /// Gets the MapSet operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapSetResult class with result.
+ /// </summary>
+ /// <param name="result">MapSet request result</param>
+ public MapSetResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapRemove operation result.
+ /// </summary>
+ public class MapRemoveResult
+ {
+ /// <summary>
+ /// Gets the MapRemove operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapRemoveResult class with result.
+ /// </summary>
+ /// <param name="result">MapRemove request result</param>
+ public MapRemoveResult(bool result)
+ {
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing MapGet operation result.
+ /// </summary>
+ public class MapGetResult
+ {
+ /// <summary>
+ /// Gets the result value list of the MapGet operation.
+ /// </summary>
+ public string[] ValueList
+ {
+ get;
+ private set;
+ }
+ /// <summary>
+ /// Gets the MapGet operation result.
+ /// </summary>
+ public bool Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes MapGetResult class with data and result.
+ /// </summary>
+ /// <param name="valueLIst">MapGet request result data</param>
+ /// <param name="result">MapGet request result</param>
+ /// <exception cref="ArgumentException">Thrown in case of Invalid parmaeter.</exception>
+ public MapGetResult(string[] valueLIst, bool result)
+ {
+ if (result == true && valueLIst == null)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParameter, false, "valueLIst");
+ }
+
+ ValueList = valueLIst;
+ Result = result;
+ }
+ }
+
+ /// <summary>
+ /// This class is for containing DataChangeListen operation result.
+ /// </summary>
+ public class DataChangeListenResult
+ {
+ /// <summary>
+ /// Gets the DataChangeListen operation result.
+ /// </summary>
+ public ResultType Result
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Initializes DataChangeListenResult class with result.
+ /// </summary>
+ /// <param name="result">DataChangeListen request result</param>
+ public DataChangeListenResult(ResultType result)
+ {
+ Result = result;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications.DataControl
+{
+
+ /// <summary>
+ /// Enumeration for DataControl column type
+ /// </summary>
+ public enum ColumnType : short
+ {
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeInt = 1,
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeDouble = 2,
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeString = 3,
+ /// <summary>
+ /// Value representing DataControl operation Success
+ /// </summary>
+ ColumnTypeBlob = 4
+ }
+
+ /// <summary>
+ /// Enumeration for DataControl column type
+ /// </summary>
+ public enum ChangeType : short
+ {
+ /// <summary>
+ /// Value representing DataControl provider data changed by update
+ /// </summary>
+ Update,
+ /// <summary>
+ /// Value representing DataControl provider data changed by insert
+ /// </summary>
+ Insert,
+ /// <summary>
+ /// Value representing DataControl provider data changed by delete
+ /// </summary>
+ Delete,
+ /// <summary>
+ /// Value representing DataControl provider data changed by map add
+ /// </summary>
+ MapAdd,
+ /// <summary>
+ /// Value representing DataControl provider data changed by map remove
+ /// </summary>
+ MapRemove,
+ /// <summary>
+ /// Value representing DataControl provider data changed by map set
+ /// </summary>
+ MapSet,
+ }
+
+ /// <summary>
+ /// Enumeration for DataControl result type
+ /// </summary>
+ public enum ResultType : int
+ {
+ /// <summary>
+ /// Value representing DataControl operation success
+ /// </summary>
+ Success = Interop.DataControl.NativeResultType.Success,
+ /// <summary>
+ /// Value representing DataControl operation cause out of memory error
+ /// </summary>
+ OutOfMemory = Interop.DataControl.NativeResultType.OutOfMemory,
+ /// <summary>
+ /// Value representing DataControl operation cause IO error
+ /// </summary>
+ IoError = Interop.DataControl.NativeResultType.IoError,
+ /// <summary>
+ /// Value representing DataControl operation cause Invalid parameter error
+ /// </summary>
+ InvalidParameter = Interop.DataControl.NativeResultType.InvalidParameter,
+ /// <summary>
+ /// Value representing DataControl operation cause permission denied error
+ /// </summary>
+ PermissionDenied = Interop.DataControl.NativeResultType.PermissionDenied,
+ /// <summary>
+ /// Value representing DataControl operation cause max exceed error
+ /// </summary>
+ MaxExceed = Interop.DataControl.NativeResultType.MaxExceed,
+ }
+}