summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyunho Kang <hhstark.kang@samsung.com>2017-02-06 16:12:01 +0900
committerjusung son <jusung07.son@samsung.com>2017-03-09 15:45:16 +0900
commit2538329f7b12b5e63a8e7ff72fc6068a00c698cc (patch)
treee80347c7a23609a7de15cc2b130f45fd0d8521c6
parenta1334779fd8ede77e70182cf5bab7bfc5216c634 (diff)
downloaddata-control-submit/tizen/20170310.033151.tar.gz
data-control-submit/tizen/20170310.033151.tar.bz2
data-control-submit/tizen/20170310.033151.zip
Change-Id: I0ade91b17623af9486a919bdb05670815f964b30 Signed-off-by: Hyunho Kang <hhstark.kang@samsung.com> Signed-off-by: jusung son <jusung07.son@samsung.com>
-rw-r--r--LICENSE202
-rwxr-xr-xTizen.Applications.DataControl/Interop/Interop.DataControl.cs466
-rwxr-xr-xTizen.Applications.DataControl/Interop/Interop.Libraries.cs23
-rwxr-xr-xTizen.Applications.DataControl/Properties/AssemblyInfo.cs36
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Application.DataControl.snkbin0 -> 596 bytes
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs259
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl.csproj94
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl.nuspec21
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl.project.json11
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs361
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs973
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs70
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs81
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs616
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs1078
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs385
-rwxr-xr-xTizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs106
-rwxr-xr-xpackaging/csapi-data-control.manifest5
-rwxr-xr-xpackaging/csapi-data-control.spec45
19 files changed, 4832 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/Tizen.Applications.DataControl/Interop/Interop.DataControl.cs b/Tizen.Applications.DataControl/Interop/Interop.DataControl.cs
new file mode 100755
index 0000000..d20ec84
--- /dev/null
+++ b/Tizen.Applications.DataControl/Interop/Interop.DataControl.cs
@@ -0,0 +1,466 @@
+/*
+ * 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,
+ InvalidParamer = 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 = "datacontrol_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);
+ }
+ }
+ }
+
+ }
+}
diff --git a/Tizen.Applications.DataControl/Interop/Interop.Libraries.cs b/Tizen.Applications.DataControl/Interop/Interop.Libraries.cs
new file mode 100755
index 0000000..1658ec6
--- /dev/null
+++ b/Tizen.Applications.DataControl/Interop/Interop.Libraries.cs
@@ -0,0 +1,23 @@
+/*
+ * 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";
+ }
+}
diff --git a/Tizen.Applications.DataControl/Properties/AssemblyInfo.cs b/Tizen.Applications.DataControl/Properties/AssemblyInfo.cs
new file mode 100755
index 0000000..0893ef3
--- /dev/null
+++ b/Tizen.Applications.DataControl/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Tizen.Applications.DataControl")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Tizen.Applications.DataControl")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6f7e4ff6-4cea-4bb6-87b4-56498d6f3b24")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tizen.Applications.DataControl/Tizen.Application.DataControl.snk b/Tizen.Applications.DataControl/Tizen.Application.DataControl.snk
new file mode 100755
index 0000000..af23c55
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Application.DataControl.snk
Binary files differ
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs
new file mode 100755
index 0000000..03ee2b5
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.Core/CloneCursorCore.cs
@@ -0,0 +1,259 @@
+/*
+ * 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl.csproj b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.csproj
new file mode 100755
index 0000000..22e9e2a
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.csproj
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6F7E4FF6-4CEA-4BB6-87B4-56498D6F3B24}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tizen.Applications.DataControl</RootNamespace>
+ <AssemblyName>Tizen.Applications.DataControl</AssemblyName>
+ <FileAlignment>512</FileAlignment>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ </PropertyGroup>
+ <PropertyGroup>
+ <TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
+ <TargetFrameworkVersion>v1.3</TargetFrameworkVersion>
+ <NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>
+ <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
+ <NoStdLib>true</NoStdLib>
+ <NoWarn>$(NoWarn);1701</NoWarn>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>Tizen.Application.DataControl.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <None Include="Tizen.Application.DataControl.snk" />
+ <None Include="Tizen.Applications.DataControl.project.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Interop\Interop.Libraries.cs" />
+ <Compile Include="Interop\Interop.DataControl.cs" />
+ <Compile Include="Tizen.Applications.DataControl\ICursor.cs" />
+ <Compile Include="Tizen.Applications.DataControl\Consumer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Tizen.Applications.DataControl\BulkData.cs" />
+ <Compile Include="Tizen.Applications.DataControl.Core\CloneCursorCore.cs" />
+ <Compile Include="Tizen.Applications.DataControl\ErrorFactory.cs" />
+ <Compile Include="Tizen.Applications.DataControl\MatrixCursor.cs" />
+ <Compile Include="Tizen.Applications.DataControl\Provider.cs" />
+ <Compile Include="Tizen.Applications.DataControl\Types.cs" />
+ <Compile Include="Tizen.Applications.DataControl\Results.cs" />
+ </ItemGroup>
+ <ItemGroup />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <PropertyGroup>
+ <!-- https://github.com/dotnet/corefxlab/tree/master/samples/NetCoreSample and
+ https://docs.microsoft.com/en-us/dotnet/articles/core/tutorials/target-dotnetcore-with-msbuild
+ -->
+ <!-- We don't use any of MSBuild's resolution logic for resolving the framework, so just set these two
+ properties to any folder that exists to skip the GetReferenceAssemblyPaths task (not target) and
+ to prevent it from outputting a warning (MSB3644).
+ -->
+ <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)</_TargetFrameworkDirectories>
+ <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>
+ <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>
+ </PropertyGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties Tizen_1Applications_1DataControl_1project_1json__JSONSchema="http://json.schemastore.org/sarif-1.0.0.json" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl.nuspec b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.nuspec
new file mode 100755
index 0000000..972ed2c
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.nuspec
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<package>
+ <metadata>
+ <id>Tizen.Applications.DataControl</id>
+ <version>$version$</version>
+ <authors>Samsung Electronics</authors>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <licenseUrl>https://www.apache.org/licenses/LICENSE-2.0</licenseUrl>
+ <projectUrl>https://www.tizen.org/</projectUrl>
+ <iconUrl>https://developer.tizen.org/sites/default/files/images/tizen-pinwheel-on-light-rgb_64_64.png</iconUrl>
+ <copyright>© Samsung Electronics Co., Ltd All Rights Reserved</copyright>
+ <description>Provides the Data Control API for Tizen.Net</description>
+ <dependencies>
+ <dependency id="Tizen" version="1.0.2" />
+ <dependency id="Tizen.Applications" version="1.2.0" />
+ </dependencies>
+ </metadata>
+ <files>
+ <file src="bin/$Configuration$/Tizen.Applications.DataControl.dll" target="lib/netstandard1.3" />
+ </files>
+</package>
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl.project.json b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.project.json
new file mode 100755
index 0000000..ed5f888
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl.project.json
@@ -0,0 +1,11 @@
+{
+ "dependencies": {
+ "NETStandard.Library": "1.6.0",
+ "System.Threading.Thread": "4.3.0",
+ "Tizen": "1.0.2",
+ "Tizen.Applications": "1.2.0"
+ },
+ "frameworks": {
+ "netstandard1.3": {}
+ }
+} \ No newline at end of file
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs
new file mode 100755
index 0000000..90aa0a1
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/BulkData.cs
@@ -0,0 +1,361 @@
+/*
+ * 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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);
+ }
+ }
+}
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs
new file mode 100755
index 0000000..0d50911
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Consumer.cs
@@ -0,0 +1,973 @@
+/*
+ * 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.InvalidParamer, 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.InvalidParamer, false, "column_list");
+ }
+
+ for (i = 0; i < columnList.Length; i++)
+ {
+ if (string.IsNullOrEmpty(columnList[i]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, 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.InvalidParamer, false, "insertData");
+ }
+
+ if (string.IsNullOrEmpty(where))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, false, "providerId");
+ }
+
+ if (string.IsNullOrEmpty(dataId))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, 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);
+ }
+ }
+}
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs
new file mode 100755
index 0000000..16fd3cb
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ErrorFactory.cs
@@ -0,0 +1,70 @@
+/*
+ * 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 enum ErronType : int
+ {
+ Success = Interop.DataControl.NativeResultType.Success,
+ OutOfMemory = Interop.DataControl.NativeResultType.OutOfMemory,
+ IoError = Interop.DataControl.NativeResultType.IoError,
+ InvalidParamer = Interop.DataControl.NativeResultType.InvalidParamer,
+ PermissionDenied = Interop.DataControl.NativeResultType.PermissionDenied,
+ MaxExceed = Interop.DataControl.NativeResultType.MaxExceed,
+ }
+
+ 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.InvalidParamer:
+ 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}");
+ }
+ }
+ }
+}
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs
new file mode 100755
index 0000000..4136358
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/ICursor.cs
@@ -0,0 +1,81 @@
+/*
+ * 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
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs
new file mode 100755
index 0000000..685a554
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/MatrixCursor.cs
@@ -0,0 +1,616 @@
+/*
+ * 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
+{
+ /// <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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, false);
+ }
+
+ byte_array = GetValue(index);
+ 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.InvalidParamer, false);
+ }
+
+ byte_array = GetValue(index);
+ 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.InvalidParamer, false);
+ }
+
+ byte_array = GetValue(index);
+ 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.InvalidParamer, false);
+ }
+
+ byte_array = GetValue(index);
+
+ if (byte_array == null)
+ {
+ return null;
+ }
+
+ ret = Encoding.UTF8.GetString(byte_array);
+ 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.InvalidParamer, 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 + "_"+Application.Current.ApplicationInfo.ProcessId.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.InvalidParamer, false);
+ }
+
+ for (i = 0; i < columnNames.Length; i++)
+ {
+ if (string.IsNullOrEmpty(columnNames[i]))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, false, "columnNames index " + i.ToString());
+ }
+ }
+
+ for (i = 0; i < columnTypes.Length; i++)
+ {
+ if ( columnTypes[i] < ColumnType.ColumnTypeInt || columnTypes[i] > ColumnType.ColumnTypeBlob)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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);
+ }
+ }
+}
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs
new file mode 100755
index 0000000..b2bc00c
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Provider.cs
@@ -0,0 +1,1078 @@
+/*
+ * 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;
+
+ /// <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));
+ }
+
+ 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");
+ 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;
+ }
+
+ 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;
+ }
+
+ 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.InvalidParamer, 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.InvalidParamer, 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();
+ 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);
+ _lock.ReleaseMutex();
+ }
+
+ /// <summary>
+ /// Stop Provider service.
+ /// </summary>
+ public void Stop()
+ {
+ _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);
+ }
+ }
+}
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs
new file mode 100755
index 0000000..3e7e0d3
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Results.cs
@@ -0,0 +1,385 @@
+/*
+ * 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.InvalidParamer, 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.InvalidParamer, false, "cursor");
+ }
+
+ if (result == true && (cursor is MatrixCursor) == false)
+ {
+ if (cursor.GetColumnCount() <= 0)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, false, "column count");
+ }
+
+ for (i = 0; i < cursor.GetColumnCount(); i++)
+ {
+ if (string.IsNullOrEmpty(cursor.GetColumnName(i)))
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, false, "column name index " + i.ToString());
+ }
+
+ if (cursor.GetColumnType(i) < ColumnType.ColumnTypeInt || cursor.GetColumnType(i) > ColumnType.ColumnTypeBlob)
+ {
+ ErrorFactory.ThrowException(ResultType.InvalidParamer, 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.InvalidParamer, 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.InvalidParamer, 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;
+ }
+ }
+}
diff --git a/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs
new file mode 100755
index 0000000..e18a5b3
--- /dev/null
+++ b/Tizen.Applications.DataControl/Tizen.Applications.DataControl/Types.cs
@@ -0,0 +1,106 @@
+/*
+ * 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>
+ InvalidParamer = Interop.DataControl.NativeResultType.InvalidParamer,
+ /// <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,
+ }
+}
diff --git a/packaging/csapi-data-control.manifest b/packaging/csapi-data-control.manifest
new file mode 100755
index 0000000..75b0fa5
--- /dev/null
+++ b/packaging/csapi-data-control.manifest
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/csapi-data-control.spec b/packaging/csapi-data-control.spec
new file mode 100755
index 0000000..4843cc3
--- /dev/null
+++ b/packaging/csapi-data-control.spec
@@ -0,0 +1,45 @@
+Name: csapi-data-control
+Summary: Tizen data-control API for C#
+Version: 1.0.0
+Release: 1
+Group: Development/Libraries
+License: Apache-2.0
+URL: https://www.tizen.org
+Source0: %{name}-%{version}.tar.gz
+Source1: %{name}.manifest
+
+AutoReqProv: no
+ExcludeArch: aarch64 %ix86
+
+BuildRequires: dotnet-build-tools
+
+# C# API Requires
+BuildRequires: csapi-tizen-nuget
+BuildRequires: csapi-application-nuget
+
+%define Assemblies Tizen.Applications.DataControl
+
+%description
+%{summary}
+
+%dotnet_import_sub_packages
+
+%prep
+%setup -q
+cp %{SOURCE1} .
+
+%build
+for ASM in %{Assemblies}; do
+%dotnet_build $ASM
+%dotnet_pack $ASM/$ASM.nuspec %{version}
+done
+
+%install
+for ASM in %{Assemblies}; do
+%dotnet_install $ASM
+done
+
+%files
+%manifest %{name}.manifest
+%license LICENSE
+%attr(644,root,root) %{dotnet_assembly_files}