data-control & capi-data-control : initial commit 61/33661/6 tizen_3.0.2015.q2_common accepted/tizen/common/20150224.150857 accepted/tizen/common/20150522.095428 accepted/tizen/mobile/20150225.010339 accepted/tizen/tv/20150225.005343 accepted/tizen/wearable/20150225.005527 submit/tizen/20150224.123946 submit/tizen_common/20150522.093419
authorJiwoong Im <jiwoong.im@samsung.com>
Tue, 13 Jan 2015 13:12:22 +0000 (22:12 +0900)
committerJiwoong Im <jiwoong.im@samsung.com>
Tue, 20 Jan 2015 01:34:56 +0000 (17:34 -0800)
data-control source from tizen 2.3
- Data control api which is released in tizen_2.3 is a standard
  mechanism for exchanging specific data between applications.
- JIRA ticket : TC-2324

Features
- This repository contain data-control and capi-data-control(by rpm alias).
  To provide 2 packages, install 2 pc files.

Change-Id: Id8725dcec33ce0204d47a51d663c31df466c3fda
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
31 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0644]
capi-data-control.pc.in [new file with mode: 0644]
data-control.manifest [new file with mode: 0644]
data-control.pc.in [new file with mode: 0644]
include/data-control-map.h [new file with mode: 0644]
include/data-control-provider.h [new file with mode: 0644]
include/data-control-sql-cursor.h [new file with mode: 0644]
include/data-control-sql.h [new file with mode: 0644]
include/data-control-types.h [new file with mode: 0644]
include/data-control.h [new file with mode: 0644]
include/data_control.h [new file with mode: 0644]
include/data_control_internal.h [new file with mode: 0644]
include/data_control_map.h [new file with mode: 0644]
include/data_control_provider.h [new file with mode: 0644]
include/data_control_sql.h [new file with mode: 0644]
include/data_control_sql_cursor.h [new file with mode: 0644]
include/data_control_types.h [new file with mode: 0644]
packaging/data-control.spec [new file with mode: 0644]
src/data-control-internal.c [new file with mode: 0644]
src/data-control-internal.h [new file with mode: 0644]
src/data-control-map.c [new file with mode: 0644]
src/data-control-provider.c [new file with mode: 0644]
src/data-control-sql-cursor.c [new file with mode: 0644]
src/data-control-sql.c [new file with mode: 0644]
src/data_control_internal.c [new file with mode: 0644]
src/data_control_log.h [new file with mode: 0644]
src/data_control_map.c [new file with mode: 0644]
src/data_control_provider.c [new file with mode: 0644]
src/data_control_sql.c [new file with mode: 0644]
src/data_control_sql_cursor.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8e41edd
--- /dev/null
@@ -0,0 +1,51 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+PROJECT(data-control C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+INCLUDE_DIRECTORIES (
+       include
+       )
+
+SET(requires "dlog bundle glib-2.0 appsvc pkgmgr-info capi-base-common")
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED ${requires})
+
+FOREACH(flag ${pkgs_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIC -Werror -fvisibility=hidden")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+ADD_LIBRARY (${PROJECT_NAME} SHARED
+       src/data-control-map.c
+       src/data-control-sql.c
+       src/data-control-sql-cursor.c
+       src/data-control-provider.c
+       src/data-control-internal.c
+       src/data_control_internal.c
+       src/data_control_map.c
+       src/data_control_sql.c
+       src/data_control_sql_cursor.c
+       src/data_control_provider.c
+       )
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME}
+       PROPERTIES
+       VERSION ${FULLVER}
+       SOVERSION ${MAJORVER}
+       CLEAN_DIRECT_OUTPUT 1
+       )
+
+SET(VERSION ${FULLVER})
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.pc @ONLY)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+CONFIGURE_FILE(capi-${PROJECT_NAME}.pc.in ${CMAKE_SOURCE_DIR}/capi-${PROJECT_NAME}.pc @ONLY)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/capi-${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw FILES_MATCHING PATTERN "*.h")
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
@@ -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/capi-data-control.pc.in b/capi-data-control.pc.in
new file mode 100644 (file)
index 0000000..990d71a
--- /dev/null
@@ -0,0 +1,15 @@
+
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@/appfw
+
+Name: capi-data-control
+Description: Data Control managed library
+Version: @VERSION@
+Requires: capi-base-common
+Libs: -L${libdir} -ldata-control
+Cflags: -I${includedir}
+
diff --git a/data-control.manifest b/data-control.manifest
new file mode 100644 (file)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>
diff --git a/data-control.pc.in b/data-control.pc.in
new file mode 100644 (file)
index 0000000..19dc8d0
--- /dev/null
@@ -0,0 +1,15 @@
+
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@/appfw
+
+Name: data-control
+Description: Data Control managed library
+Version: @VERSION@
+Requires: capi-base-common
+Libs: -L${libdir} -ldata-control
+Cflags: -I${includedir}
+
diff --git a/include/data-control-map.h b/include/data-control-map.h
new file mode 100644 (file)
index 0000000..85b2075
--- /dev/null
@@ -0,0 +1,494 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file       data-control-map.h
+ * @brief      This is the header file for the key-value structured data control.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_MAP_H_
+#define _APPFW_DATA_CONTROL_MAP_H_
+
+#include <data-control-types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief              Called when the result value list is received from the key-value structured data control provider.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] result_value_list       The result value list of the data control request that gets the matching values
+ * @param [in] result_value_count      The number of the values
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_map_get_response_cb)(int request_id, datacontrol_h provider,
+               char ** result_value_list, int result_value_count, bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              Called when the response is received from the key-value structured data control provider.
+ *
+ * @param [in] request_id      The request ID that identifies the data control
+ * @param [in] provider                The provider handle
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_map_set_response_cb)(int request_id, datacontrol_h provider,
+               bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              Called when the response is received from the key-value structured data control provider.
+ *
+ * @param [in] request_id      The request ID that identifies the data control
+ * @param [in] provider                The provider handle
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_map_add_response_cb)(int request_id, datacontrol_h provider,
+               bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              Called when the response is received from the key-value structured data control provider.
+ *
+ * @param [in] request_id      The request ID that identifies the data control
+ * @param [in] provider                The provider handle
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_map_remove_response_cb)(int request_id, datacontrol_h provider,
+               bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              The structure type to contain the set of callback functions for handling the response events
+ *                     of the key-value structured data control.
+ * @see                datacontrol_map_get_response_cb()
+ * @see                datacontrol_map_set_response_cb()
+ * @see                datacontrol_map_add_response_cb()
+ * @see                datacontrol_map_remove_response_cb()
+ */
+typedef struct
+{
+       datacontrol_map_get_response_cb get;
+       datacontrol_map_set_response_cb set;
+       datacontrol_map_add_response_cb add;
+       datacontrol_map_remove_response_cb remove;
+} datacontrol_map_response_cb;
+
+/**
+ * @brief              Creates a provider handle.
+ * @param [out]        provider        The provider handle
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_map_destroy()
+ *
+ * The following example demonstrates how to use the %datacontrol_map_create() method.
+ *
+ * @code
+ *
+ *     int main()
+ *     {
+ *             const char *provider_id = "http://tizen.org/datacontrol/provider/example";
+ *             const char *data_id = "table";
+ *             datacontrol_h provider;
+ *             int result = 0;
+ *
+ *             result = datacontrol_map_create(&provider);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Creating data control provider is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_map_set_provider_id(provider, provider_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Setting providerID is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_map_set_data_id(provider, data_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Setting dataID is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             // Executes some operations
+ *
+ *             result = datacontrol_map_destroy(provider);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Destorying data control provider is failed with error: %d", result);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_map_create(datacontrol_h *provider);
+
+/**
+ * @brief              Destroys the provider handle and releases all its resources.
+ * @param [in] provider        The provider handle
+ * @return             0 on success, otherwise a negative error value.
+ * @remark     When operations of data control are finished, this function must be called to prevent memory leak.
+ * @see datacontrol_map_create()
+ */
+EXPORT_API int datacontrol_map_destroy(datacontrol_h provider);
+
+/**
+ * @brief              Sets the Provider ID.
+ * @param [in] provider        The provider handle
+ * @param [in] provider_id      The data control provider ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_map_get_provider_id()
+ */
+EXPORT_API int datacontrol_map_set_provider_id(datacontrol_h provider, const char *provider_id);
+
+/**
+ * @brief              Gets the Provider ID.
+ * @param [in] provider        The provider handle
+ * @param [out]        provider_id      The data control provider ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_map_set_provider_id()
+ */
+EXPORT_API int datacontrol_map_get_provider_id(datacontrol_h provider, char **provider_id);
+
+/**
+ * @brief              Sets the Data ID.
+ * @param [in] provider        The provider handle
+ * @param [in] data_id A string for identifying a specific table to operate. @n
+ *                                             The string consists of one or more components separated by a slash('/').
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_map_get_data_id()
+ */
+EXPORT_API int datacontrol_map_set_data_id(datacontrol_h provider, const char *data_id);
+
+/**
+ * @brief              Gets the Data ID.
+ * @param [in] provider        The provider handle
+ * @param [out]        data_id A string for identifying a specific table to operate. @n
+ *                                             The string consists of one or more components separated by a slash('/').
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_map_set_data_id()
+ */
+EXPORT_API int datacontrol_map_get_data_id(datacontrol_h provider, char **data_id);
+
+/**
+ * @brief              Registers a callback function for the key-value structured data control response. @n
+ *                             The application is notified when a data control response is received from the @c provider.
+ * @param [in] provider        The provider handle
+ * @param [in] callback        The callback function to be called when a response is received.
+ * @param [in] user_data       The user data to be passed to the callback function
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_map_unregister_response_cb()
+ */
+EXPORT_API int datacontrol_map_register_response_cb(datacontrol_h provider, datacontrol_map_response_cb* callback, void *user_data);
+
+/**
+ * @brief              Unregisters the callback function in @c provider.
+ * @param [in] provider        The provider handle
+ * @return             0 on success, otherwise a negative error value.
+ */
+EXPORT_API int datacontrol_map_unregister_response_cb(datacontrol_h provider);
+
+/**
+ * @brief              Gets the value list associated with the specified @c key from the key-values map owned by the key-value structured data control provider.
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] key             The key of the value list to obtain
+ * @param [out]        request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ *
+ * The following example demonstrates how to use the %datacontrol_map_get() method.
+ *
+ * @code
+ *
+ *     void map_get_response_cb(int request_id, datacontrol_h provider,
+ *                     char **result_value_list, int result_value_count, bool provider_result, const char *error)
+ *     {
+ *             if (provider_result) {
+ *                     LOGI("The get operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The get operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_map_response_cb map_callback;
+ *
+ *     int main()
+ *     {
+ *             int result = 0;
+ *             int req_id = 0;
+ *             char *key = "key";
+ *
+ *             map_callback.get = map_get_response_cb;
+ *             result = datacontrol_map_register_response_cb(provider, &map_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_map_get(provider, key, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Getting the value list of the key(%s) is failed with error: %d", key, result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_map_get(datacontrol_h provider, const char *key, int *request_id);
+
+/**
+ * @brief              Gets the value list associated with the specified @c key from the key-values map owned by the key-value structured data control provider.
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] key             The key of the value list to obtain
+ * @param [out]        request_id      The request ID
+ * @param [in] page_number             The page number of the value set @n
+ *                                                             It starts from 1.
+ * @param [in] count_per_page  The desired maximum count of the data items per page
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ */
+EXPORT_API int datacontrol_map_get_with_page(datacontrol_h provider, const char *key, int *request_id, int page_number, int count_per_page);
+
+/**
+ * @brief              Sets the value associated with the specified @c key to a new value.
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] key             The key of the value to replace
+ * @param [in] old_value               The value to replace
+ * @param [in] new_value       The new value that replaces the existing value
+ * @param [out]        request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ *
+ * The following example demonstrates how to use the %datacontrol_map_set() method.
+ *
+ * @code
+ *
+ *     void map_set_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error)
+ *     {
+ *             if (provider_result) {
+ *                     LOGI("The set operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The set operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_map_response_cb map_callback;
+ *
+ *     int main()
+ *     {
+ *             int result = 0;
+ *             int req_id = 0;
+ *             char *key = "key";
+ *             char *old_value = "old value";
+ *             char *new_value = "new value";
+ *
+ *             map_callback.set = map_set_response_cb;
+ *             result = datacontrol_map_register_response_cb(provider, &map_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_map_set(provider, key, old_value, new_value, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Replacing old_value(%s) with new_value(%s) is failed with error: %d", old_value, new_value, result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_map_set(datacontrol_h provider, const char *key, const char *old_value, const char *new_value, int *request_id);
+
+/**
+ * @brief              Adds the @c value associated with the specified @c key to the key-values map owned by the key-value structured data control provider.
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] key             The key of the value to add
+ * @param [in] value           The value to add
+ * @param [out]        request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ *
+ * The following example demonstrates how to use the %datacontrol_map_add() method.
+ *
+ * @code
+ *
+ *     void map_add_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
+ *             if (provider_result) {
+ *                     LOGI("The add operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The add operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_map_response_cb map_callback;
+ *
+ *     int main()
+ *     {
+ *             int result = 0;
+ *             int req_id = 0;
+ *             const char *key = "key";
+ *             const char *value = "value";
+ *
+ *             map_callback.add = map_add_response_cb;
+ *             result = datacontrol_map_register_response_cb(provider, &map_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_map_add(provider, key, value, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Adding %s-%s pair is failed with error: %d", key, value, result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_map_add(datacontrol_h provider, const char *key, const char *value, int *request_id);
+
+/**
+ * @brief              Removes the @c value associated with the specified @c key from the key-values map owned by the key-value structured data control provider.
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] key             The key of the value to remove
+ * @param [in] value           The value to remove
+ * @param [out]        request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ *
+ * The following example demonstrates how to use the %datacontrol_map_remove() method.
+ *
+ * @code
+ *
+ *     void map_remove_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
+ *             if (provider_result) {
+ *                     LOGI("The remove operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The remove operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_map_response_cb map_callback;
+ *
+ *     int main()
+ *     {
+ *             int result = 0;
+ *             int req_id = 0;
+ *             const char *key = "key";
+ *             const char *value = "value";
+ *
+ *             ...
+ *
+ *             map_callback.remove = map_remove_response_cb;
+ *             result = datacontrol_map_register_response_cb(provider, &map_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_map_remove(provider, key, value, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Removing %s-%s pair is failed with error: %d", key, value, result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_map_remove(datacontrol_h provider, const char *key, const char *value, int *request_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _APPFW_DATA_CONTROL_MAP_H_ */
+
diff --git a/include/data-control-provider.h b/include/data-control-provider.h
new file mode 100644 (file)
index 0000000..4d0ddc4
--- /dev/null
@@ -0,0 +1,290 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file       data-control-provider.h
+ * @brief      This is the header file for the data control provider.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_PROVIDER_H_
+#define _APPFW_DATA_CONTROL_PROVIDER_H_
+
+#include <data-control-types.h>
+#include <data-control-sql-cursor.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief              Called when the insert request is received from an application using SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in]         insert_data     The column-value pairs to insert @n
+ *                                                     If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_sql_insert_request_cb)(int request_id, datacontrol_h provider,
+               bundle *insert_data, void *user_data);
+
+/**
+ * @brief              Called when the update request is received from an application using SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in]         update_data     The column-value pairs to update @n
+ *                                                     If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
+ * @param [in] where           A filter to select the desired rows to update. @n
+ *                                                     It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_sql_update_request_cb)(int request_id, datacontrol_h provider,
+               bundle *update_data, const char *where, void *user_data);
+
+/**
+ * @brief              Called when the delete request is received from an application using SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] where           A filter to select the desired rows to delete. @n
+ *                                                     It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_sql_delete_request_cb)(int request_id, datacontrol_h provider,
+               const char *where, void *user_data);
+
+/**
+ * @brief              Called when the select request is received from an application using SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in]         column_list     The column list to query
+ * @param [in]         column_count    The total number of columns to be queried
+ * @param [in] where           A filter to select the desired rows. @n
+ *                                                     It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param [in] order           The sorting order of the rows to query. @n
+ *                                                     It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_sql_select_request_cb)(int request_id, datacontrol_h provider,
+               const char **column_list, int column_count, const char *where, const char *order, void *user_data);
+
+/**
+ * @brief              Called when the request for obtaining the value list is received from the key-value structured data control consumer.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] key                     The key of the value list to obtain
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_map_get_value_request_cb)(int request_id, datacontrol_h provider, const char *key, void *user_data);
+
+/**
+ * @brief              Called when the request for replacing the value is received from the key-value structured data control consumer.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] key                     The key of the value to replace
+ * @param [in] old_value               The value to replace
+ * @param [in] new_value       The new value that replaces the existing value
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_map_set_value_request_cb)(int request_id, datacontrol_h provider, const char *key,
+               const char *old_value, const char *new_value, void *user_data);
+
+/**
+ * @brief              Called when the request for adding the value is received from the key-value structured data control consumer.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] key                     The key of the value to add
+ * @param [in] value           The value to add
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_map_add_value_request_cb)(int request_id, datacontrol_h provider, const char *key,
+               const char *value, void *user_data);
+
+/**
+ * @brief              Called when the request for removing the value is received from the key-value structured data control consumer.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] key                     The key of the value to remove
+ * @param [in] value           The value to remove
+ * @param [in]  user_data   The user data passed from the register function
+ */
+typedef void (*datacontrol_provider_map_remove_value_request_cb)(int request_id, datacontrol_h provider, const char *key,
+               const char *value, void *user_data);
+
+/**
+ * @brief              The structure type to contain the set of callback functions for handling the request events
+ *                     of SQL-friendly interface based data control.
+ * @see                datacontrol_provider_sql_select_request_cb()
+ * @see                datacontrol_provider_sql_insert_request_cb()
+ * @see                datacontrol_provider_sql_update_request_cb()
+ * @see                datacontrol_provider_sql_delete_request_cb()
+ */
+typedef struct
+{
+       datacontrol_provider_sql_insert_request_cb insert;
+       datacontrol_provider_sql_select_request_cb select;
+       datacontrol_provider_sql_update_request_cb update;
+       datacontrol_provider_sql_delete_request_cb delete;
+} datacontrol_provider_sql_cb;
+
+/**
+ * @brief              The structure type to contain the set of callback functions for handling the request events
+ *                     from the key-value structured data control consumer.
+ * @see                datacontrol_provider_map_get_value_request_cb()
+ * @see                datacontrol_provider_map_set_value_request_cb()
+ * @see                datacontrol_provider_map_add_value_request_cb()
+ * @see                datacontrol_provider_map_remove_value_request_cb()
+ */
+typedef struct
+{
+       datacontrol_provider_map_get_value_request_cb get;
+       datacontrol_provider_map_set_value_request_cb set;
+       datacontrol_provider_map_add_value_request_cb add;
+       datacontrol_provider_map_remove_value_request_cb remove;
+} datacontrol_provider_map_cb;
+
+/**
+ * @brief              Registers a callback function for the sql data control request.
+ *                     The provider is notified when a data control request is received from the client applications.
+ * @param [in] callback        The callback function to be called when a data control request is received
+ * @param [in] user_data       The user data to be passed to the callback function
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_sql_register_cb(datacontrol_provider_sql_cb *callback, void *user_data);
+
+/**
+ * @brief              Unregisters the callback functions.
+ * @return     0 on success, otherwise a negative error value.
+ */
+EXPORT_API int datacontrol_provider_sql_unregister_cb(void);
+
+/**
+ * @brief              Registers a callback function for the map data control request.
+ *                     The provider is notified when a data control request is received from the client applications.
+ * @param [in] callback        The callback function to be called when a data control request is received
+ * @param [in]  user_data   The user data to be passed to the callback function
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_map_register_cb(datacontrol_provider_map_cb *callback, void *user_data);
+
+/**
+ * @brief              Unregisters the callback functions.
+ * @return     0 on success, otherwise a negative error value.
+ */
+EXPORT_API int datacontrol_provider_map_unregister_cb(void);
+
+/**
+ * @brief              Gets the application ID which sends the data control request.
+ * @param [in] request_id      The request ID
+ * @param [out]        appid           The application ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_get_client_appid(int request_id, char **appid);
+
+/**
+ * @brief              Sends the success result and the result set of the select request to the client application.
+ * @param [in] request_id      The request ID
+ * @param [in] db_handle       The result db handle for the result set
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_select_result(int request_id, void *db_handle);
+
+/**
+ * @brief              Sends the success result of the insert request and the last inserted row ID to the client application.
+ * @param [in] request_id      The request ID
+ * @param [in] row_id          The row ID of the database changed by the insert request
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_insert_result(int request_id, long long row_id);
+
+/**
+ * @brief              Sends the success result of the update request the client application.
+ * @param [in] request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_update_result(int request_id);
+
+/**
+ * @brief              Sends the success result of the delete request the client application.
+ * @param [in] request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_delete_result(int request_id);
+
+/**
+ * @brief              Sends the provider error message to the client application.
+ * @param [in] request_id      The request ID
+ * @param [in] error                   The provider-defined error message
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_error(int request_id, const char *error);
+
+/**
+ * @brief              Sends the success result of the request for setting, adding and removing the key-value structured data the client application.
+ * @param [in] request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_map_result(int request_id);
+
+/**
+ * @brief              Sends the success result of the request for getting the value list the client application.
+ * @param [in] request_id      The request ID
+ * @param [in] value_list              The result value list
+ * @param [in] value_count     The number of the values
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_map_get_value_result(int request_id, char **value_list, int value_count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _APPFW_DATA_CONTROL_PROVIDER_H_ */
+
diff --git a/include/data-control-sql-cursor.h b/include/data-control-sql-cursor.h
new file mode 100644 (file)
index 0000000..5179efd
--- /dev/null
@@ -0,0 +1,276 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file       data-control-sql-cursor.h
+ * @brief      This is the header file for the cursor of the SQL-friendly interface based data control.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_
+#define _APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_
+
+#include <stdio.h>
+#include "data-control-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief      The structure type to represent a sql result set. This type can be used to enumerate through the result set of an SQL query.
+ */
+typedef struct
+{
+       int resultset_fd;
+       int resultset_row_count;
+       int resultset_col_count;
+       int resultset_col_type_offset;
+       int resultset_col_name_offset;
+       int resultset_content_offset;
+       int resultset_current_offset;
+       int resultset_current_row_count;
+       char* resultset_path;
+} resultset_cursor;
+
+/**
+ * @brief              Creates a cursor to enumerate through an SQL result set
+ *
+ * @param [in] path            The path of the file containing the SQL result set
+ * @return             A pointer to struct @c resultset_cursor
+ */
+resultset_cursor* datacontrol_sql_get_cursor(const char *path);
+
+/**
+ * @brief              Moves the cursor to the first position
+ *
+ * @param [in] cursor  Navigates the result of the request for the select operation
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_step_first() method.
+ *
+ * @code
+ *
+ *     void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *cursor, bool provider_result, const char *error)
+ *     {
+ *             char person_name[32] = {0,};
+ *             long long person_number = -1;
+ *
+ *             datacontrol_sql_step_first(cursor);
+ *             datacontrol_sql_get_text_data(cursor, 0, person_name);
+ *             datacontrol_sql_get_int64_data(cursor, 1, &person_number);
+ *             printf("The person %s has the number %l", person_name, person_number);
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_step_first(resultset_cursor *cursor);
+
+/**
+ * @brief              Moves the cursor to the last position
+ *
+ * @param [in] cursor  Navigates the result of data control select request
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_step_last() method.
+ *
+ * @code
+ *
+ *     void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *cursor, bool provider_result, const char *error)
+ *     {
+ *             char person_name[32] = {0,};
+ *             long long person_number = -1;
+ *
+ *             datacontrol_sql_step_last(cursor);
+ *             datacontrol_sql_get_text_data(cursor, 0, person_name);
+ *             datacontrol_sql_get_int64_data(cursor, 1, &person_number);
+ *             printf("The person %s has the number %l", person_name, person_number);
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_step_last(resultset_cursor *cursor);
+
+/**
+ * @brief              Moves the cursor to the next position
+ *
+ * @param [in] cursor  Navigates the result of the request for the select operation
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_step_next() method.
+ *
+ * @code
+ *
+ *     void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *cursor, bool provider_result, const char *error)
+ *     {
+ *             char person_name[32] = {0,};
+ *             long long person_number = -1;
+ *             while (datacontrol_sql_step_next(cursor) == DATACONTROL_ERROR_NONE) {
+ *                     datacontrol_sql_get_text_data(cursor, 0, person_name);
+ *                     datacontrol_sql_get_int64_data(cursor, 1, &person_number);
+ *                     printf("The person %s has the number %l", person_name, person_number);
+ *             }
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_step_next(resultset_cursor *cursor);
+
+/**
+ * @brief              Moves the cursor to the previous position
+ *
+ * @param [in] cursor  Navigates the result of the request for the select operation
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_sql_step_previous(resultset_cursor *cursor);
+
+/**
+ * @brief      Gets the number of columns for this cursor
+ *
+ * @param [in] cursor  Navigates the result of the request for the select operation
+ * @return             The number of columns in the calling cursor
+ */
+EXPORT_API int datacontrol_sql_get_column_count(resultset_cursor *cursor);
+
+/**
+ * @brief              Gets the name of the column indicated by the specified index
+ *
+ * @param [in]         cursor  Navigates the result of the request for the select operation
+ * @param [in] column_index            The index of the destination column
+ * @param [out]        name                    The name of the destination column
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ */
+EXPORT_API int datacontrol_sql_get_column_name(resultset_cursor *cursor, int column_index, char *name);
+
+/**
+ * @brief              Gets the size of data in the column indicated by the specified index
+ *
+ * @param [in] cursor  Navigates the result of the request for the select operation
+ * @param [in] column_index            The index of the destination column
+ * @return             The size of data in the column indicated by the specified index. @n
+ *                             If an error is occurred, a negative value is returned.
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ */
+EXPORT_API int datacontrol_sql_get_column_item_size(resultset_cursor *cursor, int column_index);
+
+/**
+ * @brief              Gets the type of the column indicated by the specified index
+ *
+ * @param [in] cursor          Navigates the result of the request for the select operation
+ * @param [in] column_index    The index of the destination column
+ * @param [out]        type                    The type of the destination column
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ */
+EXPORT_API int datacontrol_sql_get_column_item_type(resultset_cursor *cursor, int column_index, datacontrol_sql_column_type* type);
+
+/**
+ * @brief              Gets a blob data from the column indicated by the specified index
+ *
+ * @param [in] cursor          Navigates the result of the request for the select operation
+ * @param [in] column_index    The index of the destination column
+ * @param [out]        data                    The blob value obtained from the column
+ * @param [out]        size                    The size of the data
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ */
+EXPORT_API int datacontrol_sql_get_blob_data(resultset_cursor *cursor, int column_index, void *data, int size);
+
+/**
+ * @brief              Gets an int value from the column indicated by the specified index
+ *
+ * @param [in] cursor          Navigates the result of the request for the select operation
+ * @param [in] column_index    The index of the destination column
+ * @param [out]        data                    The integer value obtained from the column
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_sql_get_int_data(resultset_cursor *cursor, int column_index, int *data);
+
+/**
+ * @brief              Gets a long long value from the column indicated by the specified index
+ *
+ * @param [in] cursor          Navigates the result of the request for the select operation
+ * @param [in] column_index    The index of the destination column
+ * @param [out]        data                    The 64-bit integer value obtained from the column
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_sql_get_int64_data(resultset_cursor *cursor, int column_index, long long *data);
+
+/**
+ * @brief              Gets a double value from the column indicated by the specified index
+ *
+ * @param [in] cursor          Navigates the result of the request for the select operation
+ * @param [in] column_index            The index of the destination column
+ * @param [out]        data                    The value obtained from the column as double
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_sql_get_double_data(resultset_cursor *cursor, int column_index, double *data);
+
+/**
+ * @brief              Gets a text value from the column indicated by the specified index
+ *
+ * @param [in] cursor          Navigates the result of the request for the select operation
+ * @param [in] column_index    The index of the destination column
+ * @param [out]        data                    The value obtained from the column as text
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ */
+EXPORT_API int datacontrol_sql_get_text_data(resultset_cursor *cursor, int column_index, char *data);
+
+/**
+ * @brief              Removes the @c cursor containing SQL result set
+ *
+ * @param [in] cursor          A pointer to the result set cursor to be removed
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ */
+EXPORT_API int datacontrol_sql_remove_cursor(resultset_cursor *cursor);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_ */
+
diff --git a/include/data-control-sql.h b/include/data-control-sql.h
new file mode 100644 (file)
index 0000000..bc9d691
--- /dev/null
@@ -0,0 +1,511 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file       data-control-sql.h
+ * @brief      This is the header file for the SQL-friendly interface based data control.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_SQL_H_
+#define _APPFW_DATA_CONTROL_SQL_H_
+
+#include <data-control-types.h>
+#include <data-control-sql-cursor.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief              Called when response is received for insert operation from an application using the SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] inserted_row_id The inserted row ID set by the data control
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_sql_insert_response_cb)(int request_id, datacontrol_h provider,
+               long long inserted_row_id, bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              Called when response is received for delete operation from an application using the SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID that identifies the data control
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_sql_delete_response_cb)(int request_id, datacontrol_h provider,
+               bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              Called when response is received for select operation from an application using the SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] enumerator      Navigates the result of data control select request
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false  otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_sql_select_response_cb)(int request_id, datacontrol_h provider,
+               resultset_cursor *enumerator, bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              Called when response is received for update operation from an application using the SQL-friendly interface based data control.
+ *
+ * @param [in] request_id      The request ID
+ * @param [in] provider                The provider handle
+ * @param [in] provider_result Set to true if the data control provider successfully processed. @n
+ *                                                             false  otherwise.
+ * @param [in] error           The error message from the data control provider
+ * @param [in] user_data       The user data passed from the register function
+ */
+typedef void (*datacontrol_sql_update_response_cb)(int request_id, datacontrol_h provider,
+               bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief              The structure type to contain the set of callback functions for handling the response events
+ *                     of SQL-friendly interface based data control.
+ * @see                datacontrol_sql_select_response_cb()
+ * @see                datacontrol_sql_insert_response_cb()
+ * @see                datacontrol_sql_update_response_cb()
+ * @see                datacontrol_sql_delete_response_cb()
+ */
+typedef struct
+{
+       datacontrol_sql_select_response_cb select;
+       datacontrol_sql_insert_response_cb insert;
+       datacontrol_sql_update_response_cb update;
+       datacontrol_sql_delete_response_cb delete;
+} datacontrol_sql_response_cb;
+
+/**
+ * @brief              Creates a provider handle.
+ * @param [out]        provider        The provider handle
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_sql_destroy()
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_create() method.
+ *
+ * @code
+ *
+ *     int main()
+ *     {
+ *             const char *provider_id = "http://tizen.org/datacontrol/provider/example";
+ *             const char *data_id = "table";
+ *             datacontrol_h provider;
+ *             int result = 0;
+ *
+ *             result = datacontrol_sql_create(&provider);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Creating data control provider is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_sql_set_provider_id(provider, provider_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Setting providerID is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_sql_set_data_id(provider, data_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Setting dataID is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             // Executes some operations
+ *
+ *             result = datacontrol_sql_destroy(provider);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Destorying data control provider is failed with error: %d", result);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_create(datacontrol_h *provider);
+
+/**
+ * @brief              Destroys the provider handle and releases all its resources.
+ * @param [in] provider        The provider handle
+ * @return             0 on success, otherwise a negative error value.
+ * @remark     When operations of data control are finished, this function must be called to prevent memory leak.
+ * @see datacontrol_sql_create()
+ */
+EXPORT_API int datacontrol_sql_destroy(datacontrol_h provider);
+
+/**
+ * @brief              Sets the Provider ID.
+ * @param [in] provider        The provider handle
+ * @param [in] provider_id      The data control provider ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_sql_get_provider_id()
+ */
+EXPORT_API int datacontrol_sql_set_provider_id(datacontrol_h provider, const char *provider_id);
+
+/**
+ * @brief              Gets the Provider ID.
+ * @param [in] provider        The provider handle
+ * @param [out]        provider_id      The data control provider ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_sql_set_provider_id()
+ */
+EXPORT_API int datacontrol_sql_get_provider_id(datacontrol_h provider, char **provider_id);
+
+/**
+ * @brief              Sets the Data ID.
+ * @param [in] provider        The provider handle
+ * @param [in] data_id A string for identifying a specific table to operate. @n
+ *                                             The string consists of one or more components separated by a slash('/').
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_sql_get_data_id()
+ */
+EXPORT_API int datacontrol_sql_set_data_id(datacontrol_h provider, const char *data_id);
+
+/**
+ * @brief              Gets the Data ID.
+ * @param [in] provider        The provider handle
+ * @param [out]        data_id A string for identifying a specific table to operate. @n
+ *                                             The string consists of one or more components separated by a slash('/').
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_sql_set_data_id()
+ */
+EXPORT_API int datacontrol_sql_get_data_id(datacontrol_h provider, char **data_id);
+
+/**
+ * @brief              Registers a callback function for the sql data control response. @n
+ *                             The application is notified when a data control response is received from the @c provider.
+ * @param [in] provider        The provider handle
+ * @param [in] callback        The callback function to be called when a response is received.
+ * @param [in] user_data       The user data to be passed to the callback function
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_sql_unregister_response_cb()
+ */
+EXPORT_API int datacontrol_sql_register_response_cb(datacontrol_h provider, datacontrol_sql_response_cb* callback, void *user_data);
+
+/**
+ * @brief              Unregisters the callback function in @c provider.
+ * @param [in] provider        The provider handle
+ * @return             0 on success, otherwise a negative error value.
+ */
+EXPORT_API int datacontrol_sql_unregister_response_cb(datacontrol_h provider);
+
+/**
+ * @brief              Deletes rows of a table owned by the SQL-type data control provider
+ *
+ * @remarks            If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
+ * @param [in] provider        The provider handle
+ * @param [in] where   A filter to select the desired rows to delete. @n
+ *                                             It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param [out]        request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_delete() method.
+ *
+ * @code
+ *
+ *     void sql_delete_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
+ *             if (provider_result) {
+ *                     LOGI("The delete operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The delete operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_sql_response_cb sql_callback;
+ *
+ *     int main()
+ *     {
+ *             const char *where = "group = 'friend'";
+ *             int result = 0;
+ *             int req_id = 0;
+ *
+ *             sql_callback.delete = sql_delete_response_cb;
+ *             result = datacontrol_sql_register_response_cb(provider, &sql_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_sql_delete(provider, where, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Deleting is failed with error: %d", result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_delete(datacontrol_h provider, const char *where, int *request_id);
+
+/**
+ * @brief              Inserts new rows in a table owned by the SQL-type data control provider
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] insert_data     The column-value pairs to insert. @n
+ *                                                     If the value is a string, the value must be wrapped in single quotes,
+ *                                                     else it does not need to be wrapped in single quotes.
+ * @param [out]        request_id      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_insert() method.
+ *
+ * @code
+ *
+ *     void sql_insert_response_cb(int request_id, datacontrol_h provider, long long inserted_row_id, bool provider_result, const char *error) {
+ *             if (provider_result) {
+ *                     LOGI("The insert operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The insert operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_sql_response_cb sql_callback;
+ *
+ *     int main()
+ *     {
+ *             int result = 0;
+ *             int req_id = 0;
+ *             bundle *b = NULL;
+ *
+ *             sql_callback.insert = sql_insert_response_cb;
+ *             result = datacontrol_sql_register_response_cb(provider, &sql_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             b = bundle_create();
+ *             bundle_add_str(b, "WORD", "test");
+ *             bundle_add_str(b, "WORD_DESC", "test description");
+ *
+ *             result = datacontrol_sql_insert(provider, b, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Inserting is failed with error: %d", result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             bundle_free(b);
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_insert(datacontrol_h provider, const bundle* insert_data, int *request_id);
+
+/**
+ * @brief              Selects the specified columns to be queried
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] column_list             The column list to query
+ * @param [in] column_count            The total number of columns to be queried
+ * @param [in] where                   A filter to select the desired rows. @n
+ *                                                             It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param [in] order                   The sorting order of the rows to query. @n
+ *                                                             It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
+ * @param [out]        request_id              The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_select() method.
+ *
+ * @code
+ *
+ *     void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *enumerator, bool provider_result, const char *error) {
+ *             if (provider_result) {
+ *                     LOGI("The select operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The select operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_sql_response_cb sql_callback;
+ *
+ *     int main()
+ *     {
+ *             int result = 0;
+ *             int req_id = 0;
+ *             char *column_list[2];
+ *             column_list[0] = "WORD";
+ *             column_list[1] = "WORD_DESC";
+ *             const char *where = "WORD = 'test'";
+ *             const char *order = "WORD ASC";
+ *
+ *             sql_callback.select = sql_select_response_cb;
+ *             result = datacontrol_sql_register_response_cb(provider, &sql_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             result = datacontrol_sql_select(provider, column_list, 2, where, order, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Selecting is failed with error: %d", result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_select(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id);
+
+/**
+ * @brief              Selects the specified columns to be queried
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] column_list             The column list to query
+ * @param [in] column_count            The total number of columns to be queried
+ * @param [in] where                   A filter to select the desired rows. @n
+ *                                                             It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param [in] order                   The sorting order of the rows to query. @n
+ *                                                             It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
+ * @param [in] page_number             The page number of the result set @n
+ *                                                             It starts from 1.
+ * @param [in] count_per_page          The desired maximum count of rows on a page
+ * @param [out]        request_id                      The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        datacontrol_sql_select()
+ */
+EXPORT_API int datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id);
+
+/**
+ * @brief              Updates values of a table owned by the SQL-type data control provider.
+ *
+ * @param [in] provider        The provider handle
+ * @param [in] update_data             The column-value pairs to update. @n
+ *                                                             If the value is a string, the value must be wrapped in single quotes,
+ *                                                             else it does not need to be wrapped in single quotes.
+ * @param [in] where                   A filter to select the desired rows to update. @n
+ *                                                             It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param [out]        request_id              The request ID
+ * @return             0 on success, otherwise a negative error value.
+ * @retval #DATACONTROL_ERROR_NONE     Successful
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
+ *
+ * The following example demonstrates how to use the %datacontrol_sql_update() method.
+ *
+ * @code
+ *
+ *     void sql_update_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
+ *             if (provider_result) {
+ *                     LOGI("The update operation is successful");
+ *             }
+ *             else {
+ *                     LOGI("The update operation for the request %d is failed. error message: %s", request_id, error);
+ *             }
+ *     }
+ *
+ *     datacontrol_sql_response_cb sql_callback;
+ *
+ *     int main()
+ *     {
+ *             int result = 0;
+ *             int req_id = 0;
+ *             const char *where = "WORD = 'test'";
+ *             bundle *b = NULL;
+ *
+ *             sql_callback.update = sql_update_response_cb;
+ *             result = datacontrol_sql_register_response_cb(provider, &sql_callback);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Registering the callback function is failed with error: %d", result);
+ *                     return result;
+ *             }
+ *
+ *             b = bundle_create();
+ *             bundle_add_str(b, "WORD", "test_new");
+ *
+ *             result = datacontrol_sql_update(provider, b, where, &req_id);
+ *             if (result != DATACONTROL_ERROR_NONE) {
+ *                     LOGE("Updating is failed with error: %d", result);
+ *             }
+ *             else {
+ *                     LOGI("req_id is %d", req_id);
+ *             }
+ *
+ *             bundle_free(b);
+ *             return result;
+ *     }
+ *
+ * @endcode
+ */
+EXPORT_API int datacontrol_sql_update(datacontrol_h provider, const bundle* update_data, const char *where, int *request_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _APPFW_DATA_CONTROL_SQL_H_ */
+
diff --git a/include/data-control-types.h b/include/data-control-types.h
new file mode 100644 (file)
index 0000000..4b8e1ea
--- /dev/null
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file       data-control-types.h
+ * @brief      This is the header file for data types of the data-control.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_TYPES_H_
+#define _APPFW_DATA_CONTROL_TYPES_H_
+
+#include <errno.h>
+
+#ifdef __GNUC__
+#   ifndef EXPORT_API
+#       define EXPORT_API __attribute__((visibility("default")))
+#   endif
+#else
+#   define EXPORT_API
+#endif
+
+/**
+ * @brief Provider handle
+ */
+typedef struct datacontrol_s *datacontrol_h;
+
+/**
+ * @brief Enumerations of different types of columns in an SQL table.
+ */
+typedef enum
+{
+       DATACONTROL_SQL_COLUMN_TYPE_UNDEFINED = 0,
+       DATACONTROL_SQL_COLUMN_TYPE_INT64,
+       DATACONTROL_SQL_COLUMN_TYPE_DOUBLE,
+       DATACONTROL_SQL_COLUMN_TYPE_TEXT,
+       DATACONTROL_SQL_COLUMN_TYPE_BLOB,
+       DATACONTROL_SQL_COLUMN_TYPE_NULL
+} datacontrol_sql_column_type;
+
+/**
+ * @brief Enumerations of the various error-codes an API can return.
+ */
+typedef enum
+{
+       DATACONTROL_ERROR_NONE = 0, /**< Successful */
+       DATACONTROL_ERROR_OUT_OF_MEMORY = -ENOMEM, /**< Out of memory */
+       DATACONTROL_ERROR_IO_ERROR = -EIO, /**< I/O error */
+       DATACONTROL_ERROR_INVALID_PARAMETER = -EINVAL, /**< Invalid parameter */
+       DATACONTROL_ERROR_PERMISSION_DENIED = -EACCES, /**< Permission denied */
+       DATACONTROL_ERROR_MAX_EXCEEDED  = -EMSGSIZE /**< Too long argument */
+} datacontrol_error_e;
+
+#endif /* _APPFW_DATA_CONTROL_TYPES_H_ */
+
diff --git a/include/data-control.h b/include/data-control.h
new file mode 100644 (file)
index 0000000..e1b84c0
--- /dev/null
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file       data-control.h
+ * @brief      This is the header file for the data control.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_H_
+#define _APPFW_DATA_CONTROL_H_
+
+#include <data-control-sql.h>
+#include <data-control-sql-cursor.h>
+#include <data-control-provider.h>
+
+#endif /* _APPFW_DATA_CONTROL_H_ */
+
diff --git a/include/data_control.h b/include/data_control.h
new file mode 100644 (file)
index 0000000..94f07d6
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_APPFW_DATA_CONTROL_H__
+#define __TIZEN_APPFW_DATA_CONTROL_H__
+
+#include <tizen.h>
+#include <data_control_sql.h>
+#include <data_control_map.h>
+#include <data_control_provider.h>
+
+/**
+ * @file   data_control.h
+ * @brief  This is the header file for the data control.
+ */
+
+#endif /* __TIZEN_APPFW_DATA_CONTROL_H__ */
+
diff --git a/include/data_control_internal.h b/include/data_control_internal.h
new file mode 100644 (file)
index 0000000..387256c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+
+#ifndef __TIZEN_APPFW_DATA_CONTROL_INTERNAL_H__
+#define __TIZEN_APPFW_DATA_CONTROL_INTERNAL_H__
+
+#include <data-control-types.h>
+#include "data_control_types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int convert_to_tizen_error(datacontrol_error_e error);
+int data_control_error(data_control_error_e error,
+               const char *function, const char *description);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  __TIZEN_APPFW_DATA_CONTROL_INTERNAL_H__ */
diff --git a/include/data_control_map.h b/include/data_control_map.h
new file mode 100644 (file)
index 0000000..d6e7c9b
--- /dev/null
@@ -0,0 +1,617 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_APPFW_DATA_CONTROL_MAP_H__
+#define __TIZEN_APPFW_DATA_CONTROL_MAP_H__
+
+#include <data_control_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file   data_control_map.h
+ * @brief  This is the header file for the key-value structured data control.
+ */
+
+/**
+ * @addtogroup CAPI_DATA_CONTROL_CONSUMER_MODULE
+ * @{
+ */
+
+/**
+ * @brief  Called when the result value list is received from the key-value structured data control provider.
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a resule_value_list using free() after it is used. Note that @a result_value list is an array of char *. Its length is @a result_value_count. You should release all the elements in the @a result_value_list array and @a result_value_list itself like the following code.
+ *
+ * @code
+ *
+ *  int i;
+ *  for (i = 0; i < resule_value_count; i++)
+ *      free(result_value_list[i]);
+ *  free(result_value_list);
+ *
+ * @endcode
+
+ * @param[in]  request_id          The request ID
+ * @param[in]  provider            The provider handle
+ * @param[in]  result_value_list   The result value list of the data control request that gets the matching values
+ * @param[in]  result_value_count  The number of the values
+ * @param[in]  provider_result     Set to @c true if the data control provider is successfully processed, \n
+ *                                 otherwise set to @c false
+ * @param[in]  error               The error message from the data control provider
+ * @param[in]  user_data           The user data passed from the register function
+ */
+typedef void (*data_control_map_get_response_cb)(int request_id, data_control_h provider,
+        char **result_value_list, int result_value_count, bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  Called when the response is received from the key-value structured data control provider.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id       The request ID that identifies the data control
+ * @param[in]  provider         The provider handle
+ * @param[in]  provider_result  Set to @c true if the data control provider successfully processed, \n
+ *                              otherwise @c false
+ * @param[in]  error            The error message from the data control provider
+ * @param[in]  user_data        The user data passed from the register function
+ */
+typedef void (*data_control_map_set_response_cb)(int request_id, data_control_h provider,
+        bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  Called when the response is received from the key-value structured data control provider.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id       The request ID that identifies the data control
+ * @param[in]  provider         The provider handle
+ * @param[in]  provider_result  Set to @c true if the data control provider successfully processed, \n
+ *                              otherwise set to @c false
+ * @param[in]  error            The error message from the data control provider
+ * @param[in]  user_data        The user data passed from the register function
+ */
+typedef void (*data_control_map_add_response_cb)(int request_id, data_control_h provider,
+        bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  Called when the response is received from the key-value structured data control provider.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id       The request ID that identifies the data control
+ * @param[in]  provider         The provider handle
+ * @param[in]  provider_result  Set to @c true if the data control provider successfully processed, \n
+ *                              otherwise set to @c false
+ * @param[in]  error            The error message from the data control provider
+ * @param[in]  user_data        The user data passed from the register function
+ */
+typedef void (*data_control_map_remove_response_cb)(int request_id, data_control_h provider,
+        bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  The structure type to contain the set of callback functions for handling the response events
+ *         of the key-value structured data control.
+ * @since_tizen 2.3
+ *
+ * @see  data_control_map_get_response_cb()
+ * @see  data_control_map_set_response_cb()
+ * @see  data_control_map_add_response_cb()
+ * @see  data_control_map_remove_response_cb()
+ */
+typedef struct
+{
+    data_control_map_get_response_cb get_cb; /**< This callback function is called when the response is received for a getting value from the key-value structured data control provider. */
+    data_control_map_set_response_cb set_cb; /**< This callback function is called when the response is received for a setting value from the key-value structured data control provider. */
+    data_control_map_add_response_cb add_cb; /**< This callback function is called when the response is received for a adding value from the key-value structured data control provider. */
+    data_control_map_remove_response_cb remove_cb; /**< This callback function is called when the response is for a removing value received from the key-value structured data control provider. */
+} data_control_map_response_cb;
+
+/**
+ * @brief  Creates a provider handle.
+ * @since_tizen 2.3
+ *
+ * @remarks The following example demonstrates how to use the %data_control_map_create() method.
+ *
+ * @code
+ *
+ *  int main()
+ *  {
+ *      const char *provider_id = "http://tizen.org/datacontrol/provider/example";
+ *      const char *data_id = "table";
+ *      data_control_h provider;
+ *      int result = 0;
+ *
+ *      result = data_control_map_create(&provider);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Creating data control provider is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_map_set_provider_id(provider, provider_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Setting providerID is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_map_set_data_id(provider, data_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Setting dataID is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      // Executes some operations
+ *
+ *      result = data_control_map_destroy(provider);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Destorying data control provider is failed with error: %d", result);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+
+ * @param[out]  provider  The provider handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see        data_control_map_destroy()
+
+ */
+int data_control_map_create(data_control_h *provider);
+
+/**
+ * @brief  Destroys the provider handle and releases all its resources.
+ * @since_tizen 2.3
+ *
+ * @remarks  When operations of data control are finished, this function must be called to prevent memory leak.
+ *
+ * @param[in]  provider  The provider handle
+ *
+ * @return   @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @see data_control_map_create()
+ */
+int data_control_map_destroy(data_control_h provider);
+
+/**
+ * @brief  Sets the Provider ID.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider     The provider handle
+ * @param[in]  provider_id  The data control provider ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE               Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY      Out of memory
+ *
+ * @see        data_control_map_get_provider_id()
+ */
+int data_control_map_set_provider_id(data_control_h provider, const char *provider_id);
+
+/**
+ * @brief  Gets the Provider ID.
+ * @since_tizen 2.3
+ *
+ * @remarks  You must release @a provider_id using free() after it is used.
+ *
+ * @param[in]   provider     The provider handle
+ * @param[out]  provider_id  The data control provider ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see  data_control_map_set_provider_id()
+ */
+int data_control_map_get_provider_id(data_control_h provider, char **provider_id);
+
+/**
+ * @brief  Sets the Data ID.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider  The provider handle
+ * @param[in]  data_id   A string for identifying a specific table to operate \n
+ *                       The string consists of one or more components separated by a slash('/').
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see  data_control_map_get_data_id()
+ */
+int data_control_map_set_data_id(data_control_h provider, const char *data_id);
+
+/**
+ * @brief  Gets the data ID.
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a data_id using free() after it is used.
+ *
+ * @param[in]   provider  The provider handle
+ * @param[out]  data_id   A string for identifying a specific table to operate \n
+ *                        The string consists of one or more components separated by a slash('/').
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see  data_control_map_set_data_id()
+ */
+int data_control_map_get_data_id(data_control_h provider, char **data_id);
+
+/**
+ * @brief  Registers a callback function for the key-value structured data control response.
+ *         The application is notified when a data control response is received from the @a provider.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider  The provider handle
+ * @param[in]  callback  The callback function to be called when a response is received
+ * @param[in]  user_data The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE          Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR      I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see        data_control_map_unregister_response_cb()
+ */
+int data_control_map_register_response_cb(data_control_h provider, data_control_map_response_cb* callback, void *user_data);
+
+/**
+ * @brief  Unregisters the callback function in the @a provider.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider  The provider handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ */
+int data_control_map_unregister_response_cb(data_control_h provider);
+
+/**
+ * @brief  Gets the value list associated with the specified @a key from the key-values map owned by the key-value structured data control provider.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks If the length of value list associated with the @a key is larger than 20, this API only returns the first 20 values.
+ * @remarks The following example demonstrates how to use the %data_control_map_get() method.
+ *
+ * @code
+ *
+ *  void map_get_response_cb(int request_id, data_control_h provider,
+ *          char **result_value_list, int ret_value_count,  bool provider_result, const char *error, void *user_data)
+ *  {
+ *      if (provider_result) {
+ *          LOGI("The get operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The get operation for the request %d is failed. error message: %s", request_id, error);
+ *      }
+ *  }
+ *
+ *  data_control_map_response_cb map_callback;
+ *
+ *  int main()
+ *  {
+ *      int result = 0;
+ *      int req_id = 0;
+ *      char *key = "key";
+ *
+ *      map_callback.get_cb = map_get_response_cb;
+ *      result = data_control_map_register_response_cb(provider, &map_callback, NULL);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_map_get(provider, key, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Getting the value list of the key(%s) is failed with error: %d", key, result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+ *
+ * @param[in]   provider    The provider handle
+ * @param[in]   key         The key of the value list to obtain
+ * @param[out]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_MAX_EXCEEDED      Too long argument
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ *
+ * @see data_control_map_get_with_page()
+ */
+int data_control_map_get(data_control_h provider, const char *key, int *request_id);
+
+/**
+ * @brief  Gets the value list associated with the specified @a key from the key-values map owned by the key-value structured data control provider.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ *
+ * @param[in]   provider        The provider handle
+ * @param[in]   key             The key of the value list to obtain
+ * @param[out]  request_id      The request ID
+ * @param[in]   page_number     The page number of the value set \n
+ *                              It starts from @c 1.
+ * @param [in]  count_per_page  The desired maximum count of the data items per page
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_MAX_EXCEEDED      Too long argument
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ *
+ * @see data_control_map_get()
+ */
+int data_control_map_get_with_page(data_control_h provider, const char *key, int *request_id, int page_number, int count_per_page);
+
+/**
+ * @brief  Sets the value associated with the specified @a key to a new value.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks The following example demonstrates how to use the %data_control_map_set() method.
+ *
+ * @code
+ *
+ *  void map_set_response_cb(int request_id, data_control_h provider, bool provider_result, const char *error, void *user_data)
+ *  {
+ *      if (provider_result) {
+ *          LOGI("The set operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The set operation for the request %d is failed. error message: %s", request_id, error);
+ *      }
+ *  }
+ *
+ *  data_control_map_response_cb map_callback;
+ *
+ *  int main()
+ *  {
+ *      int result = 0;
+ *      int req_id = 0;
+ *      char *key = "key";
+ *      char *old_value = "old value";
+ *      char *new_value = "new value";
+ *
+ *      map_callback.set_cb = map_set_response_cb;
+ *      result = data_control_map_register_response_cb(provider, &map_callback, NULL);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_map_set(provider, key, old_value, new_value, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Replacing old_value(%s) with new_value(%s) is failed with error: %d", old_value, new_value, result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+
+ * @param[in]   provider    The provider handle
+ * @param[in]   key         The key of the value to replace
+ * @param[in]   old_value   The value to replace
+ * @param[in]   new_value   The new value that replaces the existing value
+ * @param[out]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_MAX_EXCEEDED      Too long argument
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_map_set(data_control_h provider, const char *key, const char *old_value, const char *new_value, int *request_id);
+
+/**
+ * @brief  Adds the @a value associated with the specified @a key to the key-values map owned by the key-value structured data control provider.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks The following example demonstrates how to use the %data_control_map_add() method.
+ *
+ * @code
+ *
+ *  void map_add_response_cb(int request_id, data_control_h provider, bool provider_result, const char *error, void *user_data) {
+ *      if (provider_result) {
+ *          LOGI("The add operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The add operation for the request %d is failed. error message: %s", request_id, error);
+ *      }
+ *  }
+ *
+ *  data_control_map_response_cb map_callback;
+ *
+ *  int main()
+ *  {
+ *      int result = 0;
+ *      int req_id = 0;
+ *      const char *key = "key";
+ *      const char *value = "value";
+ *
+ *      map_callback.add_cb = map_add_response_cb;
+ *      result = data_control_map_register_response_cb(provider, &map_callback, NULL);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_map_add(provider, key, value, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Adding %s-%s pair is failed with error: %d", key, value, result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+
+ * @param[in]   provider    The provider handle
+ * @param[in]   key         The key of the value to add
+ * @param[in]   value       The value to add
+ * @param[out]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_MAX_EXCEEDED      Too long argument
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_map_add(data_control_h provider, const char *key, const char *value, int *request_id);
+
+/**
+ * @brief  Removes the @a value associated with the specified @a key from the key-values map owned by the key-value structured data control provider.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks The following example demonstrates how to use the %data_control_map_remove() method.
+ *
+ * @code
+ *
+ *  void map_remove_response_cb(int request_id, data_control_h provider, bool provider_result, const char *error, void *user_data) {
+ *      if (provider_result) {
+ *          LOGI("The remove operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The remove operation for the request %d is failed. error message: %s", request_id, error);
+ *     }
+ *  }
+ *
+ *  data_control_map_response_cb map_callback;
+ *
+ *  int main()
+ *  {
+ *      int result = 0;
+ *      int req_id = 0;
+ *      const char *key = "key";
+ *      const char *value = "value";
+ *
+ *      map_callback.remove_cb = map_remove_response_cb;
+ *      result = data_control_map_register_response_cb(provider, &map_callback, NULL);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_map_remove(provider, key, value, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Removing %s-%s pair is failed with error: %d", key, value, result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+ *
+ * @param[in]   provider    The provider handle
+ * @param[in]   key         The key of the value to remove
+ * @param[in]   value       The value to remove
+ * @param[out]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_MAX_EXCEEDED      Too long argument
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_map_remove(data_control_h provider, const char *key, const char *value, int *request_id);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_APPFW_DATA_CONTROL_MAP_H__ */
diff --git a/include/data_control_provider.h b/include/data_control_provider.h
new file mode 100644 (file)
index 0000000..2690c97
--- /dev/null
@@ -0,0 +1,471 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_APPFW_DATA_CONTROL_PROVIDER_H_
+#define __TIZEN_APPFW_DATA_CONTROL_PROVIDER_H_
+
+#include <data_control_types.h>
+#include <data_control_sql_cursor.h>
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file   data_control_provider.h
+ * @brief  This is the header file for the data control provider.
+ */
+
+/**
+ * @addtogroup CAPI_DATA_CONTROL_PROVIDER_MODULE
+ * @{
+ */
+
+/**
+ * @brief  Called when the insert request is received from an application using SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id   The request ID
+ * @param[in]  provider     The provider handle
+ * @param[in]  insert_data  The column-value pairs to insert \n
+ *                          If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
+ * @param[in]  user_data    The user data passed from the register function
+ */
+typedef void (*data_control_provider_sql_insert_request_cb)(int request_id, data_control_h provider,
+        bundle *insert_data, void *user_data);
+
+/**
+ * @brief  Called when the update request is received from an application using SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id   The request ID
+ * @param[in]  provider     The provider handle
+ * @param[in]  update_data  The column-value pairs to update \n
+ *                          If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
+ * @param[in]  where        A filter to select the desired rows to update \n
+ *                          It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param[in]  user_data    The user data passed from the register function
+ */
+typedef void (*data_control_provider_sql_update_request_cb)(int request_id, data_control_h provider,
+        bundle *update_data, const char *where, void *user_data);
+
+/**
+ * @brief  Called when the delete request is received from an application using SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  provider    The provider handle
+ * @param[in]  where       A filter to select the desired rows to delete \n
+ *                         It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param[in]  user_data   The user data passed from the register function
+ */
+typedef void (*data_control_provider_sql_delete_request_cb)(int request_id, data_control_h provider,
+        const char *where, void *user_data);
+
+/**
+ * @brief  Called when the select request is received from an application using SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id    The request ID
+ * @param[in]  provider      The provider handle
+ * @param[in]  column_list   The column list to query
+ * @param[in]  column_count  The total number of columns to be queried
+ * @param[in]  where         A filter to select the desired rows \n
+ *                           It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param[in]  order         The sorting order of the rows to query \n
+ *                           It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
+ * @param[in]  user_data     The user data passed from the register function
+ */
+typedef void (*data_control_provider_sql_select_request_cb)(int request_id, data_control_h provider,
+        const char **column_list, int column_count, const char *where, const char *order, void *user_data);
+
+/**
+ * @brief  Called when the request for obtaining the value list is received from the key-value structured data control consumer.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  provider    The provider handle
+ * @param[in]  key         The key of the value list to obtain
+ * @param[in]  user_data   The user data passed from the register function
+ */
+typedef void (*data_control_provider_map_get_value_request_cb)(int request_id, data_control_h provider, const char *key, void *user_data);
+
+/**
+ * @brief  Called when the request for replacing the value is received from the key-value structured data control consumer.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  provider    The provider handle
+ * @param[in]  key         The key of the value to replace
+ * @param[in]  old_value   The value to replace
+ * @param[in]  new_value   The new value that replaces the existing value
+ * @param[in]  user_data   The user data passed from the register function
+ */
+typedef void (*data_control_provider_map_set_value_request_cb)(int request_id, data_control_h provider, const char *key,
+        const char *old_value, const char *new_value, void *user_data);
+
+/**
+ * @brief  Called when the request for adding the value is received from the key-value structured data control consumer.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  provider    The provider handle
+ * @param[in]  key         The key of the value to add
+ * @param[in]  value       The value to add
+ * @param[in]  user_data   The user data passed from the register function
+ */
+typedef void (*data_control_provider_map_add_value_request_cb)(int request_id, data_control_h provider, const char *key,
+        const char *value, void *user_data);
+
+/**
+ * @brief  Called when the request for removing the value is received from the key-value structured data control consumer.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  provider    The provider handle
+ * @param[in]  key         The key of the value to remove
+ * @param[in]  value       The value to remove
+ * @param[in]  user_data   The user data passed from the register function
+ */
+typedef void (*data_control_provider_map_remove_value_request_cb)(int request_id, data_control_h provider, const char *key,
+        const char *value, void *user_data);
+
+/**
+ * @brief  The structure type to contain the set of callback functions for handling the request events
+ *         of SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @see  data_control_provider_sql_select_request_cb()
+ * @see  data_control_provider_sql_insert_request_cb()
+ * @see  data_control_provider_sql_update_request_cb()
+ * @see  data_control_provider_sql_delete_request_cb()
+ */
+typedef struct
+{
+    data_control_provider_sql_insert_request_cb insert_cb; /**< This callback function is called when a request for insert operation is received from other application. */
+    data_control_provider_sql_select_request_cb select_cb; /**< This callback function is called when a request for select operation is received from other application. */
+    data_control_provider_sql_update_request_cb update_cb; /**< This callback function is called when a request for update operation is received from other application. */
+    data_control_provider_sql_delete_request_cb delete_cb; /**< This callback function is called when a request for delete operation is received from other application. */
+} data_control_provider_sql_cb;
+
+/**
+ * @brief  The structure type to contain the set of callback functions for handling the request events
+ *         from the key-value structured data control consumer.
+ * @since_tizen 2.3
+ *
+ * @see  data_control_provider_map_get_value_request_cb()
+ * @see  data_control_provider_map_set_value_request_cb()
+ * @see  data_control_provider_map_add_value_request_cb()
+ * @see  data_control_provider_map_remove_value_request_cb()
+ */
+typedef struct
+{
+    data_control_provider_map_get_value_request_cb get_cb; /**< This callback function is called when a request for getting value is received from other application. */
+    data_control_provider_map_set_value_request_cb set_cb; /**< This callback function is called when a request for setting value is received from other application. */
+    data_control_provider_map_add_value_request_cb add_cb; /**< This callback function is called when a request for adding value is received from other application. */
+    data_control_provider_map_remove_value_request_cb remove_cb; /**< This callback function is called when a request for removing value is received from other application. */
+} data_control_provider_map_cb;
+
+/**
+ * @brief  Registers a callback function for the SQL data control request.
+ *         The provider is notified when a data control request is received from the client applications.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing
+ *
+ * @param[in]  callback  The callback function to be called when a data control request is received
+ * @param[in]  user_data The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_provider_sql_register_cb(data_control_provider_sql_cb *callback, void *user_data);
+
+/**
+ * @brief  Unregisters the callback functions.
+ * @since_tizen 2.3
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ */
+int data_control_provider_sql_unregister_cb(void);
+
+/**
+ * @brief  Registers a callback function for the map data control request.
+ *         The provider is notified when a data control request is received from the client applications.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing
+ *
+ * @param[in]  callback  The callback function to be called when a data control request is received
+ * @param[in]  user_data The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_provider_map_register_cb(data_control_provider_map_cb *callback, void *user_data);
+
+/**
+ * @brief  Unregisters the callback functions.
+ * @since_tizen 2.3
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ */
+int data_control_provider_map_unregister_cb(void);
+
+/**
+ * @brief  Gets the application ID which sends the data control request.
+ * @since_tizen 2.3
+ *
+ * @param[in]   request_id  The request ID
+ * @param[out]  appid       The application ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_provider_get_client_appid(int request_id, char **appid);
+
+/**
+ * @brief  Sends the success result and the result set of the select request to the client application.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  db_handle   The result DB handle for the result set
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_provider_send_select_result(int request_id, void *db_handle);
+
+/**
+ * @brief  Sends the success result of the insert request and the last inserted row ID to the client application.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  row_id      The row ID of the database changed by the insert request
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_provider_send_insert_result(int request_id, long long row_id);
+
+/**
+ * @brief  Sends the success result of the update request to the client application.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_provider_send_update_result(int request_id);
+
+/**
+ * @brief  Sends the success result of the delete request to the client application.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_provider_send_delete_result(int request_id);
+
+/**
+ * @brief  Sends the provider error message to the client application.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ * @param[in]  error       The provider-defined error message
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_provider_send_error(int request_id, const char *error);
+
+/**
+ * @brief  Sends the success result of the request for setting, adding and removing the key-value structured data the client application.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_provider_send_map_result(int request_id);
+
+/**
+ * @brief  Sends the success result of the request for getting the value list to the client application.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id   The request ID
+ * @param[in]  value_list   The result value list
+ * @param[in]  value_count  The number of the values
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_provider_send_map_get_value_result(int request_id, char **value_list, int value_count);
+
+/**
+ * @brief  Creates SQL INSERT statement.
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider    The provider handle
+ * @param[in]  insert_map  The column-value pairs to insert
+ *
+ * @return  The SQL INSERT statement on success, otherwise NULL
+ * @exception DATA_CONTROL_ERROR_NONE  Success
+ * @exception DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception DATA_CONTROL_ERROR_INVALID_PARAMETER     Invalid parameter
+ */
+char* data_control_provider_create_insert_statement(data_control_h provider, bundle *insert_map);
+
+/**
+ * @brief  Creates SQL DELETE statement.
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider  The provider handle
+ * @param[in]  where      A filter to select the desired rows to delete \n
+ *                        Pass @c NULL if all rows need to be deleted.
+ *
+ * @return  The SQL DELETE statement on success, otherwise NULL
+ * @exception DATA_CONTROL_ERROR_NONE  Success
+ * @exception DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception DATA_CONTROL_ERROR_INVALID_PARAMETER     Invalid parameter
+ */
+char* data_control_provider_create_delete_statement(data_control_h provider, const char *where);
+
+/**
+ * @brief  Creates SQL UPDATE statement.
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider    The provider handle
+ * @param[in]  update_map  The column-value pairs to update
+ * @param[in]  where       A filter to select the desired rows to update
+ *
+ * @return The SQL UPDATE statement on success, otherwise NULL
+ * @exception DATA_CONTROL_ERROR_NONE  Success
+ * @exception DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception DATA_CONTROL_ERROR_INVALID_PARAMETER     Invalid parameter
+ */
+char* data_control_provider_create_update_statement(data_control_h provider, bundle *update_map, const char *where);
+
+/**
+ * @brief  Creates SQL SELECT statement.
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider      The provider handle
+ * @param[in]  column_list   The column names to query \n
+ *                           Pass @c NULL if all columns need to be selected.
+ * @param[in]  column_count  The total number of columns to be queried
+ * @param[in]  where         A filter to select the desired rows
+ * @param[in]  order         The sorting order of rows to query
+ *
+ * @return  The SQL SELECT statement on success, otherwise NULL
+ * @exception DATA_CONTROL_ERROR_NONE  Success
+ * @exception DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception DATA_CONTROL_ERROR_INVALID_PARAMETER     Invalid parameter
+ */
+char* data_control_provider_create_select_statement(data_control_h provider, const char **column_list, int column_count, const char *where, const char *order);
+
+/**
+ * @brief  Checks whether the given provider ID matches the provider handle's provider ID.
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider     The provider handle
+ * @param[in]  provider_id  The provider ID to be compared with handle's provider ID
+ *
+ * @return  @c true if the provider_id matches,
+ *          otherwise @c false if it does not match
+ * @exception DATA_CONTROL_ERROR_NONE  Success
+ * @exception DATA_CONTROL_ERROR_INVALID_PARAMETER     Invalid parameter
+ */
+bool data_control_provider_match_provider_id(data_control_h provider, const char *provider_id);
+
+/**
+ * @brief  Checks whether the given data ID matches the provider handle's data ID.
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider  The provider handle
+ * @param[in]  data_id   The data ID to be compared with handle's data ID
+ *
+ * @return  @c true if the @a data_id matches,
+ *          otherwise @c false if it does not match
+ * @exception DATA_CONTROL_ERROR_NONE  Success
+ * @exception DATA_CONTROL_ERROR_INVALID_PARAMETER     Invalid parameter
+ */
+bool data_control_provider_match_data_id(data_control_h provider, const char *data_id);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_APPFW_DATA_CONTROL_PROVIDER_H_ */
+
diff --git a/include/data_control_sql.h b/include/data_control_sql.h
new file mode 100644 (file)
index 0000000..9f1f4bd
--- /dev/null
@@ -0,0 +1,624 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_APPFW_DATA_CONTROL_SQL_H__
+#define __TIZEN_APPFW_DATA_CONTROL_SQL_H__
+
+#include <data_control_types.h>
+#include <data_control_sql_cursor.h>
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file   data_control_sql.h
+ * @brief  This is the header file for the SQL-friendly interface based data control.
+ */
+
+/**
+ * @addtogroup CAPI_DATA_CONTROL_CONSUMER_MODULE
+ * @{
+ */
+
+/**
+ * @brief  Called when a response is received for an insert operation from an application using the SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id       The request ID
+ * @param[in]  provider         The provider handle
+ * @param[in]  inserted_row_id  The inserted row ID set by the data control
+ * @param[in]  provider_result  Set to @c true if the data control provider successfully processed, \n
+ *                              otherwise set to @c false
+ * @param[in]  error            The error message from the data control provider
+ * @param[in]  user_data        The user data passed from the register function
+ */
+typedef void (*data_control_sql_insert_response_cb)(int request_id, data_control_h provider,
+        long long inserted_row_id, bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  Called when a response is received for a delete operation from an application using the SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id       The request ID that identifies the data control
+ * @param[in]  provider_result  Set to @c true if the data control provider successfully processed, \n
+ *                              otherwise set to @c false
+ * @param[in]  error            The error message from the data control provider
+ * @param[in]  user_data        The user data passed from the register function
+ */
+typedef void (*data_control_sql_delete_response_cb)(int request_id, data_control_h provider,
+        bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  Called when a response is received for a select operation from an application using the SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @remarks  @a enumerator will be removed after this callback is called.
+ *
+ * @param[in]  request_id       The request ID
+ * @param[in]  provider         The provider handle
+ * @param[in]  enumerator       The enumerator for navigating the result of data control select request
+ * @param[in]  provider_result  Set to @c true if the data control provider successfully processed, \n
+ *                              otherwise set to @c false
+ * @param[in]  error            The error message from the data control provider
+ * @param[in]  user_data        The user data passed from the register function
+ */
+typedef void (*data_control_sql_select_response_cb)(int request_id, data_control_h provider,
+        result_set_cursor enumerator, bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  Called when a response is received for an update operation from an application using the SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @param[in]  request_id       The request ID
+ * @param[in]  provider         The provider handle
+ * @param[in]  provider_result  Set to @c true if the data control provider successfully processed, \n
+ *                              otherwise set to @c false
+ * @param[in]  error            The error message from the data control provider
+ * @param[in]  user_data        The user data passed from the register function
+ */
+typedef void (*data_control_sql_update_response_cb)(int request_id, data_control_h provider,
+        bool provider_result, const char *error, void *user_data);
+
+/**
+ * @brief  The structure type to contain the set of callback functions for handling the response events
+ *         of the SQL-friendly interface based data control.
+ * @since_tizen 2.3
+ *
+ * @see  data_control_sql_select_response_cb()
+ * @see  data_control_sql_insert_response_cb()
+ * @see  data_control_sql_update_response_cb()
+ * @see  data_control_sql_delete_response_cb()
+ */
+typedef struct
+{
+    data_control_sql_select_response_cb select_cb; /**< This callback function is called when a response is received for an select operation from an application using the SQL-friendly interface based data control. */
+    data_control_sql_insert_response_cb insert_cb; /**< This callback function is called when a response is received for an insert operation from an application using the SQL-friendly interface based data control. */
+    data_control_sql_update_response_cb update_cb; /**< This callback function is called when a response is received for an update operation from an application using the SQL-friendly interface based data control. */
+    data_control_sql_delete_response_cb delete_cb; /**< This callback function is called when a response is received for a delete operation from an application using the SQL-friendly interface based data control. */
+} data_control_sql_response_cb;
+
+/**
+ * @brief  Creates a provider handle.
+ * @since_tizen 2.3
+ *
+ * @remarks The following example demonstrates how to use the %data_control_sql_create() method:
+ *
+ * @code
+ *
+ *  int main()
+ *  {
+ *      const char *provider_id = "http://tizen.org/datacontrol/provider/example";
+ *      const char *data_id = "table";
+ *      data_control_h provider;
+ *      int result = 0;
+ *
+ *      result = data_control_sql_create(&provider);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Creating data control provider is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_sql_set_provider_id(provider, provider_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Setting providerID is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_sql_set_data_id(provider, data_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Setting dataID is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      // Executes some operations
+ *
+ *      result = data_control_sql_destroy(provider);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Destroying data control provider is failed with error: %d", result);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+
+ * @param[out]  provider  The provider handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see  data_control_sql_destroy()
+ */
+int data_control_sql_create(data_control_h *provider);
+
+/**
+ * @brief  Destroys the provider handle and releases all its resources.
+ * @since_tizen 2.3
+ *
+ * @remarks  When operations of data control are finished, this function must be called to prevent the memory leak.
+ *
+ * @param[in]  provider  The provider handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @see data_control_sql_create()
+ */
+int data_control_sql_destroy(data_control_h provider);
+
+/**
+ * @brief  Sets the Provider ID.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider     The provider handle
+ * @param[in]  provider_id  The data control provider ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see  data_control_sql_get_provider_id()
+ */
+int data_control_sql_set_provider_id(data_control_h provider, const char *provider_id);
+
+/**
+ * @brief  Gets the Provider ID.
+ * @since_tizen 2.3
+ *
+ * @remarks  You must release @a provider_id using free() after it is used.
+ *
+ * @param[in]   provider     The provider handle
+ * @param[out]  provider_id  The data control provider ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see  data_control_sql_set_provider_id()
+ */
+int data_control_sql_get_provider_id(data_control_h provider, char **provider_id);
+
+/**
+ * @brief  Sets the data ID.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider  The provider handle
+ * @param[in]  data_id   A string for identifying a specific table to operate \n
+ *                       The string consists of one or more components separated by a slash('/').
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ *
+ * @see  data_control_sql_get_data_id()
+ */
+int data_control_sql_set_data_id(data_control_h provider, const char *data_id);
+
+/**
+ * @brief  Gets the data ID.
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a data_id using free() after it is used.
+ *
+ * @param[in]   provider  The provider handle
+ * @param[out]  data_id   A string for identifying a specific table to operate \n
+ *                        The string consists of one or more components separated by a slash('/').
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE               Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY      Out of memory
+ *
+ * @see  data_control_sql_set_data_id()
+ */
+int data_control_sql_get_data_id(data_control_h provider, char **data_id);
+
+/**
+ * @brief  Registers a callback function for the SQL data control response.
+ * @since_tizen 2.3
+ *
+ * remarks The application is notified when a data control response is received from the @a provider.
+ *
+ * @param[in]  provider  The provider handle
+ * @param[in]  callback  The callback function to be called when a response is received
+ * @param[in]  user_data The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE          Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR      I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see  data_control_sql_unregister_response_cb()
+ */
+int data_control_sql_register_response_cb(data_control_h provider, data_control_sql_response_cb* callback, void *user_data);
+
+/**
+ * @brief  Unregisters the callback function in the @a provider.
+ * @since_tizen 2.3
+ *
+ * @param[in]  provider  The provider handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ */
+int data_control_sql_unregister_response_cb(data_control_h provider);
+
+/**
+ * @brief  Deletes rows of a table owned by the SQL-type data control provider.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks If the value is a string, then the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
+ * @remarks The following example demonstrates how to use the %data_control_sql_delete() method:
+ *
+ * @code
+ *
+ *  void sql_delete_response_cb(int request_id, data_control_h provider, bool provider_result, const char *error, void *user_data) {
+ *      if (provider_result) {
+ *          LOGI(The delete operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The delete operation for the request %d is failed. error message: %s", request_id, error);
+ *      }
+ *  }
+ *
+ *  data_control_sql_response_cb sql_callback;
+ *
+ *  int main()
+ *  {
+ *      const char *where = "group = 'friend'";
+ *      int result = 0;
+ *      int req_id = 0;
+ *
+ *      sql_callback.delete_cb = sql_delete_response_cb;
+ *      result = data_control_sql_register_response_cb(provider, &sql_callback, void *user_data);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_sql_delete(provider, where, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Deleting is failed with error: %d", result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+ *
+ * @param[in]   provider    The provider handle
+ * @param[in]   where       A filter to select the desired rows to delete \n
+ *                          It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param[out]  request_id  The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_sql_delete(data_control_h provider, const char *where, int *request_id);
+
+/**
+ * @brief  Inserts new rows in a table owned by the SQL-type data control provider.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks The following example demonstrates how to use the %data_control_sql_insert() method:
+ *
+ * @code
+ *
+ *  void sql_insert_response_cb(int request_id, data_control_h provider, long long inserted_row_id, bool provider_result, const char *error, void *user_data) {
+ *      if (provider_result) {
+ *          LOGI("The insert operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The insert operation for the request %d is failed. error message: %s", request_id, error);
+ *      }
+ *  }
+ *
+ *  data_control_sql_response_cb sql_callback;
+ *
+ *  int main()
+ *  {
+ *      int result = 0;
+ *      int req_id = 0;
+ *      bundle *b = NULL;
+ *
+ *      sql_callback.insert_cb = sql_insert_response_cb;
+ *      result = data_control_sql_register_response_cb(provider, &sql_callback, void *user_data);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      b = bundle_create();
+ *      bundle_add(b, "WORD", "test");
+ *      bundle_add(b, "WORD_DESC", "test description");
+ *
+ *      result = data_control_sql_insert(provider, b, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Inserting is failed with error: %d", result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      bundle_free(b);
+ *      return result;
+ *  }
+ *
+ * @endcode
+
+ * @param[in]   provider     The provider handle
+ * @param[in]   insert_data  The column-value pairs to insert\ n
+ *                           If the value is a string, then the value must be wrapped in single quotes,
+ *                           else it does not need to be wrapped in single quotes.
+ * @param[out]  request_id   The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_sql_insert(data_control_h provider, const bundle* insert_data, int *request_id);
+
+/**
+ * @brief  Selects the specified columns to be queried.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks The following example demonstrates how to use the %data_control_sql_select() method:
+ *
+ * @code
+ *
+ *  void sql_select_response_cb(int request_id, data_control_h provider, result_set_cursor *enumerator, bool provider_result, const char *error, void *user_data) {
+ *      if (provider_result) {
+ *          LOGI("The select operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The select operation for the request %d is failed. error message: %s", request_id, error);
+ *      }
+ *  }
+ *
+ *  data_control_sql_response_cb sql_callback;
+ *
+ *  int main()
+ *  {
+ *      int result = 0;
+ *      int req_id = 0;
+ *      char *column_list[2];
+ *      column_list[0] = "WORD";
+ *      column_list[1] = "WORD_DESC";
+ *      const char *where = "WORD = 'test'";
+ *      const char *order = "WORD ASC";
+ *
+ *      sql_callback.select_cb = sql_select_response_cb;
+ *      result = data_control_sql_register_response_cb(provider, &sql_callback, void *user_data);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      result = data_control_sql_select(provider, column_list, 2, where, order, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Selecting is failed with error: %d", result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      return result;
+ *  }
+ *
+ * @endcode
+
+
+ * @param[in]   provider      The provider handle
+ * @param[in]   column_list   The column list to query
+ * @param[in]   column_count  The total number of columns to be queried
+ * @param[in]   where         A filter to select the desired rows \n
+ *                            It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param[in]   order         The sorting order of the rows to query \n
+ *                            It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
+ * @param[out]  request_id    The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_sql_select(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id);
+
+/**
+ * @brief  Selects the specified columns to be queried.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks  If you want to use this api, you must add privileges.
+ *
+ * @param[in]   provider        The provider handle
+ * @param[in]   column_list     The column list to query
+ * @param[in]   column_count    The total number of columns to be queried
+ * @param[in]   where           A filter to select the desired rows \n
+ *                              It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param[in]   order           The sorting order of the rows to query \n
+ *                              It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
+ * @param[in]   page_number     The page number of the result set \n
+ *                              It starts from @c 1.
+ * @param[in]   count_per_page  The desired maximum count of rows on a page
+ * @param[out]  request_id      The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ * @see  data_control_sql_select()
+ */
+int data_control_sql_select_with_page(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id);
+
+/**
+ * @brief  Updates values of a table owned by the SQL-type data control provider.
+ * @since_tizen 2.3
+ * @privlevel   public
+ * @privilege   %http://tizen.org/privilege/datasharing \n
+ *              %http://tizen.org/privilege/appmanager.launch
+ *
+ * @remarks If you want to use this api, you must add privileges.
+ * @remarks The following example demonstrates how to use the %data_control_sql_update() method:
+ *
+ * @code
+ *
+ *  void sql_update_response_cb(int request_id, data_control_h provider, bool provider_result, const char *error, void *user_data) {
+ *      if (provider_result) {
+ *          LOGI("The update operation is successful");
+ *      }
+ *      else {
+ *          LOGI("The update operation for the request %d is failed. error message: %s", request_id, error);
+ *      }
+ *  }
+ *
+ *  data_control_sql_response_cb sql_callback;
+ *
+ *  int main()
+ *  {
+ *      int result = 0;
+ *      int req_id = 0;
+ *      const char *where = "WORD = 'test'";
+ *      bundle *b = NULL;
+ *
+ *      sql_callback.update_cb = sql_update_response_cb;
+ *      result = data_control_sql_register_response_cb(provider, &sql_callback, void *user_data);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Registering the callback function is failed with error: %d", result);
+ *          return result;
+ *      }
+ *
+ *      b = bundle_create();
+ *      bundle_add(b, "WORD", "test_new");
+ *
+ *      result = data_control_sql_update(provider, b, where, &req_id);
+ *      if (result != DATA_CONTROL_ERROR_NONE) {
+ *          LOGE("Updating is failed with error: %d", result);
+ *      }
+ *      else {
+ *          LOGI("req_id is %d", req_id);
+ *      }
+ *
+ *      bundle_free(b);
+ *      return result;
+ *  }
+ *
+ * @endcode
+ *
+ *
+ * @param[in]   provider     The provider handle
+ * @param[in]   update_data  The column-value pairs to update \n
+ *                           If the value is a string, the value must be wrapped in single quotes,
+ *                           else it does not need to be wrapped in single quotes.
+ * @param[in]   where        A filter to select the desired rows to update \n
+ *                           It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
+ * @param[out]  request_id   The request ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ * @retval #DATA_CONTROL_ERROR_PERMISSION_DENIED Permission denied
+ */
+int data_control_sql_update(data_control_h provider, const bundle* update_data, const char *where, int *request_id);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_APPFW__DATA_CONTROL_SQL_H__ */
diff --git a/include/data_control_sql_cursor.h b/include/data_control_sql_cursor.h
new file mode 100644 (file)
index 0000000..60175b6
--- /dev/null
@@ -0,0 +1,313 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_
+#define __TIZEN_APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_
+
+#include <stdio.h>
+#include "data_control_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file   data_control_sql_cursor.h
+ * @brief  This is the header file for the cursor of the SQL-friendly interface based data control.
+ */
+
+/**
+ * @addtogroup CAPI_DATA_CONTROL_CONSUMER_MODULE
+ * @{
+ */
+
+/**
+ * @brief   The structure type to represent a SQL result set.
+ * @details This type can be used to enumerate through the result set of an SQL query.
+ * @since_tizen 2.3
+ */
+typedef struct result_set_s *result_set_cursor;
+
+/**
+ * @brief  Moves the cursor to the first position.
+ * @since_tizen 2.3
+ *
+ * @remarks The following example demonstrates how to use the %data_control_sql_step_first() method:
+ *
+ * @code
+ *
+ *  void sql_select_response_cb(int request_id, data_control_h provider, result_set_cursor cursor, bool provider_result, const char *error)
+ *  {
+ *      char person_name[32] = {0,};
+ *      long long person_number = -1;
+ *
+ *      data_control_sql_step_first(cursor);
+ *      data_control_sql_get_text_data(cursor, 0, person_name);
+ *      data_control_sql_get_int64_data(cursor, 1, &person_number);
+ *      printf("The person %s has the number %l", person_name, person_number);
+ *  }
+ *
+ * @endcode
+
+ * @param[in]  cursor  The cursor that navigates the result of the request for the select operation
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE          Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR      I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_step_first(result_set_cursor cursor);
+
+/**
+ * @brief  Moves the cursor to the last position.
+ * @since_tizen 2.3
+ *
+ * @remarks The following example demonstrates how to use the %data_control_sql_step_last() method:
+ *
+ * @code
+ *
+ *  void sql_select_response_cb(int request_id, data_control_h provider, result_set_cursor cursor, bool provider_result, const char *error)
+ *  {
+ *      char person_name[32] = {0,};
+ *      long long person_number = -1;
+ *
+ *      data_control_sql_step_last(cursor);
+ *      data_control_sql_get_text_data(cursor, 0, person_name);
+ *      data_control_sql_get_int64_data(cursor, 1, &person_number);
+ *      printf("The person %s has the number %l", person_name, person_number);
+ *  }
+ *
+ * @endcode
+
+ * @param[in]  cursor  The cursor that navigates the result of data control select request
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE          Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR      I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_step_last(result_set_cursor cursor);
+
+/**
+ * @brief  Moves the cursor to the next position.
+ * @since_tizen 2.3
+ *
+ * @remarks The following example demonstrates how to use the %data_control_sql_step_next() method:
+ *
+ * @code
+ *
+ *  void sql_select_response_cb(int request_id, data_control_h provider, result_set_cursor cursor, bool provider_result, const char *error)
+ *  {
+ *      char person_name[32] = {0,};
+ *      long long person_number = -1;
+ *      while (data_control_sql_step_next(cursor) == DATA_CONTROL_ERROR_NONE) {
+ *          data_control_sql_get_text_data(cursor, 0, person_name);
+ *          data_control_sql_get_int64_data(cursor, 1, &person_number);
+ *          printf("The person %s has the number %l", person_name, person_number);
+ *      }
+ *  }
+ *
+ * @endcode
+ *
+ * @param[in]  cursor  The cursor that navigates the result of the request for the select operation
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE          Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR      I/O error
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_step_next(result_set_cursor cursor);
+
+/**
+ * @brief  Moves the cursor to the previous position.
+ * @since_tizen 2.3
+ *
+ * @param[in]  cursor  The cursor that navigates the result of the request for the select operation
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_step_previous(result_set_cursor cursor);
+
+/**
+ * @brief  Gets the number of columns for this cursor.
+ * @since_tizen 2.3
+ *
+ * @param[in]  cursor  The cursor that navigates the result of the request for the select operation
+ *
+ * @return  The number of columns in the calling cursor
+ */
+int data_control_sql_get_column_count(result_set_cursor cursor);
+
+/**
+ * @brief  Gets the name of the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]   cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]   column_index  The index of the destination column
+ * @param[out]  name          The name of the destination column. You should provide a buffer for the column name. The limit of column name length is 4096 bytes.
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE     Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_get_column_name(result_set_cursor cursor, int column_index, char *name);
+
+/**
+ * @brief  Gets the size of the data in the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]  cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]  column_index  The index of the destination column
+ *
+ * @return  The size of data in the column indicated by the specified index \n
+ *          If an error is occurred, then a negative value is returned.
+ *
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_get_column_item_size(result_set_cursor cursor, int column_index);
+
+/**
+ * @brief  Gets the type of the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]   cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]   column_index  The index of the destination column
+ * @param[out]  type          The type of the destination column
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE     Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_get_column_item_type(result_set_cursor cursor, int column_index, data_control_sql_column_type_e* type);
+
+/**
+ * @brief  Gets a blob data from the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]   cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]   column_index  The index of the destination column
+ * @param[out]  data          The blob value obtained from the column
+ * @param[out]  size          The size of the data
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_MAX_EXCEEDED      Too long argument
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_get_blob_data(result_set_cursor cursor, int column_index, void *data, int size);
+
+/**
+ * @brief  Gets an int value from the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]   cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]   column_index  The index of the destination column
+ * @param[out]  data          The integer value obtained from the column
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_get_int_data(result_set_cursor cursor, int column_index, int *data);
+
+/**
+ * @brief  Gets a long long value from the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]   cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]   column_index  The index of the destination column
+ * @param[out]  data          The 64-bit integer value obtained from the column
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_get_int64_data(result_set_cursor cursor, int column_index, long long *data);
+
+/**
+ * @brief  Gets a double value from the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]   cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]   column_index  The index of the destination column
+ * @param[out]  data          The value obtained from the column as double
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int data_control_sql_get_double_data(result_set_cursor cursor, int column_index, double *data);
+
+/**
+ * @brief  Gets a text value from the column indicated by the specified index.
+ * @since_tizen 2.3
+ *
+ * @param[in]   cursor        The cursor that navigates the result of the request for the select operation
+ * @param[in]   column_index  The index of the destination column
+ * @param[out]  data          The value obtained from the column as text. You should provide a buffer for the data. You can get the size of data via data_control_sql_get_column_item_size().
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval #DATA_CONTROL_ERROR_NONE              Successful
+ * @retval #DATA_CONTROL_ERROR_IO_ERROR          I/O error
+ * @retval #DATA_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DATA_CONTROL_ERROR_OUT_OF_MEMORY     Out of memory
+ */
+int data_control_sql_get_text_data(result_set_cursor cursor, int column_index, char *data);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_ */
+
diff --git a/include/data_control_types.h b/include/data_control_types.h
new file mode 100644 (file)
index 0000000..dbeed3a
--- /dev/null
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_APPFW__DATA_CONTROL_TYPES_H__
+#define __TIZEN_APPFW__DATA_CONTROL_TYPES_H__
+
+#include <tizen.h>
+
+/**
+ * @file    data_control_types.h
+ * @brief   This is the header file for data types of the data-control.
+ */
+
+/**
+ * @addtogroup CAPI_DATA_CONTROL_MODULE
+ * @{
+ */
+
+/**
+ * @brief The structure type for the provider handle.
+ * @since_tizen 2.3
+ */
+typedef struct data_control_s *data_control_h;
+
+/**
+ * @brief Enumeration for different types of columns in a SQL table.
+ * @since_tizen 2.3
+ */
+typedef enum
+{
+    DATA_CONTROL_SQL_COLUMN_TYPE_UNDEFINED = 0, /**< undefined type */
+    DATA_CONTROL_SQL_COLUMN_TYPE_INT64,         /**< integer type */
+    DATA_CONTROL_SQL_COLUMN_TYPE_DOUBLE,        /**< double type */
+    DATA_CONTROL_SQL_COLUMN_TYPE_TEXT,          /**< text type */
+    DATA_CONTROL_SQL_COLUMN_TYPE_BLOB,          /**< blob type */
+    DATA_CONTROL_SQL_COLUMN_TYPE_NULL           /**< null value */
+} data_control_sql_column_type_e;
+
+/**
+ * @brief Enumeration for the various error-codes an API can return.
+ * @since_tizen 2.3
+ */
+typedef enum
+{
+    DATA_CONTROL_ERROR_NONE = TIZEN_ERROR_NONE,                           /**< Successful */
+    DATA_CONTROL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY,         /**< Out of memory */
+    DATA_CONTROL_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR,                   /**< I/O error */
+    DATA_CONTROL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+    DATA_CONTROL_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+    DATA_CONTROL_ERROR_MAX_EXCEEDED  = TIZEN_ERROR_DATA_CONTROL | 0x01    /**< Too long argument */
+} data_control_error_e;
+
+/**
+* @}
+*/
+
+#endif /* __TIZEN_APPFW__DATA_CONTROL_TYPES_H__ */
+
diff --git a/packaging/data-control.spec b/packaging/data-control.spec
new file mode 100644 (file)
index 0000000..8721876
--- /dev/null
@@ -0,0 +1,69 @@
+Name:       data-control
+Summary:    Data Control library
+Version:    0.0.16
+Release:    1
+Group:      Application Framework/Libraries
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(bundle)
+BuildRequires:  pkgconfig(appsvc)
+BuildRequires:  pkgconfig(pkgmgr-info)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(capi-base-common)
+
+# runtime requires
+Requires(post): /sbin/ldconfig
+Requires(post): coreutils
+Requires(postun): /sbin/ldconfig
+
+Provides:   capi-data-control
+
+%description
+Data Control library
+
+%package devel
+Summary:  Data Control library (Development)
+Group:    Application Framework/Development
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Data Control library (DEV)
+
+
+%prep
+%setup -q
+
+%build
+
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+
+# Call make instruction with smp support
+%__make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+
+%make_install
+mkdir -p %{buildroot}/tmp/datacontrol/request
+mkdir -p %{buildroot}/tmp/datacontrol/result
+mkdir -p %{buildroot}/usr/share/license
+install LICENSE.APLv2  %{buildroot}/usr/share/license/%{name}
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%{_libdir}/lib%{name}.so.*
+%manifest %{name}.manifest
+/usr/share/license/%{name}
+
+%files devel
+%{_includedir}/appfw/*.h
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/lib%{name}.so
+
diff --git a/src/data-control-internal.c b/src/data-control-internal.c
new file mode 100644 (file)
index 0000000..aea4808
--- /dev/null
@@ -0,0 +1,60 @@
+#include <dlog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <pthread.h>
+
+#include <bundle.h>
+#include <pkgmgr-info.h>
+
+#include "data-control-sql-cursor.h"
+#include "data-control-internal.h"
+
+#define MAX_COLUMN_SIZE                                512
+#define MAX_STATEMENT_SIZE                     1024
+
+int
+_datacontrol_sql_get_cursor(const char *path)
+{
+
+       return 0;
+}
+
+char*
+_datacontrol_create_select_statement(char *data_id, const char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page)
+{
+       char *column = calloc(MAX_COLUMN_SIZE, sizeof(char));
+       int i = 0;
+
+       while (i < column_count - 1)
+       {
+               LOGI("column i = %d, %s", i, column_list[i]);
+               strcat(column, column_list[i]);
+               strcat(column, ", ");
+               i++;
+       }
+
+       LOGI("column i = %d, %s", i, column_list[i]);
+       strcat(column, column_list[i]);
+
+       char *statement = calloc(MAX_STATEMENT_SIZE, sizeof(char));
+       snprintf(statement, MAX_STATEMENT_SIZE, "SELECT %s * FROM %s WHERE %s ORDER BY %s", column, data_id, where, order);
+
+       LOGI("SQL statement: %s", statement);
+
+       free(column);
+       return statement;
+}
+
+int
+_datacontrol_create_request_id(void)
+{
+       static int id = 0;
+
+       g_atomic_int_inc(&id);
+
+       return id;
+}
diff --git a/src/data-control-internal.h b/src/data-control-internal.h
new file mode 100644 (file)
index 0000000..ddaad33
--- /dev/null
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file       data-control-internal.h
+ * @brief      This is the header file for private keys of the data-control.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_INTERNAL_H_
+#define _APPFW_DATA_CONTROL_INTERNAL_H_
+
+#undef LOG_TAG
+#ifndef LOG_TAG
+#define LOG_TAG "DATA_CONTROL"
+#endif
+
+#define MAX_LEN_DATACONTROL_REQ_TYPE  8
+#define MAX_LEN_DATACONTROL_COLUMN_COUNT  8
+
+#define OSP_K_LAUNCH_TYPE   "__OSP_LAUNCH_TYPE__"
+#define OSP_K_ARG           "__OSP_ARGS__"
+#define OSP_K_REQUEST_ID    "__OSP_REQUEST_ID__"
+#define OSP_K_DATACONTROL_PROVIDER             "__OSP_DATACONTROL_PROVIDER__"
+#define OSP_K_DATACONTROL_DATA                 "__OSP_DATACONTROL_DATA__"
+#define OSP_K_DATACONTROL_REQUEST_TYPE  "__OSP_DATACONTROL_REQUEST_TYPE__"
+#define OSP_K_DATACONTROL_PROTOCOL_VERSION     "__OSP_DATACONTROL_PROTOCOL_VERSION__"
+#define OSP_K_CALLER_TYPE   "__OSP_CALLER_TYPE__"
+
+#define DATACONTROL_SELECT_STATEMENT   "DATACONTROL_SELECT_STATEMENT"
+
+#define DATACONTROL_EMPTY              "NULL"
+#define DATACONTROL_SELECT_EXTRA_COUNT         6  // data id, column count, where, order, page, per_page
+
+
+
+#define OSP_V_LAUNCH_TYPE_DATACONTROL          "datacontrol"
+#define OSP_V_VERSION_2_1_0_3  "ver_2.1.0.3"
+#define OSP_V_CALLER_TYPE_OSP  "osp"
+
+#define DATACONTROL_REQUEST_FILE_PREFIX "/tmp/datacontrol/request"
+#define DATACONTROL_RESULT_FILE_PREFIX  "/tmp/datacontrol/result."
+
+
+/**
+ * @brief Enumerations of different type of data control requests.
+ */
+typedef enum
+{
+       DATACONTROL_TYPE_ERROR = -1,
+       DATACONTROL_TYPE_UNDEFINED,
+       DATACONTROL_TYPE_SQL_SELECT,
+       DATACONTROL_TYPE_SQL_INSERT,
+       DATACONTROL_TYPE_SQL_UPDATE,
+       DATACONTROL_TYPE_SQL_DELETE,
+       DATACONTROL_TYPE_MAP_GET,
+       DATACONTROL_TYPE_MAP_SET,
+       DATACONTROL_TYPE_MAP_ADD,
+       DATACONTROL_TYPE_MAP_REMOVE,
+       DATACONTROL_TYPE_MAX = 255
+} datacontrol_request_type;
+
+int
+datacontrol_sql_set_cursor(const char *path);
+
+char*
+_datacontrol_create_select_statement(char *data_id, const char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page);
+
+int
+_datacontrol_create_request_id(void);
+
+#endif /* _APPFW_DATA_CONTROL_INTERNAL_H_ */
+
diff --git a/src/data-control-map.c b/src/data-control-map.c
new file mode 100644 (file)
index 0000000..a22747c
--- /dev/null
@@ -0,0 +1,964 @@
+#include <dlog.h>
+#include <errno.h>
+#include <search.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <pthread.h>
+#include <fcntl.h>
+
+#include <appsvc/appsvc.h>
+#include <aul/aul.h>
+#include <bundle.h>
+#include <pkgmgr-info.h>
+
+#include "data-control-map.h"
+#include "data-control-internal.h"
+
+struct datacontrol_s {
+       char *provider_id;
+       char *data_id;
+};
+
+typedef struct
+{
+    char *provider_id;
+    char *app_id;
+    char *data_id;
+    char *access_info;
+    void *user_data;
+    datacontrol_map_response_cb *map_response_cb;
+} map_response_cb_s;
+
+static void *datacontrol_map_tree_root = NULL;
+static const int MAX_ARGUMENT_SIZE = 16384; // 16KB
+
+static void
+datacontrol_map_call_cb(const char *provider_id, int request_id, datacontrol_request_type type,
+       const char *data_id, bool provider_result, const char *error, char **result_value_list, int result_value_count, void* data)
+{
+       LOGI("datacontrol_map_call_cb, dataID: %s", data_id);
+
+       datacontrol_map_response_cb *callback = NULL;
+
+       map_response_cb_s *map_dc = NULL;
+       map_dc = (map_response_cb_s *)data;
+       callback = map_dc->map_response_cb;
+       if (!callback)
+       {
+               LOGE("no listener set");
+               return;
+       }
+
+       datacontrol_h provider;
+       datacontrol_map_create(&provider);
+
+       datacontrol_map_set_provider_id(provider, provider_id);
+       datacontrol_map_set_data_id(provider, data_id);
+
+       switch (type)
+       {
+               case DATACONTROL_TYPE_MAP_GET:
+               {
+                       LOGI("GET VALUE");
+                       if (callback != NULL && callback->get != NULL)
+                       {
+                               callback->get(request_id, provider, result_value_list, result_value_count, provider_result, error, map_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+
+                       break;
+               }
+               case DATACONTROL_TYPE_MAP_SET:
+               {
+                       LOGI("SET VALUE");
+                       if (callback != NULL && callback->set != NULL)
+                       {
+                               callback->set(request_id, provider, provider_result, error, map_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+
+                       break;
+               }
+               case DATACONTROL_TYPE_MAP_ADD:
+               {
+                       LOGI("ADD VALUE");
+                       if (callback != NULL && callback->add!= NULL)
+                       {
+                               callback->add(request_id, provider, provider_result, error, map_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+
+                       break;
+               }
+               case DATACONTROL_TYPE_MAP_REMOVE:
+               {
+                       LOGI("REMOVE VALUE");
+                       if (callback != NULL && callback->remove != NULL)
+                       {
+                               callback->remove(request_id, provider, provider_result, error, map_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+                       break;
+               }
+               default:
+                       break;
+       }
+
+       datacontrol_map_destroy(provider);
+}
+
+static void
+datacontrol_map_instance_free(void *datacontrol_map_instance)
+{
+       map_response_cb_s *dc = (map_response_cb_s *)datacontrol_map_instance;
+       if (dc)
+       {
+               free(dc->provider_id);
+               free(dc->data_id);
+               free(dc->app_id);
+               free(dc->access_info);
+               free(datacontrol_map_instance);
+       }
+
+       return;
+}
+
+static int
+datacontrol_map_instance_compare(const void *l_datacontrol_map_instance, const void *r_datacontrol_map_instance)
+{
+       map_response_cb_s *dc_left = (map_response_cb_s *)l_datacontrol_map_instance;
+       map_response_cb_s *dc_right = (map_response_cb_s *)r_datacontrol_map_instance;
+       return strcmp(dc_left->provider_id, dc_right->provider_id);
+}
+
+static char**
+datacontrol_map_get_value_list(const char *path, int count)
+{
+       char **value_list = NULL;
+       int i = 0;
+       int fd = 0;
+       int ret = 0;
+
+       value_list = (char **) calloc(count, sizeof(char *));
+       if (value_list == NULL)
+       {
+               LOGE("Failed to create value list");
+               return NULL;
+       }
+
+       SECURE_LOGI("The result file of GET: %s", path);
+       /* TODO - shoud be changed to solve security concerns */
+       fd = open(path, O_RDONLY, 644);
+       if (fd == -1)
+       {
+               SECURE_LOGE("unable to open update_map file: %d", errno);
+               goto ERROR;
+       }
+
+       while (count)
+       {
+               int length = 0;
+               int size = read(fd, &length, sizeof(int));
+               if (size <= 0)
+               {
+                       SECURE_LOGE("unable to read the result value file: %d", errno);
+                       goto ERROR;
+               }
+
+               value_list[i] = (char *) calloc(length + 1, sizeof(char));
+
+               size = read(fd, value_list[i], length);
+               if (size <= 0)
+               {
+                       SECURE_LOGE("unable to read the result value file: %d", errno);
+                       ++i;
+                       goto ERROR;
+               }
+
+               LOGI("value_list[%d] = %s", i, value_list[i]);
+               ++i;
+               --count;
+       }
+
+       close(fd);
+       ret = remove(path);
+       if (ret == -1)
+       {
+               SECURE_LOGE("unable to remove the result value file(%s). errno = %d", path, errno);
+       }
+
+       return value_list;
+
+ERROR:
+       if (value_list)
+       {
+               int j;
+               for (j = 0; j < i; j++)
+               {
+                       free(value_list[j]);
+               }
+               free(value_list);
+       }
+
+       close(fd);
+       ret = remove(path);
+       if (ret == -1)
+       {
+               SECURE_LOGE("unable to remove the result value file(%s). errno = %d", path, errno);
+       }
+       return NULL;
+}
+
+static int
+datacontrol_map_handle_cb(bundle* b, int request_code, appsvc_result_val res, void* data)
+{
+       LOGI("datacontrol_map_handle_cb, request_code: %d, result: %d", request_code, res);
+
+       int ret = 0;
+       const char** result_list = NULL;
+       const char* provider_id = NULL;
+       const char* data_id = NULL;
+       const char* error_message = NULL;
+       datacontrol_request_type request_type = 0;
+       int request_id = -1;
+       int result_list_len = 0;
+       int provider_result = 0;
+       int value_count = 0;
+       const char* result_path = NULL;
+       char** value_list = NULL;
+       const char* p = NULL;
+
+       if (!b)
+       {
+               LOGE("the bundle returned from datacontrol-provider-service is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       p = appsvc_get_data(b, OSP_K_REQUEST_ID);
+       if (!p)
+       {
+               LOGE("Invalid Bundle: request_id is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+       else
+       {
+               request_id = atoi(p);
+       }
+
+       SECURE_LOGI("Request ID: %d", request_id);
+
+       // result list
+       result_list = appsvc_get_data_array(b, OSP_K_ARG, &result_list_len);
+       if (!result_list)
+       {
+               LOGE("Invalid Bundle: arguement list is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       p = result_list[0]; // result list[0] = provider_result
+       if (!p)
+       {
+               LOGE("Invalid Bundle: provider_result is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGI("Provider result: %s", p);
+
+       provider_result = atoi(p);
+
+       error_message = result_list[1]; // result list[1] = error
+       if (!error_message)
+       {
+               LOGE("Invalid Bundle: error_message is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGI("Error message: %s", error_message);
+
+       p = appsvc_get_data(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+       if (!p)
+       {
+               LOGE("Invalid Bundle: data-control request type is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       request_type = (datacontrol_request_type)atoi(p);
+
+       provider_id = appsvc_get_data(b, OSP_K_DATACONTROL_PROVIDER);
+       if (!provider_id)
+       {
+               LOGE("Invalid Bundle: provider_id is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       data_id = appsvc_get_data(b, OSP_K_DATACONTROL_DATA);
+       if (!data_id)
+       {
+               LOGE("Invalid Bundle: data_id is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       SECURE_LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type);
+
+       switch (request_type)
+       {
+               case DATACONTROL_TYPE_MAP_GET:
+               {
+                       LOGI("GET RESPONSE");
+                       if (provider_result)
+                       {
+                               value_count = atoi(result_list[2]);
+                               result_path = result_list[3];
+                               if (!result_path)
+                               {
+                                       LOGE("map query result path is null");
+                                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+                               }
+                               value_list = datacontrol_map_get_value_list(result_path, value_count);
+                       }
+                       break;
+               }
+               case DATACONTROL_TYPE_MAP_SET:
+               case DATACONTROL_TYPE_MAP_ADD:
+               case DATACONTROL_TYPE_MAP_REMOVE:
+               {
+                       LOGI("SET or ADD or REMOVE RESPONSE");
+                       break;
+               }
+
+               default:
+                       break;
+       }
+
+       if (request_type >= DATACONTROL_TYPE_MAP_GET && request_type <= DATACONTROL_TYPE_MAP_REMOVE)
+       {
+               datacontrol_map_call_cb(provider_id, request_id, request_type, data_id, provider_result, error_message, value_list, value_count, data);
+               ret = DATACONTROL_ERROR_NONE;
+       }
+       else
+       {
+               ret = DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       return ret;
+}
+
+static void
+app_svc_res_cb_map(bundle* b, int request_code, appsvc_result_val res, void* data)
+{
+       LOGI("app_svc_res_cb_map, request_code: %d, result: %d", request_code, res);
+
+       if (data)
+       {
+               datacontrol_map_handle_cb(b, request_code, res, data);
+       }
+       else
+       {
+               LOGE("error: listener information is null");
+       }
+}
+
+
+static int
+datacontrol_map_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *arg_list, int request_id)
+{
+       SECURE_LOGI("Map Data control request, type: %d, request id: %d", type, request_id);
+
+       char *app_id = NULL;
+       void *data = NULL;
+
+       if (type < DATACONTROL_TYPE_MAP_GET || type > DATACONTROL_TYPE_MAP_REMOVE)
+       {
+               LOGE("Invalid request type: %d", (int)type);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!datacontrol_map_tree_root)
+       {
+               LOGE("The listener tree is empty");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(sizeof(map_response_cb_s),1);
+       if (!map_dc_temp)
+       {
+               LOGE("Failed to create map datacontrol");
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       map_dc_temp->provider_id = strdup(provider->provider_id);
+       if (!map_dc_temp->provider_id)
+       {
+               LOGE("Failed to assign provider id to map data control: %d", errno);
+               free(map_dc_temp);
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       map_dc_temp->data_id = strdup(provider->data_id);
+       if (!map_dc_temp->data_id)
+       {
+               LOGE("Failed to assign data id to map data control: %d", errno);
+               free(map_dc_temp->provider_id);
+               free(map_dc_temp);
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       map_dc_temp->app_id = NULL;
+       map_dc_temp->access_info = NULL;
+       map_dc_temp->user_data = NULL;
+       map_dc_temp->map_response_cb = NULL;
+
+       void *map_dc_returned = NULL;
+       map_dc_returned = tfind(map_dc_temp, &datacontrol_map_tree_root, datacontrol_map_instance_compare);
+
+       datacontrol_map_instance_free(map_dc_temp);
+
+       if (!map_dc_returned)
+       {
+               LOGE("Finding the map datacontrol in the listener tree is failed.");
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       map_response_cb_s *map_dc = *(map_response_cb_s **)map_dc_returned;
+       app_id = map_dc->app_id;
+       data = map_dc;
+
+       SECURE_LOGI("Map datacontrol appid: %s", map_dc->app_id);
+
+       char caller_app_id[255];
+       pid_t pid = getpid();
+       if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0)
+       {
+               SECURE_LOGE("Failed to get appid by pid(%d).", pid);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT);
+       appsvc_set_appid(arg_list, app_id);
+       bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP);
+       bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
+       bundle_add_str(arg_list, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
+       bundle_add_str(arg_list, AUL_K_CALLER_APPID, caller_app_id);
+       bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1");
+
+       char datacontrol_request_operation[MAX_LEN_DATACONTROL_REQ_TYPE] = {0, };
+       snprintf(datacontrol_request_operation, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(type));
+       bundle_add_str(arg_list, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation);
+
+       char req_id[32] = {0, };
+       snprintf(req_id, 32, "%d", request_id);
+       bundle_add_str(arg_list, OSP_K_REQUEST_ID, req_id);
+
+       // For DataControl CAPI
+       bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE");
+
+       SECURE_LOGI("Map data control request - provider id: %s, data id: %s, provider appid: %s, request ID: %s", provider->provider_id, provider->data_id, app_id, req_id);
+
+       pid = -1;
+       int count = 0;
+       const int TRY_COUNT = 4;
+       const int TRY_SLEEP_TIME = 65000;
+       do
+       {
+               pid = appsvc_run_service(arg_list, request_id, app_svc_res_cb_map, data);
+               if (pid >= 0)
+               {
+                       SECURE_LOGI("Launch the provider app successfully: %d", pid);
+                       return DATACONTROL_ERROR_NONE;
+               }
+               else if (pid == APPSVC_RET_EINVAL)
+               {
+                       SECURE_LOGE("not able to launch service: %d", pid);
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               count++;
+
+               usleep(TRY_SLEEP_TIME);
+       }
+       while (count < TRY_COUNT);
+
+       SECURE_LOGE("unable to launch service: %d", pid);
+       return DATACONTROL_ERROR_IO_ERROR;
+}
+
+int
+datacontrol_map_create(datacontrol_h *provider)
+{
+       struct datacontrol_s *request;
+
+       if (provider == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       request = malloc(sizeof(struct datacontrol_s));
+       if (request == NULL)
+       {
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       request->provider_id = NULL;
+       request->data_id = NULL;
+
+       *provider = request;
+
+       return 0;
+}
+
+int
+datacontrol_map_destroy(datacontrol_h provider)
+{
+       if (provider == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->provider_id != NULL)
+       {
+               free(provider->provider_id);
+       }
+
+       if (provider->data_id != NULL)
+       {
+               free(provider->data_id);
+       }
+
+       free(provider);
+
+       return 0;
+}
+
+int
+datacontrol_map_set_provider_id(datacontrol_h provider, const char *provider_id)
+{
+       if (provider == NULL || provider_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->provider_id != NULL)
+       {
+               free(provider->provider_id);
+       }
+
+       provider->provider_id = strdup(provider_id);
+       if (provider->provider_id == NULL)
+       {
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       return 0;
+}
+
+int
+datacontrol_map_get_provider_id(datacontrol_h provider, char **provider_id)
+{
+       if (provider == NULL || provider_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->provider_id != NULL)
+       {
+               *provider_id = strdup(provider->provider_id);
+               if (*provider_id == NULL)
+               {
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+       }
+       else
+       {
+               *provider_id = NULL;
+       }
+
+       return 0;
+}
+
+int
+datacontrol_map_set_data_id(datacontrol_h provider, const char *data_id)
+{
+       if (provider == NULL || data_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->data_id != NULL)
+       {
+               free(provider->data_id);
+       }
+
+       provider->data_id = strdup(data_id);
+       if (provider->data_id == NULL)
+       {
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       return 0;
+}
+
+int
+datacontrol_map_get_data_id(datacontrol_h provider, char **data_id)
+{
+       if (provider == NULL || data_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->data_id != NULL)
+       {
+               *data_id = strdup(provider->data_id);
+               if (*data_id == NULL)
+               {
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+       }
+       else
+       {
+               *data_id = NULL;
+       }
+       return 0;
+}
+
+int
+datacontrol_map_register_response_cb(datacontrol_h provider, datacontrol_map_response_cb* callback, void *user_data)
+{
+       int ret = 0;
+       char* app_id = NULL;
+       char* access = NULL;
+
+       ret = pkgmgrinfo_appinfo_get_datacontrol_info(provider->provider_id, "Map", &app_id, &access);
+       if (ret != PMINFO_R_OK)
+       {
+               LOGE("unable to get map data control information: %d", ret);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       SECURE_LOGI("data control provider appid = %s", app_id);
+
+       map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(sizeof(map_response_cb_s), 1);
+       if (!map_dc_temp)
+       {
+               LOGE("unable to create a temporary map data control");
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       map_dc_temp->provider_id = strdup(provider->provider_id);
+       if (!map_dc_temp->provider_id)
+       {
+               LOGE("unable to assign provider_id to map data control: %d", errno);
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       map_dc_temp->data_id = strdup(provider->data_id);
+       if (!map_dc_temp->data_id)
+       {
+               LOGE("unable to assign data_id to map data control: %d", errno);
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       map_dc_temp->app_id = app_id;
+       map_dc_temp->access_info = access;
+       map_dc_temp->user_data = user_data;
+       map_dc_temp->map_response_cb = callback;
+
+       void *map_dc_returned = NULL;
+       map_dc_returned = tsearch(map_dc_temp, &datacontrol_map_tree_root, datacontrol_map_instance_compare);
+
+       map_response_cb_s *map_dc = *(map_response_cb_s **)map_dc_returned;
+       if (map_dc != map_dc_temp)
+       {
+               map_dc->map_response_cb = callback;
+               map_dc->user_data = user_data;
+               LOGI("the data control is already set");
+               datacontrol_map_instance_free(map_dc_temp);
+       }
+
+       return DATACONTROL_ERROR_NONE;
+
+EXCEPTION:
+       if (access)
+               free(access);
+       if (app_id)
+               free(app_id);
+       if (map_dc_temp)
+       {
+               if (map_dc_temp->provider_id)
+                       free(map_dc_temp->provider_id);
+               if (map_dc_temp->data_id)
+                       free(map_dc_temp->data_id);
+               free(map_dc_temp);
+       }
+
+       return ret;
+}
+
+int
+datacontrol_map_unregister_response_cb(datacontrol_h provider)
+{
+       int ret = DATACONTROL_ERROR_NONE;
+       map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(sizeof(map_response_cb_s),1);
+
+
+       if (!map_dc_temp)
+       {
+               LOGE("unable to create a temporary map data control");
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       map_dc_temp->provider_id = strdup(provider->provider_id);
+       if (!map_dc_temp->provider_id)
+       {
+               LOGE("unable to assign provider_id to map data control: %d", errno);
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       void *map_dc_returned = NULL;
+
+       map_dc_returned = tdelete(map_dc_temp, &datacontrol_map_tree_root, datacontrol_map_instance_compare);
+       if (map_dc_returned == NULL)
+       {
+               LOGE("invalid parameter");
+               ret = DATACONTROL_ERROR_INVALID_PARAMETER;
+               goto EXCEPTION;
+       }
+
+
+EXCEPTION:
+        if (map_dc_temp)
+        {
+               if (map_dc_temp->provider_id)
+                       free(map_dc_temp->provider_id);
+               free(map_dc_temp);
+        }
+
+        return ret;
+}
+
+int
+datacontrol_map_get(datacontrol_h provider, const char *key, int *request_id)
+{
+       return datacontrol_map_get_with_page(provider, key, request_id, 1, 20);
+}
+
+int
+datacontrol_map_get_with_page(datacontrol_h provider, const char *key, int *request_id, int page_number, int count_per_page)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       SECURE_LOGI("Gets the value list from provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
+
+       long long arg_size = (strlen(provider->data_id) + strlen(key)) * sizeof(wchar_t);
+       if (arg_size > MAX_ARGUMENT_SIZE)
+       {
+               LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size);
+               return DATACONTROL_ERROR_MAX_EXCEEDED;
+       }
+
+       int ret = 0;
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       const char* arg_list[4];
+       arg_list[0] = provider->data_id;
+       arg_list[1] = key;
+
+       char page_no_str[32] = {0, };
+       ret = snprintf(page_no_str, 32, "%d", page_number);
+       if (ret < 0)
+       {
+               LOGE("unable to convert page no to string: %d", errno);
+               bundle_free(b);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       char count_per_page_str[32] = {0, };
+       ret = snprintf(count_per_page_str, 32, "%d", count_per_page);
+       if (ret < 0)
+       {
+               LOGE("unable to convert count per page no to string: %d", errno);
+               bundle_free(b);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       arg_list[2] = page_no_str;
+       arg_list[3] = count_per_page_str;
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, 4);
+
+       // Set the request id
+       int reqId = _datacontrol_create_request_id();
+       *request_id = reqId;
+
+       ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_GET, b, reqId);
+       bundle_free(b);
+
+       return ret;
+}
+
+int
+datacontrol_map_set(datacontrol_h provider, const char *key, const char *old_value, const char *new_value, int *request_id)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || old_value == NULL || new_value == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       SECURE_LOGI("Sets the old value to new value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
+
+       long long arg_size = (strlen(provider->data_id) + strlen(key) + strlen(old_value) + strlen(new_value)) * sizeof(wchar_t);
+       if (arg_size > MAX_ARGUMENT_SIZE)
+       {
+               LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size);
+               return DATACONTROL_ERROR_MAX_EXCEEDED;
+       }
+
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       const char* arg_list[4];
+       arg_list[0] = provider->data_id;
+       arg_list[1] = key;
+       arg_list[2] = old_value;
+       arg_list[3] = new_value;
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, 4);
+
+       // Set the request id
+       int reqId = _datacontrol_create_request_id();
+       *request_id = reqId;
+
+       int ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_SET, b, reqId);
+       bundle_free(b);
+
+       return ret;
+}
+
+int
+datacontrol_map_add(datacontrol_h provider, const char *key, const char *value, int *request_id)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       SECURE_LOGI("Adds the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
+
+       long long arg_size = (strlen(provider->data_id) + strlen(key) + strlen(value)) * sizeof(wchar_t);
+       if (arg_size > MAX_ARGUMENT_SIZE)
+       {
+               LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size);
+               return DATACONTROL_ERROR_MAX_EXCEEDED;
+       }
+
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       const char* arg_list[3];
+       arg_list[0] = provider->data_id;
+       arg_list[1] = key;
+       arg_list[2] = value;
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, 3);
+
+       // Set the request id
+       int reqId = _datacontrol_create_request_id();
+       *request_id = reqId;
+
+       int ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_ADD, b, reqId);
+       bundle_free(b);
+
+       return ret;
+}
+
+int
+datacontrol_map_remove(datacontrol_h provider, const char *key, const char *value, int *request_id)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       SECURE_LOGI("Removes the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
+
+       long long arg_size = (strlen(provider->data_id) + strlen(key) + strlen(value)) * sizeof(wchar_t);
+       if (arg_size > MAX_ARGUMENT_SIZE)
+       {
+               LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size);
+               return DATACONTROL_ERROR_MAX_EXCEEDED;
+       }
+
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       const char* arg_list[3];
+       arg_list[0] = provider->data_id;
+       arg_list[1] = key;
+       arg_list[2] = value;
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, 3);
+
+       // Set the request id
+       int reqId = _datacontrol_create_request_id();
+       *request_id = reqId;
+
+       int ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_REMOVE, b, reqId);
+       bundle_free(b);
+
+       return ret;
+}
diff --git a/src/data-control-provider.c b/src/data-control-provider.c
new file mode 100644 (file)
index 0000000..35376d6
--- /dev/null
@@ -0,0 +1,1145 @@
+#include <dlog.h>
+#include <errno.h>
+#include <search.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <pthread.h>
+#include <sqlite3.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <appsvc/appsvc.h>
+#include <aul/aul.h>
+#include <bundle.h>
+#include <pkgmgr-info.h>
+
+#include "data-control-sql.h"
+#include "data-control-provider.h"
+#include "data-control-internal.h"
+
+#define ROW_ID_SIZE                            32
+#define RESULT_PATH_MAX                512
+
+#define RESULT_PAGE_NUMBER             "RESULT_PAGE_NUMBER"
+#define MAX_COUNT_PER_PAGE             "MAX_COUNT_PER_PAGE"
+#define RESULT_VALUE_COUNT                     "RESULT_VALUE_COUNT"
+
+#define PACKET_INDEX_REQUEST_RESULT    0
+#define PACKET_INDEX_ERROR_MSG         1
+#define PACKET_INDEX_SELECT_RESULT_FILE        2
+#define PACKET_INDEX_ROW_ID                    2
+#define PACKET_INDEX_VALUE_COUNT               2
+#define PACKET_INDEX_GET_RESULT_FILE   3
+
+#define PACKET_INDEX_DATAID    0
+#define PACKET_INDEX_COLUMNCOUNT       1
+#define PACKET_INDEX_MAP       2
+
+#define PACKET_INDEX_UPDATEWHERE       3
+#define PACKET_INDEX_DELETEWHERE       1
+
+#define PACKET_INDEX_MAP_KEY   1
+#define PACKET_INDEX_MAP_VALUE_1ST     2
+#define PACKET_INDEX_MAP_VALUE_2ND     3
+#define PACKET_INDEX_MAP_PAGE_NO       2
+#define PACKET_INDEX_MAP_COUNT_PER_PAGE        3
+
+static GHashTable *request_table = NULL;
+
+//static pthread_mutex_t provider_lock = PTHREAD_MUTEX_INITIALIZER;
+
+struct datacontrol_s {
+       char *provider_id;
+       char *data_id;
+};
+
+
+typedef int (*provider_handler_cb) (bundle * b, int request_id, void *data);
+
+static datacontrol_provider_sql_cb* provider_sql_cb = NULL;
+static datacontrol_provider_map_cb* provider_map_cb = NULL;
+static void* provider_map_user_data = NULL;
+static void* provider_sql_user_data = NULL;
+
+static void
+__free_data(gpointer data)
+{
+       if (data)
+       {
+               free(data);
+               data = NULL;
+       }
+}
+
+static void
+__initialize_provider(void)
+{
+       request_table = g_hash_table_new_full(g_int_hash, g_int_equal, __free_data, __free_data);
+}
+
+static int
+__provider_new_request_id(void)
+{
+       static int id = 0;
+
+       g_atomic_int_inc(&id);
+
+       return id;
+}
+
+static char*
+__get_client_pkgid(bundle *b)
+{
+       const char *caller_appid = NULL;
+       char *caller_pkgid = NULL;
+       pkgmgrinfo_appinfo_h app_info_handle = NULL;
+
+       caller_appid = bundle_get_val(b, AUL_K_CALLER_APPID);
+       pkgmgrinfo_appinfo_get_appinfo(caller_appid, &app_info_handle);
+       pkgmgrinfo_appinfo_get_pkgname(app_info_handle, &caller_pkgid);
+       SECURE_LOGI("client pkg id : %s", caller_pkgid);
+
+       return caller_pkgid ? strdup(caller_pkgid) : NULL;
+}
+
+static bundle*
+__get_data_sql(const char *path, int column_count)
+{
+       bundle* b = bundle_create();
+
+       int len = 0;
+       int i = 0;
+       size_t size = 0;
+       char *key = NULL;
+       char *value = NULL;
+       int fd = 0;
+       int ret = 0;
+
+       SECURE_LOGI("The request file of INSERT/UPDATE: %s", path);
+
+       /* TODO - shoud be changed to solve security concerns */
+       fd = open(path, O_RDONLY, 644);
+       if (fd == -1) {
+               SECURE_LOGE("unable to open insert_map file: %d", errno);
+               return b;
+       }
+
+       for (i = 0; i < column_count; i++)
+       {
+               size = read(fd, &len, sizeof(int));
+               if (size < sizeof(int) || len < 0 || len == INT_MAX)
+               {
+                       SECURE_LOGE("key length:%d, read():%s, returned:%d", len, strerror(errno), size);
+                       break;
+               }
+
+               key = calloc(len + 1, sizeof(char));
+               size = read(fd, key, len);      // key
+               if (size < 0)
+               {
+                       SECURE_LOGE("key length:%d, read():%s, returned:%d", len, strerror(errno), size);
+                       free(key);
+                       break;
+               }
+
+               size = read(fd, &len, sizeof(int));
+               if (size < sizeof(int) || len < 0 || len == INT_MAX)
+               {
+                       SECURE_LOGE("value length:%d, read():%s, returned:%d", len, strerror(errno), size);
+                       free(key);
+                       break;
+               }
+
+               value = calloc(len + 1, sizeof(char));
+               size = read(fd, value, len); // value
+               if (size < 0)
+               {
+                       SECURE_LOGE("value length:%d, read():%s, returned:%d", len, strerror(errno), size);
+                       free(key);
+                       free(value);
+                       break;
+               }
+
+               LOGI("key: %s, value: %s", key, value);
+
+               bundle_add_str(b, key, value);
+
+               free(key);
+               free(value);
+       }
+
+       fsync(fd);
+       close(fd);
+       ret = remove(path);
+       if (ret == -1)
+       {
+               SECURE_LOGE("unable to remove the request file of INSERT/UPDATE(%s). errno = %d", path, errno);
+       }
+
+       return b;
+}
+
+static int
+__set_select_result(bundle* b, const char* path, void* data)
+{
+       LOGI("__set_select_result");
+       // The provider application should call the sqlite3_open().
+       // and it also should call the sqlite3_prepare_v2() in datacontrol_provider_sql_select_request_cb().
+       // and then, it should call the datacontrol_provider_send_select_result() with a pointer to sqlite3_stmt.
+       // The 3rd param 'data' is the pointer to sqlite3_stmt.
+
+       // In this function, the result set is written in specified file path as specific form.
+       // [sizeof(int)] row count
+       // [sizeof(int)] column count
+       // [sieeof(int)] total size of column names
+       // [sizeof(int)] column type x N
+       // [  variant  ] column name x N
+       // [sizeof(int)] type
+       // [sizeof(int)] size
+       // [  varient  ] content
+
+       int column_count = 0;
+       int i = 0;
+       char *column_name = NULL;
+       int total_len_of_column_names = 0;
+       int count_per_page = 0;
+       int row_count = 0;
+       sqlite3_stmt *state = (sqlite3_stmt *)data;
+       int fd = 0;
+       char *client_pkgid = NULL;
+
+       if (b ==NULL || path == NULL || data == NULL)
+       {
+               LOGE("The input param is invalid.");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (sqlite3_reset(state) != SQLITE_OK)
+       {
+               LOGE("sqlite3_reset() is failed.");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (sqlite3_step(state) != SQLITE_ROW)
+       {
+               LOGE("The DB does not have another row.");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       client_pkgid = __get_client_pkgid(b);
+
+       /* TODO - shoud be changed to solve security concerns */
+       fd = open(path, O_WRONLY | O_CREAT, 644);
+       if (fd == -1) {
+               SECURE_LOGE("unable to open insert_map file: %d", errno);
+               free(client_pkgid);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+       free(client_pkgid);
+
+       // 1. column count
+       column_count = sqlite3_column_count(state);
+       if (lseek(fd, sizeof(int), SEEK_SET) == -1)
+       {
+               LOGE("lseek is failed. errno =  %d", errno);
+       }
+       if (write(fd, &column_count, sizeof(int)) == -1)
+       {
+               LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno);
+       }
+
+       // 2. column type x column_count
+       // #define SQLITE_INTEGER       1
+       // #define SQLITE_FLOAT 2
+       // #define SQLITE_TEXT  3
+       // #define SQLITE_BLOB  4
+       // #define SQLITE_NULL  5
+       if (lseek(fd, sizeof(int), SEEK_CUR) == -1)
+       {
+               LOGE("lseek is failed. errno =  %d", errno);
+       }
+
+       for (i = 0; i < column_count; ++i)
+       {
+               int type = sqlite3_column_type(state, i);
+               if (write(fd, &type, sizeof(int)) == -1)
+               {
+                       LOGE("Writing a type to a file descriptor is failed. errno = %d", errno);
+               }
+       }
+
+       // 3. column name x column_count
+       for (i = 0; i < column_count; i++)
+       {
+               column_name = (char *)sqlite3_column_name(state, i);
+               column_name = strcat(column_name, "\n");
+               if (write(fd, column_name, strlen(column_name)) == -1)
+               {
+                       LOGE("Writing a column_name to a file descriptor is failed. errno = %d", errno);
+               }
+               total_len_of_column_names += strlen(column_name);
+       }
+
+       // 4. total length of column names
+       if (lseek(fd, sizeof(int) * 2, SEEK_SET) == -1)
+       {
+               LOGE("lseek is failed. errno =  %d", errno);
+       }
+       if (write(fd, &total_len_of_column_names, sizeof(int)) == -1)
+       {
+               LOGE("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno);
+       }
+       // 5. type, size and value of each element
+       if (lseek(fd, (sizeof(int) * column_count) + total_len_of_column_names, SEEK_CUR) == -1)
+       {
+               LOGE("lseek is failed. errno =  %d", errno);
+       }
+       count_per_page = atoi(bundle_get_val(b, MAX_COUNT_PER_PAGE));
+       do
+       {
+               for (i = 0; i < column_count; ++i)
+               {
+                       int type = 0;
+                       int size = 0;
+                       void* value = NULL;
+                       bool is_null_type = false;
+                       int column_type = sqlite3_column_type(state, i);
+                       long long tmp_long = 0;
+                       double tmp_double = 0.0;
+                       switch (column_type)
+                       {
+                               case SQLITE_INTEGER:
+                               {
+                                       type = 1;
+                                       size = sizeof(long long);
+                                       tmp_long = sqlite3_column_int64(state, i);
+                                       value = &tmp_long;
+                                       break;
+                               }
+                               case SQLITE_FLOAT:
+                               {
+                                       type = 2;
+                                       size = sizeof(double);
+                                       tmp_double = sqlite3_column_double(state, i);
+                                       value =&tmp_double;
+                                       break;
+                               }
+                               case SQLITE_TEXT:
+                               {
+                                       type = 3;
+                                       value = (char *)sqlite3_column_text(state, i);
+                                       size = strlen(value);
+                                       break;
+                               }
+                               case SQLITE_BLOB:
+                               {
+                                       type = 4;
+                                       size = sqlite3_column_bytes(state, i);
+                                       value = (char *)sqlite3_column_blob(state, i);
+                                       break;
+                               }
+                               case SQLITE_NULL:
+                               {
+                                       type = 5;
+                                       size = 0;
+                                       is_null_type = true;
+                                       break;
+                               }
+                               default:
+                               {
+                                       LOGE("The column type is invalid.");
+                                       break;
+                               }
+                       }
+
+                       if (write(fd, &type, sizeof(int)) == -1)
+                       {
+                               LOGE("Writing a type to a file descriptor is failed. errno = %d", errno);
+                       }
+                       if (write(fd, &size, sizeof(int)) == -1)
+                       {
+                               LOGE("Writing a size to a file descriptor is failed. errno = %d", errno);
+                       }
+                       if (size > 0 && !is_null_type)
+                       {
+                               if (write(fd, value, size) == -1)
+                               {
+                                       LOGE("Writing a value to a file descriptor is failed. errno = %d", errno);
+                               }
+                       }
+               }
+               ++row_count;
+       } while(sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page);
+
+       // 6. row count
+       if (lseek(fd, 0, SEEK_SET) == -1)
+       {
+               LOGE("lseek is failed. errno =  %d", errno);
+       }
+       if (write(fd, &row_count, sizeof(int)) == -1)
+       {
+               LOGE("Writing a row_count to a file descriptor is failed. errno = %d", errno);
+       }
+       close(fd);
+
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+static int
+__set_get_value_result(bundle *b, const char* path, char **value_list)
+{
+       int i = 0;
+       int fd = -1;
+       char *client_pkgid = NULL;
+
+       if (b == NULL || path == NULL || value_list == NULL)
+       {
+               LOGE("The input param is invalid.");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       int page_number = atoi(bundle_get_val(b, RESULT_PAGE_NUMBER));
+       int count_per_page = atoi(bundle_get_val(b, MAX_COUNT_PER_PAGE));
+       int value_count = atoi(bundle_get_val(b, RESULT_VALUE_COUNT));
+       int current_offset = (page_number - 1) * count_per_page;
+       int remain_count = value_count - current_offset;
+       remain_count = (remain_count > 0) ? remain_count : 0;   // round off to zero if the negative num is found
+       int add_value_count = (count_per_page > remain_count) ? remain_count : count_per_page;
+
+       if (add_value_count < value_count)
+       {
+               bundle_del(b, RESULT_VALUE_COUNT);
+               char value_count_str[32] = {0,};
+               snprintf(value_count_str, 32, "%d", add_value_count);
+               bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str);
+       }
+
+       if (add_value_count <= 0)
+       {
+               LOGI("There is no value list.");
+               return DATACONTROL_ERROR_NONE;
+       }
+
+       client_pkgid = __get_client_pkgid(b);
+       /* TODO - shoud be changed to solve security concerns */
+       fd = open(path, O_WRONLY | O_CREAT, 644);
+       if (fd == -1) {
+               SECURE_LOGE("unable to open insert_map file: %d", errno);
+               free(client_pkgid);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+       free(client_pkgid);
+
+       for (i = 0; i < add_value_count; ++i)
+       {
+               int length = strlen(value_list[current_offset + i]);
+               if (write(fd, &length, sizeof(int)) == -1)
+               {
+                       LOGE("Writing a length to a file descriptor is failed. errno = %d", errno);
+               }
+               if (write(fd, value_list[current_offset + i], length) == -1)
+               {
+                       LOGE("Writing a value_list to a file descriptor is failed. errno = %d", errno);
+               }
+       }
+
+       fsync(fd);
+       close(fd);
+       return DATACONTROL_ERROR_NONE;
+}
+
+static char*
+__get_result_file_path(bundle *b)
+{
+       LOGI("__get_result_file_path");
+       const char *caller = bundle_get_val(b, AUL_K_CALLER_APPID);
+       if (!caller)
+       {
+               LOGE("caller appid is NULL.");
+               return NULL;
+       }
+
+       const char *caller_req_id = bundle_get_val(b, OSP_K_REQUEST_ID);
+
+       char *result_path = calloc(RESULT_PATH_MAX, sizeof(char));
+       snprintf(result_path, RESULT_PATH_MAX, "%s/%s_%s", DATACONTROL_RESULT_FILE_PREFIX, caller, caller_req_id);
+
+       SECURE_LOGI("result file path: %s", result_path);
+
+       return result_path;
+}
+
+static bundle*
+__set_result(bundle* b, datacontrol_request_type type, void* data)
+{
+       bundle* res;
+       aul_create_result_bundle(b, &res);
+
+       // Set the type
+       char type_str[MAX_LEN_DATACONTROL_REQ_TYPE] = {0,};
+       if (type == DATACONTROL_TYPE_UNDEFINED || type == DATACONTROL_TYPE_ERROR)
+       {
+               char *request_type = (char*)bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+               strncpy(type_str, request_type, MAX_LEN_DATACONTROL_REQ_TYPE);
+               LOGI("type is %s", type_str);
+       }
+       else
+       {
+               snprintf(type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)type);
+       }
+       bundle_add_str(res, OSP_K_DATACONTROL_REQUEST_TYPE, type_str);
+
+       // Set the provider id
+       char *provider_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+       bundle_add_str(res, OSP_K_DATACONTROL_PROVIDER, provider_id);
+
+       // Set the data id
+       char *data_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_DATA);
+       bundle_add_str(res, OSP_K_DATACONTROL_DATA, data_id);
+
+       // Set the caller request id
+       char *request_id = (char*)bundle_get_val(b, OSP_K_REQUEST_ID);
+       bundle_add_str(res, OSP_K_REQUEST_ID, request_id);
+
+       switch(type)
+       {
+               case DATACONTROL_TYPE_SQL_SELECT:
+               {
+                       const char* list[3];
+
+                       list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
+                       list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+                       char *path = __get_result_file_path(b);
+                       if (path != NULL)
+                       {
+                               int ret = __set_select_result(b, path, data);
+                               if (ret < 0)
+                               {
+                                       memset(path, 0, RESULT_PATH_MAX);
+                                       strcpy(path, "NoResultSet");
+                                       LOGI("Empty ResultSet");
+                               }
+                               list[PACKET_INDEX_SELECT_RESULT_FILE] = path;
+                       }
+                       else
+                       {
+                               list[PACKET_INDEX_SELECT_RESULT_FILE] = DATACONTROL_EMPTY;
+                       }
+
+                       bundle_add_str_array(res, OSP_K_ARG, list, 3);
+
+                       if (path != NULL)
+                       {
+                               free(path);
+                       }
+
+                       break;
+               }
+
+               case DATACONTROL_TYPE_SQL_INSERT:
+               {
+                       long long row_id = *(long long*)data;
+
+                       const char* list[3];
+                       list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
+                       list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+                       // Set the row value
+                       char row_str[ROW_ID_SIZE] = {0,};
+                       snprintf(row_str, ROW_ID_SIZE, "%lld", row_id);
+
+                       list[PACKET_INDEX_ROW_ID] = row_str;
+
+                       bundle_add_str_array(res, OSP_K_ARG, list, 3);
+                       break;
+               }
+               case DATACONTROL_TYPE_SQL_UPDATE:
+               case DATACONTROL_TYPE_SQL_DELETE:
+               {
+                       const char* list[2];
+                       list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
+                       list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+                       bundle_add_str_array(res, OSP_K_ARG, list, 2);
+                       break;
+               }
+               case DATACONTROL_TYPE_MAP_GET:
+               {
+                       const char* list[4];
+
+                       list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
+                       list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+                       char *path = __get_result_file_path(b);
+                       if (path != NULL)
+                       {
+                               char **value_list = (char **)data;
+                               __set_get_value_result(b, path, value_list);
+                               list[PACKET_INDEX_VALUE_COUNT] = bundle_get_val(b, RESULT_VALUE_COUNT); // value count
+                               list[PACKET_INDEX_GET_RESULT_FILE] = path;
+                       }
+                       else
+                       {
+                               list[PACKET_INDEX_VALUE_COUNT] = 0;     // value count
+                               list[PACKET_INDEX_GET_RESULT_FILE] = DATACONTROL_EMPTY;
+                       }
+
+                       bundle_add_str_array(res, OSP_K_ARG, list, 4);
+
+                       if (path != NULL)
+                       {
+                               free(path);
+                       }
+
+                       break;
+               }
+               case DATACONTROL_TYPE_UNDEFINED:        // DATACONTROL_TYPE_MAP_SET || ADD || REMOVE
+               {
+                       const char* list[2];
+                       list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
+                       list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+                       bundle_add_str_array(res, OSP_K_ARG, list, 2);
+                       break;
+               }
+               default:  // Error
+               {
+                       const char* list[2];
+                       list[PACKET_INDEX_REQUEST_RESULT] = "0";                // request result
+                       list[PACKET_INDEX_ERROR_MSG] = (char*)data;  // error string
+
+                       bundle_add_str_array(res, OSP_K_ARG, list, 2);
+                       break;
+               }
+       }
+
+       return res;
+}
+
+static int
+__send_result(bundle* b, datacontrol_request_type type)
+{
+       int ret = aul_send_service_result(b);
+
+       if (ret < 0)
+       {
+               LOGE("Fail to send a result to caller");
+
+               int index = 0;
+
+               switch (type)
+               {
+                       case DATACONTROL_TYPE_SQL_SELECT:
+                       {
+                               index = PACKET_INDEX_SELECT_RESULT_FILE;
+                               break;
+                       }
+                       case DATACONTROL_TYPE_MAP_GET:
+                       {
+                               index = PACKET_INDEX_GET_RESULT_FILE;
+                               break;
+                       }
+                       default:
+                       {
+                               bundle_free(b);
+                               return DATACONTROL_ERROR_IO_ERROR;
+                       }
+               }
+
+               int len = 0;
+               const char **str_arr = bundle_get_str_array(b, OSP_K_ARG, &len);
+               SECURE_LOGI("result file: %s (%d)", str_arr[index], index);
+               ret = remove(str_arr[index]);
+               if (ret == -1)
+               {
+                       SECURE_LOGE("unable to remove the result file. errno = %d", errno);
+               }
+
+               bundle_free(b);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_free(b);
+       return DATACONTROL_ERROR_NONE;
+}
+
+int
+__datacontrol_handler_cb(bundle *b, int request_id, void* data)
+{
+       LOGI("datacontrol_handler_cb");
+
+       const char *request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+       if (request_type == NULL)
+       {
+               LOGE("Invalid data control request");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       // Get the request type
+       datacontrol_request_type type = atoi(request_type);
+       if (type >= DATACONTROL_TYPE_SQL_SELECT && type <= DATACONTROL_TYPE_SQL_DELETE)
+       {
+               if (provider_sql_cb == NULL)
+               {
+                       LOGE("SQL callback is not registered.");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (type >= DATACONTROL_TYPE_MAP_GET && type <= DATACONTROL_TYPE_MAP_REMOVE)
+       {
+               if (provider_map_cb == NULL)
+               {
+                       LOGE("Map callback is not registered.");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else
+       {
+               LOGE("Invalid requeste type");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       int len = 0;
+       const char **arg_list = bundle_get_str_array(b, OSP_K_ARG, &len);
+
+       datacontrol_h provider = malloc(sizeof(struct datacontrol_s));
+
+       // Set the provider ID
+       provider->provider_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+
+       // Set the data ID
+       provider->data_id = (char*)arg_list[PACKET_INDEX_DATAID];
+
+       // Set the request ID
+       int provider_req_id = __provider_new_request_id();
+
+       SECURE_LOGI("Provider ID: %s, data ID: %s, request type: %s", provider->provider_id, provider->data_id, request_type);
+
+       // Add the data to the table
+       int *key = malloc(sizeof(int));
+       *key = provider_req_id;
+
+       bundle *value = bundle_dup(b);
+       g_hash_table_insert(request_table, key, value);
+
+       switch (type)
+       {
+               case DATACONTROL_TYPE_SQL_SELECT:
+                       {
+                               int i = 1;
+                               int current = 0;
+                               int column_count = atoi(arg_list[i++]); // Column count
+
+                               LOGI("SELECT column count: %d", column_count);
+
+                               const char** column_list = (const char**)malloc(column_count * (sizeof(char *)));
+
+                               while (current < column_count)
+                               {
+                                       column_list[current++] = arg_list[i++];  // Column data
+
+                                       LOGI("Column %d: %s", current, column_list[current-1]);
+                               }
+
+                               const char *where = arg_list[i++];  // where
+                               const char *order = arg_list[i++];  // order
+
+                               LOGI("where: %s, order: %s", where, order);
+
+                               if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+                               {
+                                       where = NULL;
+                               }
+
+                               if (strncmp(order, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+                               {
+                                       order = NULL;
+                               }
+
+                               const char *page_number = arg_list[i++];
+                               const char *per_page =  arg_list[i];
+
+                               bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
+                               bundle_add_str(value, MAX_COUNT_PER_PAGE, per_page);
+
+                               char *statement = _datacontrol_create_select_statement(provider->data_id, column_list, column_count, where, order, atoi(page_number), atoi(per_page));
+
+                               // Add a select statement to the bundle
+                               bundle_add_str(value, DATACONTROL_SELECT_STATEMENT, statement);
+
+                               free(statement);
+
+                               provider_sql_cb->select(provider_req_id, provider, column_list, column_count, where, order, provider_sql_user_data);
+
+                               free(column_list);
+
+                               break;
+                       }
+               case DATACONTROL_TYPE_SQL_INSERT:
+               case DATACONTROL_TYPE_SQL_UPDATE:
+                       {
+                               int column_count = atoi(arg_list[PACKET_INDEX_COLUMNCOUNT]);
+                               const char *sql_path = arg_list[PACKET_INDEX_MAP];
+
+                               LOGI("INSERT / UPDATE handler");
+                               SECURE_LOGI("Data path: %s, Column count: %d", sql_path, column_count);
+
+                               bundle* sql = __get_data_sql(sql_path, column_count);
+
+                               if (type == DATACONTROL_TYPE_SQL_INSERT)
+                               {
+                                       SECURE_LOGI("INSERT column count: %d, sql_path: %s", column_count, sql_path);
+                                       provider_sql_cb->insert(provider_req_id, provider, sql, provider_sql_user_data);
+                               }
+                               else
+                               {
+                                       const char *where = arg_list[PACKET_INDEX_UPDATEWHERE];
+                                       LOGI("UPDATE from where: %s", where);
+
+                                       if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+                                       {
+                                               where = NULL;
+                                       }
+                                       provider_sql_cb->update(provider_req_id, provider, sql, where, provider_sql_user_data);
+                               }
+
+                               bundle_free(sql);
+                               break;
+                       }
+               case DATACONTROL_TYPE_SQL_DELETE:
+                       {
+                               const char *where = arg_list[PACKET_INDEX_DELETEWHERE];
+
+                               LOGI("DELETE from where: %s", where);
+                               if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+                               {
+                                       where = NULL;
+                               }
+                               provider_sql_cb->delete(provider_req_id, provider, where, provider_sql_user_data);
+                               break;
+                       }
+               case DATACONTROL_TYPE_MAP_GET:
+                       {
+                               const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+                               const char *page_number= arg_list[PACKET_INDEX_MAP_PAGE_NO];
+                               const char *count_per_page =  arg_list[PACKET_INDEX_MAP_COUNT_PER_PAGE];
+                               bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
+                               bundle_add_str(value, MAX_COUNT_PER_PAGE, count_per_page);
+
+                               LOGI("Gets the value list related with the key(%s) from Map datacontrol. ", map_key);
+
+                               provider_map_cb->get(provider_req_id, provider, map_key, provider_map_user_data);
+                               break;
+                       }
+               case DATACONTROL_TYPE_MAP_SET:
+                       {
+                               const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+                               const char *old_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
+                               const char *new_value = arg_list[PACKET_INDEX_MAP_VALUE_2ND];
+
+                               LOGI("Sets the old value(%s) of the key(%s) to the new value(%s) in Map datacontrol.", old_value, map_key, new_value);
+
+                               provider_map_cb->set(provider_req_id, provider, map_key, old_value, new_value, provider_map_user_data);
+                               break;
+                       }
+               case DATACONTROL_TYPE_MAP_ADD:
+                       {
+                               const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+                               const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
+
+                               LOGI("Adds the %s-%s in Map datacontrol.", map_key, map_value);
+
+                               provider_map_cb->add(provider_req_id, provider, map_key, map_value, provider_map_user_data);
+                               break;
+                       }
+               case DATACONTROL_TYPE_MAP_REMOVE:
+                       {
+                               const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+                               const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
+
+                               LOGI("Removes the %s-%s in Map datacontrol.", map_key, map_value);
+
+                               provider_map_cb->remove(provider_req_id, provider, map_key, map_value, provider_map_user_data);
+                               break;
+                       }
+               default:
+                               break;
+       }
+
+       free(provider);
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+int
+datacontrol_provider_sql_register_cb(datacontrol_provider_sql_cb *callback, void *user_data)
+{
+       int ret = DATACONTROL_ERROR_NONE;
+
+       if (callback == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       LOGI("datacontrol_provider_sql_register_cb");
+
+       provider_sql_cb = callback;
+       provider_sql_user_data = user_data;
+
+       if (provider_map_cb == NULL)    // If the provider_map_cb was registered(not NULL), __datacontrol_handler_cb is set already.
+       {
+               ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
+       }
+
+       return ret;
+}
+
+int
+datacontrol_provider_sql_unregister_cb(void)
+{
+       if (provider_map_cb == NULL)    // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible.
+       {
+               aul_unset_data_control_provider_cb();
+       }
+       provider_sql_cb = NULL;
+       provider_sql_user_data = NULL;
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+int datacontrol_provider_map_register_cb(datacontrol_provider_map_cb *callback, void *user_data)
+{
+       int ret = DATACONTROL_ERROR_NONE;
+
+       if (callback == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       LOGI("datacontrol_provider_map_register_cb");
+
+       provider_map_cb = callback;
+       provider_map_user_data = user_data;
+
+       if (provider_sql_cb == NULL)    // If the provider_sql_cb was registered(not NULL), __datacontrol_handler_cb is set already.
+       {
+               ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
+       }
+
+       return ret;
+}
+
+int datacontrol_provider_map_unregister_cb(void)
+{
+       if (provider_sql_cb == NULL)    // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible.
+       {
+               aul_unset_data_control_provider_cb();
+       }
+       provider_map_cb = NULL;
+       provider_map_user_data = NULL;
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+int
+datacontrol_provider_get_client_appid(int request_id, char **appid)
+{
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       const char *caller = bundle_get_val(b, AUL_K_CALLER_APPID);
+       if (!caller)
+       {
+               SECURE_LOGE("No appid for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       SECURE_LOGI("Request ID: %d, caller appid: %s", request_id, caller);
+
+       *appid = strdup(caller);
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+int
+datacontrol_provider_send_select_result(int request_id, void *db_handle)
+{
+       SECURE_LOGI("Send a select result for request id: %d", request_id);
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, db_handle);
+
+       return __send_result(res, DATACONTROL_TYPE_SQL_SELECT);
+}
+
+int
+datacontrol_provider_send_insert_result(int request_id, long long row_id)
+{
+       SECURE_LOGI("Send an insert result for request id: %d", request_id);
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_INSERT, (void*)&row_id);
+
+       return __send_result(res, DATACONTROL_TYPE_SQL_INSERT);
+}
+
+int
+datacontrol_provider_send_update_result(int request_id)
+{
+       SECURE_LOGI("Send an update result for request id: %d", request_id);
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_UPDATE, NULL);
+
+       return __send_result(res, DATACONTROL_TYPE_SQL_UPDATE);
+}
+
+int
+datacontrol_provider_send_delete_result(int request_id)
+{
+       SECURE_LOGI("Send a delete result for request id: %d", request_id);
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_DELETE, NULL);
+
+       return __send_result(res, DATACONTROL_TYPE_SQL_DELETE);
+}
+
+int
+datacontrol_provider_send_error(int request_id, const char *error)
+{
+       SECURE_LOGI("Send an error for request id: %d", request_id);
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       bundle* res = __set_result(b, DATACONTROL_TYPE_ERROR, (void*)error);
+
+       return __send_result(res, DATACONTROL_TYPE_ERROR);
+}
+
+int
+datacontrol_provider_send_map_result(int request_id)
+{
+       SECURE_LOGI("Send a set/add/remove result for request id: %d", request_id);
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       bundle* res = __set_result(b, DATACONTROL_TYPE_UNDEFINED, NULL);
+
+       return __send_result(res, DATACONTROL_TYPE_UNDEFINED);
+}
+
+int
+datacontrol_provider_send_map_get_value_result(int request_id, char **value_list, int value_count)
+{
+       SECURE_LOGI("Send a get result for request id: %d", request_id);
+
+       if (request_table == NULL)
+       {
+               __initialize_provider();
+       }
+
+       bundle* b = g_hash_table_lookup(request_table, &request_id);
+       if (!b)
+       {
+               SECURE_LOGE("No data for the request id: %d", request_id);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       char value_count_str[32] = {0,};
+       snprintf(value_count_str, 32, "%d", value_count);
+       bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str);
+
+       bundle* res = __set_result(b, DATACONTROL_TYPE_MAP_GET, value_list);
+
+       return __send_result(res, DATACONTROL_TYPE_MAP_GET);
+}
diff --git a/src/data-control-sql-cursor.c b/src/data-control-sql-cursor.c
new file mode 100644 (file)
index 0000000..80b1471
--- /dev/null
@@ -0,0 +1,764 @@
+#include <dlog.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "data-control-sql-cursor.h"
+
+#undef LOG_TAG
+#ifndef LOG_TAG
+#define LOG_TAG "DATA_CONTROL"
+#endif
+
+static int *row_offset_list = NULL;
+
+resultset_cursor* datacontrol_sql_get_cursor(const char * path)
+{
+       resultset_cursor *cursor = (resultset_cursor *)calloc(sizeof(resultset_cursor), 1);
+       if (!cursor)
+       {
+               LOGE("unable to create cursor");
+               return NULL;
+       }
+
+       cursor->resultset_row_count = 0;
+       cursor->resultset_col_count = 0;
+       cursor->resultset_col_type_offset = 0;
+       cursor->resultset_col_name_offset = 0;
+       cursor->resultset_content_offset = 0;
+       cursor->resultset_current_offset = 0;
+       cursor->resultset_current_row_count = 0;
+       /* TODO - shoud be changed to solve security concerns */
+       cursor->resultset_fd = open(path, O_RDONLY, 644);
+       if (cursor->resultset_fd == -1)
+       {
+               SECURE_LOGE("unable to open resultset file(%s): %d", path, errno);
+               goto EXCEPTION;
+       }
+
+       cursor->resultset_path = strdup(path);
+       if (!cursor->resultset_path)
+       {
+               SECURE_LOGE("unable to assign path to resultset file: %d", errno);
+               close(cursor->resultset_fd);
+               goto EXCEPTION;
+       }
+
+       return cursor;
+
+EXCEPTION:
+       free(cursor);
+       return NULL;
+}
+
+int datacontrol_sql_step_next(resultset_cursor *cursor)
+{
+       int total_col_name_size = 0;
+       int ret = 0;
+       int fd = cursor->resultset_fd;
+       if (cursor->resultset_current_offset == 0)
+       {
+               ret = lseek(fd, 0, SEEK_SET);
+               if (ret < 0)
+               {
+                       LOGE("unable to seek to beginning in the resultset file: %d", errno);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &(cursor->resultset_row_count), sizeof(int));
+               if (ret <= 0)
+               {
+                       LOGE("unable to read the resultset file: %d", errno);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &(cursor->resultset_col_count), sizeof(int));
+               if (ret <= 0)
+               {
+                       LOGE("unable to read the resultset file: %d", errno);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &(total_col_name_size), sizeof(int));
+               if (ret <= 0)
+               {
+                       LOGE("unable to read the resultset file: %d", errno);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               cursor->resultset_col_type_offset = sizeof(int) * 3;
+               cursor->resultset_col_name_offset = cursor->resultset_col_type_offset + (cursor->resultset_col_count) * sizeof(int);
+               cursor->resultset_content_offset = cursor->resultset_col_name_offset + total_col_name_size;
+
+               cursor->resultset_current_offset = cursor->resultset_content_offset;
+
+               row_offset_list = (int *)malloc((cursor->resultset_row_count) * (sizeof(int)));
+               if (!row_offset_list)
+               {
+                       LOGE("unable to create row_offset_list");
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+
+               int counter = 0;
+               for (counter = 0; counter < cursor->resultset_row_count; counter++)
+               {
+                       row_offset_list[counter] = 0;
+               }
+               row_offset_list[cursor->resultset_current_row_count] = cursor->resultset_current_offset;
+       }
+       else
+       {
+               if (!(cursor->resultset_current_row_count < (cursor->resultset_row_count -1)))
+               {
+                       LOGE("Reached to the end of the result set");
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = row_offset_list[cursor->resultset_current_row_count + 1];
+               if (ret == 0) // Move to next offset
+               {
+                       int size = 0;
+                       int i = 0;
+
+                       ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
+                       if (ret < 0)
+                       {
+                               LOGE("unable to seek in the resultset file: %d", errno);
+                               return DATACONTROL_ERROR_IO_ERROR;
+                       }
+
+                       for (i = 0; i < cursor->resultset_col_count; i++)
+                       {
+                               ret = lseek(fd, sizeof(int), SEEK_CUR);
+                               if (ret < 0)
+                               {
+                                       LOGE("unable to seek in the resultset file: %d", errno);
+                                       return DATACONTROL_ERROR_IO_ERROR;
+                               }
+
+                               ret = read(fd, &size, sizeof(int));
+                               if (ret == 0)
+                               {
+                                       LOGE("unable to read the resultset file: %d", errno);
+                                       return DATACONTROL_ERROR_IO_ERROR;
+                               }
+
+                               ret = lseek(fd, size, SEEK_CUR);
+                               if (ret < 0)
+                               {
+                                       LOGE("unable to seek in the resultset file: %d", errno);
+                                       return DATACONTROL_ERROR_IO_ERROR;
+                               }
+
+                               cursor->resultset_current_offset += sizeof(int) * 2 + size;
+                       }
+
+                       row_offset_list[cursor->resultset_current_row_count + 1] = cursor->resultset_current_offset;
+               }
+               else
+               {
+                       cursor->resultset_current_offset = row_offset_list[cursor->resultset_current_row_count + 1];
+               }
+               cursor->resultset_current_row_count++;
+
+       }
+       return DATACONTROL_ERROR_NONE;
+}
+
+int datacontrol_sql_step_last(resultset_cursor *cursor)
+{
+       int ret = 0;
+
+       if (cursor->resultset_current_row_count == (cursor->resultset_row_count - 1))
+       {
+               return DATACONTROL_ERROR_NONE; // Already @ last row
+       }
+
+       if (!row_offset_list)
+       {
+               ret = datacontrol_sql_step_next(cursor); // make a first move
+               if (ret != DATACONTROL_ERROR_NONE)
+               {
+                       return ret;
+               }
+       }
+
+       // check if the rowOffsetList contains last row offset
+       if (row_offset_list && row_offset_list[cursor->resultset_row_count - 1] != 0)
+       {
+               cursor->resultset_current_offset = row_offset_list[cursor->resultset_row_count - 1];
+               cursor->resultset_current_row_count = cursor->resultset_row_count - 1;
+       }
+       else
+       {
+               int i = 0;
+               // Move till last row offset.
+               for (i = (cursor->resultset_current_row_count + 1); i < cursor->resultset_row_count; i++)
+               {
+                       ret = datacontrol_sql_step_next(cursor); // move till last row data offset
+                       if (ret != DATACONTROL_ERROR_NONE)
+                       {
+                               return ret;
+                       }
+
+               }
+       }
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+
+int datacontrol_sql_step_first(resultset_cursor *cursor)
+{
+       if (cursor->resultset_current_offset > 0)
+       {
+               cursor->resultset_current_offset = cursor->resultset_content_offset;
+               cursor->resultset_current_row_count = 0;
+               return DATACONTROL_ERROR_NONE;
+       }
+
+       // MoveFirst is called for the first time before MoveNext() or MoveLast()
+       cursor->resultset_current_offset = 0;
+       return datacontrol_sql_step_next(cursor);
+}
+
+
+int datacontrol_sql_step_previous(resultset_cursor *cursor)
+{
+       if ((cursor->resultset_current_row_count - 1) < 0)
+       {
+               LOGE("invalid request");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+       cursor->resultset_current_offset = row_offset_list[cursor->resultset_current_row_count - 1];
+       cursor->resultset_current_row_count--;
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+
+int datacontrol_sql_get_column_count(resultset_cursor *cursor)
+{
+       return cursor->resultset_col_count;
+}
+
+int datacontrol_sql_get_column_name(resultset_cursor *cursor, int column_index, char *name)
+{
+       char col_name[4096] = {0, };
+       int i = 0;
+       int ret = 0;
+       FILE *fp = fdopen(dup(cursor->resultset_fd), "r");
+       if (fp == NULL)
+       {
+               LOGE("unable to open resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       ret = fseek(fp, cursor->resultset_col_name_offset, SEEK_SET);
+       if (ret < 0)
+       {
+               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+               fclose(fp);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       for (i = 0; i < column_index + 1; i++)
+       {
+               if (!(fgets(col_name, 4096, fp)))
+               {
+                       LOGE("unable to read a line in the resultset file: %s", strerror(errno));
+                       fclose(fp);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
+       memset(name, 0, strlen(col_name)); // To avoid copying newline
+       memcpy(name, col_name, strlen(col_name) - 1);
+
+       LOGI("The column name is %s", name);
+
+       fclose(fp);
+       return DATACONTROL_ERROR_NONE;
+}
+
+
+int datacontrol_sql_get_column_item_size(resultset_cursor *cursor, int column_index)
+{
+       int type = -1;
+       int size = 0;
+       int i = 0;
+       int ret = 0;
+
+       int fd = cursor->resultset_fd;
+
+       ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
+       if (ret < 0)
+       {
+               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       for (i = 0; i < column_index; i++) // move to column index
+       {
+               ret = read(fd, &type, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &size, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = lseek(fd, size, SEEK_CUR);
+               if (ret < 0)
+               {
+                       LOGE("unable to seek in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
+       ret = read(fd, &type, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       ret = read(fd, &size, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       return size;
+}
+
+
+int datacontrol_sql_get_column_item_type(resultset_cursor *cursor, int column_index, datacontrol_sql_column_type* col_type)
+{
+       int type = -1;
+       int i = 0;
+       int size = 0;
+       int ret = 0;
+
+       int fd = cursor->resultset_fd;
+
+       ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
+       if (ret < 0)
+       {
+               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       for (i = 0; i < column_index; i++) // move to column index
+       {
+               ret = read(fd, &type, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &size, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = lseek(fd, size, SEEK_CUR);
+               if (ret < 0)
+               {
+                       LOGE("unable to seek in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
+       ret = read(fd, &type, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       switch (type)
+       {
+       case DATACONTROL_SQL_COLUMN_TYPE_INT64:
+               *col_type = DATACONTROL_SQL_COLUMN_TYPE_INT64;
+               break;
+
+       case DATACONTROL_SQL_COLUMN_TYPE_DOUBLE:
+               *col_type = DATACONTROL_SQL_COLUMN_TYPE_DOUBLE;
+               break;
+
+       case DATACONTROL_SQL_COLUMN_TYPE_TEXT:
+               *col_type = DATACONTROL_SQL_COLUMN_TYPE_TEXT;
+               break;
+
+       case DATACONTROL_SQL_COLUMN_TYPE_BLOB:
+               *col_type = DATACONTROL_SQL_COLUMN_TYPE_BLOB;
+               break;
+
+       case DATACONTROL_SQL_COLUMN_TYPE_NULL:
+               *col_type = DATACONTROL_SQL_COLUMN_TYPE_NULL;
+               break;
+
+       default:
+               *col_type = DATACONTROL_SQL_COLUMN_TYPE_UNDEFINED;
+               break;
+       }
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+
+int datacontrol_sql_get_blob_data(resultset_cursor *cursor, int column_index, void *buffer, int data_size)
+{
+       int type = -1;
+       int size = 0;
+       int i = 0;
+       int ret = 0;
+
+       int fd = cursor->resultset_fd;
+
+       ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
+       if (ret < 0)
+       {
+               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       for (i = 0; i < column_index; i++) // move to column index
+       {
+               ret = read(fd, &type, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &size, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = lseek(fd, size, SEEK_CUR);
+               if (ret < 0)
+               {
+                       LOGE("unable to seek in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
+       ret = read(fd, &type, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_BLOB)
+       {
+               LOGE("type mismatch: requested for BLOB type but %d present:", type);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = read(fd, &size, sizeof(int));
+       if (size > data_size)
+       {
+               LOGE("size is more than the size requested");
+               return DATACONTROL_ERROR_MAX_EXCEEDED; //overflow
+       }
+
+       if (size > 0)
+       {
+               char *data = (char*)malloc((size + 1) * (sizeof(char)));
+               memset(data, 0, size + 1);
+
+               ret = read(fd, data, size);
+               if (ret < size)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       free(data);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               memcpy(buffer, data, size + 1);
+               free(data);
+       }
+       return DATACONTROL_ERROR_NONE;
+}
+
+
+int datacontrol_sql_get_int_data(resultset_cursor *cursor, int column_index, int *data)
+{
+       long long long_value = 0;
+       int ret = -1;
+
+       ret = datacontrol_sql_get_int64_data(cursor, column_index, &long_value);
+       if (ret == 0)
+       {
+               *data = (int) long_value;
+       }
+
+       return ret;
+}
+
+
+int datacontrol_sql_get_int64_data(resultset_cursor *cursor, int column_index, long long *data)
+{
+       int type = -1;
+       int size = 0;
+       int i = 0;
+       int ret = 0;
+
+       int fd = cursor->resultset_fd;
+
+       ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
+       if (ret < 0)
+       {
+               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       for (i = 0; i < column_index; i++) // move to column index
+       {
+               ret = read(fd, &type, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &size, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = lseek(fd, size, SEEK_CUR);
+               if (ret < 0)
+               {
+                       LOGE("unable to seek in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
+       ret = read(fd, &type, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_INT64)
+       {
+               LOGE("type mismatch: requested for int type but %d present:", type);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = read(fd, &size, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       ret = read(fd, data, size);
+       if (ret < size)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+int datacontrol_sql_get_double_data(resultset_cursor *cursor, int column_index, double *data)
+{
+       int type = -1;
+       int size = 0;
+       int i = 0;
+       int ret = 0;
+
+       int fd = cursor->resultset_fd;
+
+       ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
+       if (ret < 0)
+       {
+               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       for (i = 0; i < column_index; i++) // move to column index
+       {
+               ret = read(fd, &type, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &size, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = lseek(fd, size, SEEK_CUR);
+               if (ret < 0)
+               {
+                       LOGE("unable to seek in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
+       ret = read(fd, &type, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_DOUBLE)
+       {
+               LOGE("type mismatch: requested for double type but %d present:", type);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = read(fd, &size, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       ret = read(fd, data, size);
+       if (ret < size)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+
+int datacontrol_sql_get_text_data(resultset_cursor *cursor, int column_index, char *buffer)
+{
+       int type = -1;
+       int size = 0;
+       int i = 0;
+       int ret = 0;
+
+       int fd = cursor->resultset_fd;
+
+       ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
+       if (ret < 0)
+       {
+               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       for (i = 0; i < column_index; i++) // move to column index
+       {
+               ret = read(fd, &type, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = read(fd, &size, sizeof(int));
+               if (ret == 0)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               ret = lseek(fd, size, SEEK_CUR);
+               if (ret < 0)
+               {
+                       LOGE("unable to seek in the resultset file: %s", strerror(errno));
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+       }
+
+       ret = read(fd, &type, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_TEXT)
+       {
+               LOGE("type mismatch: requested for text type but %d present:", type);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = read(fd, &size, sizeof(int));
+       if (ret == 0)
+       {
+               LOGE("unable to read in the resultset file: %s", strerror(errno));
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       if (size > 0)
+       {
+               char *data = (char*)malloc((size + 1) * (sizeof(char)));
+               if(!data)
+               {
+                       LOGE("unable to create buffer to read");
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+
+               memset(data, 0, size + 1);
+               ret = read(fd, data, size);
+               if (ret < size)
+               {
+                       LOGE("unable to read in the resultset file: %s", strerror(errno));
+                       free(data);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               memcpy(buffer, data, size + 1);
+               free(data);
+       }
+
+       return DATACONTROL_ERROR_NONE;
+}
+
+
+int datacontrol_sql_remove_cursor(resultset_cursor *cursor)
+{
+       close(cursor->resultset_fd);
+
+       int ret = remove(cursor->resultset_path);
+       if (ret == -1)
+       {
+               LOGE("unable to remove map query result file: %d", ret);
+       }
+
+       free(row_offset_list);
+       row_offset_list = 0;
+
+       free(cursor->resultset_path);
+       free(cursor);
+
+       return DATACONTROL_ERROR_NONE;
+}
diff --git a/src/data-control-sql.c b/src/data-control-sql.c
new file mode 100644 (file)
index 0000000..98d45ce
--- /dev/null
@@ -0,0 +1,1175 @@
+#include <dlog.h>
+#include <errno.h>
+#include <search.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <appsvc/appsvc.h>
+#include <aul/aul.h>
+#include <bundle.h>
+#include <pkgmgr-info.h>
+
+#include "data-control-sql.h"
+#include "data-control-internal.h"
+
+#define REQUEST_PATH_MAX               512
+#define MAX_REQUEST_ARGUMENT_SIZE      1048576 // 1MB
+
+struct datacontrol_s {
+       char *provider_id;
+       char *data_id;
+};
+
+typedef struct
+{
+    char *provider_id;
+    char *app_id;
+    char *data_id;
+    char *access_info;
+    void *user_data;
+    datacontrol_sql_response_cb *sql_response_cb;
+} sql_response_cb_s;
+
+
+static void *datacontrol_sql_tree_root = NULL;
+
+static void
+datacontrol_sql_call_cb(const char *provider_id, int request_id, datacontrol_request_type type
+       , const char *data_id, bool provider_result, const char *error, long long insert_rowid, resultset_cursor* cursor, void* data)
+{
+       SECURE_LOGI("datacontrol_sql_call_cb, dataID: %s", data_id);
+
+       datacontrol_sql_response_cb *callback = NULL;
+
+       sql_response_cb_s *sql_dc = NULL;
+       sql_dc = (sql_response_cb_s *)data;
+       callback = sql_dc->sql_response_cb;
+       if (!callback)
+       {
+               LOGE("no listener set");
+               return;
+       }
+
+       datacontrol_h provider;
+       datacontrol_sql_create(&provider);
+
+       datacontrol_sql_set_provider_id(provider, provider_id);
+       datacontrol_sql_set_data_id(provider, data_id);
+
+       switch (type)
+       {
+               case DATACONTROL_TYPE_SQL_SELECT:
+               {
+                       LOGI("SELECT");
+                       if (callback != NULL && callback->select != NULL)
+                       {
+                               callback->select(request_id, provider, cursor, provider_result, error, sql_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+
+                       break;
+               }
+               case DATACONTROL_TYPE_SQL_INSERT:
+               {
+                       SECURE_LOGI("INSERT row_id: %lld", insert_rowid);
+                       if (callback != NULL && callback->insert != NULL)
+                       {
+                               callback->insert(request_id, provider, insert_rowid, provider_result, error, sql_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+
+                       break;
+               }
+               case DATACONTROL_TYPE_SQL_UPDATE:
+               {
+                       LOGI("UPDATE");
+                       if (callback != NULL && callback->update != NULL)
+                       {
+                               callback->update(request_id, provider, provider_result, error, sql_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+
+                       break;
+               }
+               case DATACONTROL_TYPE_SQL_DELETE:
+               {
+                       LOGI("DELETE");
+                       if (callback != NULL && callback->delete != NULL)
+                       {
+                               callback->delete(request_id, provider, provider_result, error, sql_dc->user_data);
+                       }
+                       else
+                       {
+                               LOGI("No registered callback function");
+                       }
+                       break;
+               }
+               default:
+                       break;
+       }
+
+       datacontrol_sql_destroy(provider);
+}
+
+static void
+datacontrol_sql_instance_free(void *datacontrol_sql_instance)
+{
+       sql_response_cb_s *dc = (sql_response_cb_s *)datacontrol_sql_instance;
+       if (dc)
+       {
+               free(dc->provider_id);
+               free(dc->data_id);
+               free(dc->app_id);
+               free(dc->access_info);
+               free(datacontrol_sql_instance);
+       }
+
+       return;
+}
+
+static int
+datacontrol_sql_instance_compare(const void *l_datacontrol_sql_instance, const void *r_datacontrol_sql_instance)
+{
+       sql_response_cb_s *dc_left = (sql_response_cb_s *)l_datacontrol_sql_instance;
+       sql_response_cb_s *dc_right = (sql_response_cb_s *)r_datacontrol_sql_instance;
+       return strcmp(dc_left->provider_id, dc_right->provider_id);
+}
+
+
+static int
+datacontrol_sql_handle_cb(bundle* b, int request_code, appsvc_result_val res, void* data)
+{
+       SECURE_LOGI("datacontrol_sql_handle_cb, request_code: %d, result: %d", request_code, res);
+
+       int ret = 0;
+       const char** result_list = NULL;
+       resultset_cursor *cursor = NULL;
+       const char* provider_id = NULL;
+       const char* data_id = NULL;
+       const char* error_message = NULL;
+       long long insert_rowid = -1;
+       datacontrol_request_type request_type = 0;
+       int request_id = -1;
+       int result_list_len = 0;
+       int provider_result = 0;
+       const char* resultset_path = NULL;
+       const char* p = NULL;
+
+       if (b)
+       {
+               p = appsvc_get_data(b, OSP_K_REQUEST_ID);
+               if (!p)
+               {
+                       LOGE("Invalid Bundle: request_id is null");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+               else
+               {
+                       request_id = atoi(p);
+               }
+
+               SECURE_LOGI("Request ID: %d", request_id);
+
+               // result list
+               result_list = appsvc_get_data_array(b, OSP_K_ARG, &result_list_len);
+               if (!result_list)
+               {
+                       LOGE("Invalid Bundle: arguement list is null");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               p = result_list[0]; // result list[0] = provider_result
+               if (!p)
+               {
+                       LOGE("Invalid Bundle: provider_result is null");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               LOGI("Provider result: %s", p);
+
+               provider_result = atoi(p);
+
+               error_message = result_list[1]; // result list[1] = error
+               if (!error_message)
+               {
+                       LOGE("Invalid Bundle: error_message is null");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               LOGI("Error message: %s", error_message);
+
+               p = appsvc_get_data(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+               if (!p)
+               {
+                       LOGE("Invalid Bundle: data-control request type is null");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               request_type = (datacontrol_request_type)atoi(p);
+
+               provider_id = appsvc_get_data(b, OSP_K_DATACONTROL_PROVIDER);
+               if (!provider_id)
+               {
+                       LOGE("Invalid Bundle: provider_id is null");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               data_id = appsvc_get_data(b, OSP_K_DATACONTROL_DATA);
+               if (!data_id)
+               {
+                       LOGE("Invalid Bundle: data_id is null");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               SECURE_LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type);
+
+               switch (request_type)
+               {
+                       case DATACONTROL_TYPE_SQL_SELECT:
+                       {
+                               LOGI("SELECT RESPONSE");
+                               if (provider_result)
+                               {
+                                       resultset_path = result_list[2]; // result list[2]
+                                       if (!resultset_path)
+                                       {
+                                               LOGE("sql query result path is null");
+                                               return DATACONTROL_ERROR_INVALID_PARAMETER;
+                                       }
+
+                                       SECURE_LOGI("resultset_path: %s", resultset_path);
+
+                                       if (strcmp(resultset_path, "NoResultSet") != 0) // Result set exists
+                                       {
+                                               cursor = datacontrol_sql_get_cursor(resultset_path);
+                                               if (!cursor)
+                                               {
+                                                       LOGE("failed to get cursor on sql query resultset");
+                                                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+                                               }
+                                       }
+                               }
+                               break;
+                       }
+                       case DATACONTROL_TYPE_SQL_INSERT:
+                       {
+                               LOGI("INSERT RESPONSE");
+                               if (provider_result)
+                               {
+                                       p = result_list[2]; // result list[2]
+                                       if (!p)
+                                       {
+                                               LOGE("Invalid Bundle: insert row_id is null");
+                                               return DATACONTROL_ERROR_INVALID_PARAMETER;
+                                       }
+
+                                       insert_rowid = atoll(p);
+                               }
+                               break;
+                       }
+                       case DATACONTROL_TYPE_SQL_UPDATE:
+                       case DATACONTROL_TYPE_SQL_DELETE:
+                       {
+                               LOGI("UPDATE or DELETE RESPONSE");
+                               break;
+                       }
+
+                       default:
+                               break;
+               }
+
+       }
+       else
+       {
+               LOGE("the bundle returned from datacontrol-provider-service is null");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (request_type >=  DATACONTROL_TYPE_SQL_SELECT && request_type <=  DATACONTROL_TYPE_SQL_DELETE)
+       {
+               datacontrol_sql_call_cb(provider_id, request_id, request_type, data_id, provider_result, error_message, insert_rowid, cursor, data);
+               if ((request_type == DATACONTROL_TYPE_SQL_SELECT) && (cursor))
+               {
+                       datacontrol_sql_remove_cursor(cursor);
+               }
+
+               ret = DATACONTROL_ERROR_NONE;
+       }
+       else
+       {
+               ret = DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       return ret;
+}
+
+static void
+app_svc_res_cb_sql(bundle* b, int request_code, appsvc_result_val res, void* data)
+{
+       LOGI("app_svc_res_cb_sql, request_code: %d, result: %d", request_code, res);
+
+       if (data)
+       {
+               datacontrol_sql_handle_cb(b, request_code, res, data);
+       }
+       else
+       {
+               LOGE("error: listener information is null");
+       }
+}
+
+
+static int
+datacontrol_sql_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *arg_list, int request_id)
+{
+       SECURE_LOGI("SQL Data control request, type: %d, request id: %d", type, request_id);
+
+       char *app_id = NULL;
+       void *data = NULL;
+
+       if ((int)type <= (int)DATACONTROL_TYPE_SQL_DELETE)
+       {
+               if ((int)type < (int)DATACONTROL_TYPE_SQL_SELECT)
+               {
+                       LOGE("invalid request type: %d", (int)type);
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               if (!datacontrol_sql_tree_root)
+               {
+                       LOGE("the listener tree is empty");
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(sizeof(sql_response_cb_s),1);
+               if (!sql_dc_temp)
+               {
+                       LOGE("failed to create sql datacontrol");
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+
+               sql_dc_temp->provider_id = strdup(provider->provider_id);
+               if (!sql_dc_temp->provider_id)
+               {
+                       LOGE("failed to assign provider id to sql data control: %d", errno);
+                       free(sql_dc_temp);
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+
+               sql_dc_temp->data_id = strdup(provider->data_id);
+               if (!sql_dc_temp->data_id)
+               {
+                       LOGE("failed to assign data id to sql data control: %d", errno);
+                       free(sql_dc_temp->provider_id);
+                       free(sql_dc_temp);
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+
+               sql_dc_temp->app_id = NULL;
+               sql_dc_temp->access_info = NULL;
+               sql_dc_temp->user_data = NULL;
+               sql_dc_temp->sql_response_cb = NULL;
+
+               void *sql_dc_returned = NULL;
+               sql_dc_returned = tfind(sql_dc_temp, &datacontrol_sql_tree_root, datacontrol_sql_instance_compare);
+
+               datacontrol_sql_instance_free(sql_dc_temp);
+
+               if (!sql_dc_returned)
+               {
+                       LOGE("sql datacontrol returned after tfind is null");
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+               sql_response_cb_s *sql_dc = *(sql_response_cb_s **)sql_dc_returned;
+               app_id = sql_dc->app_id;
+               data = sql_dc;
+
+               SECURE_LOGI("SQL datacontrol appid: %s", sql_dc->app_id);
+       }
+
+       char caller_app_id[255];
+       pid_t pid = getpid();
+       if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0)
+       {
+               SECURE_LOGE("Failed to get appid by pid(%d).", pid);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT);
+       appsvc_set_appid(arg_list, app_id);
+       bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP);
+       bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
+       bundle_add_str(arg_list, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
+       bundle_add_str(arg_list, AUL_K_CALLER_APPID, caller_app_id);
+       bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1");
+
+
+       char datacontrol_request_operation[MAX_LEN_DATACONTROL_REQ_TYPE] = {0, };
+       snprintf(datacontrol_request_operation, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(type));
+       bundle_add_str(arg_list, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation);
+
+       char req_id[32] = {0, };
+       snprintf(req_id, 32, "%d", request_id);
+       bundle_add_str(arg_list, OSP_K_REQUEST_ID, req_id);
+
+       // For DataControl CAPI
+       bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE");
+
+       SECURE_LOGI("SQL data control request - provider id: %s, data id: %s, provider appid: %s, request ID: %s", provider->provider_id, provider->data_id, app_id, req_id);
+
+       pid = -1;
+       int count = 0;
+       const int TRY_COUNT = 4;
+       const int TRY_SLEEP_TIME = 65000;
+       do
+       {
+               pid = appsvc_run_service(arg_list, request_id, app_svc_res_cb_sql, data);
+               if (pid >= 0)
+               {
+                       SECURE_LOGI("Launch the provider app successfully: %d", pid);
+                       return DATACONTROL_ERROR_NONE;
+               }
+               else if (pid == APPSVC_RET_EINVAL)
+               {
+                       SECURE_LOGE("not able to launch service: %d", pid);
+                       return DATACONTROL_ERROR_INVALID_PARAMETER;
+               }
+
+               count++;
+
+               usleep(TRY_SLEEP_TIME);
+       }
+       while (count < TRY_COUNT);
+
+       SECURE_LOGE("unable to launch service: %d", pid);
+       return DATACONTROL_ERROR_IO_ERROR;
+}
+
+int
+datacontrol_sql_create(datacontrol_h *provider)
+{
+       struct datacontrol_s *request;
+
+       if (provider == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       request = malloc(sizeof(struct datacontrol_s));
+       if (request == NULL)
+       {
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       request->provider_id = NULL;
+       request->data_id = NULL;
+
+       *provider = request;
+
+       return 0;
+}
+
+int
+datacontrol_sql_destroy(datacontrol_h provider)
+{
+       if (provider == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->provider_id != NULL)
+       {
+               free(provider->provider_id);
+       }
+
+       if (provider->data_id != NULL)
+       {
+               free(provider->data_id);
+       }
+
+       free(provider);
+       return 0;
+}
+
+int
+datacontrol_sql_set_provider_id(datacontrol_h provider, const char *provider_id)
+{
+       if (provider == NULL || provider_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->provider_id != NULL)
+       {
+               free(provider->provider_id);
+       }
+
+       provider->provider_id = strdup(provider_id);
+       if (provider->provider_id == NULL)
+       {
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       return 0;
+}
+
+int
+datacontrol_sql_get_provider_id(datacontrol_h provider, char **provider_id)
+{
+       if (provider == NULL || provider_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->provider_id != NULL)
+       {
+               *provider_id = strdup(provider->provider_id);
+               if (*provider_id == NULL)
+               {
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+       }
+       else
+       {
+               *provider_id = NULL;
+       }
+
+       return 0;
+}
+
+int
+datacontrol_sql_set_data_id(datacontrol_h provider, const char *data_id)
+{
+       if (provider == NULL || data_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->data_id != NULL)
+       {
+               free(provider->data_id);
+       }
+
+       provider->data_id = strdup(data_id);
+       if (provider->data_id == NULL)
+       {
+               return DATACONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       return 0;
+}
+
+int
+datacontrol_sql_get_data_id(datacontrol_h provider, char **data_id)
+{
+       if (provider == NULL || data_id == NULL)
+       {
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       if (provider->data_id != NULL)
+       {
+               *data_id = strdup(provider->data_id);
+               if (*data_id == NULL)
+               {
+                       return DATACONTROL_ERROR_OUT_OF_MEMORY;
+               }
+       }
+       else
+       {
+               *data_id = NULL;
+       }
+       return 0;
+}
+
+int
+datacontrol_sql_register_response_cb(datacontrol_h provider, datacontrol_sql_response_cb* callback, void *user_data)
+{
+       int ret = 0;
+       char* app_id = NULL;
+       char* access = NULL;
+
+       ret = pkgmgrinfo_appinfo_get_datacontrol_info(provider->provider_id, "Sql", &app_id, &access);
+       if (ret != PMINFO_R_OK)
+       {
+               LOGE("unable to get sql data control information: %d", ret);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       SECURE_LOGI("data control provider appid = %s", app_id);
+
+       sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(sizeof(sql_response_cb_s),1);
+       if (!sql_dc_temp)
+       {
+               LOGE("unable to create a temporary sql data control");
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       sql_dc_temp->provider_id = strdup(provider->provider_id);
+       if (!sql_dc_temp->provider_id)
+       {
+               LOGE("unable to assign provider_id to sql data control: %d", errno);
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       sql_dc_temp->data_id = strdup(provider->data_id);
+       if (!sql_dc_temp->data_id)
+       {
+               LOGE("unable to assign data_id to sql data control: %d", errno);
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       sql_dc_temp->app_id = app_id;
+       sql_dc_temp->access_info = access;
+       sql_dc_temp->user_data = user_data;
+       sql_dc_temp->sql_response_cb = callback;
+
+       void *sql_dc_returned = NULL;
+       sql_dc_returned = tsearch(sql_dc_temp, &datacontrol_sql_tree_root, datacontrol_sql_instance_compare);
+
+       sql_response_cb_s *sql_dc = *(sql_response_cb_s **)sql_dc_returned;
+       if (sql_dc != sql_dc_temp)
+       {
+               sql_dc->sql_response_cb = callback;
+               sql_dc->user_data = user_data;
+               LOGI("the data control is already set");
+               datacontrol_sql_instance_free(sql_dc_temp);
+       }
+
+       return DATACONTROL_ERROR_NONE;
+
+EXCEPTION:
+       if (access)
+               free(access);
+       if (app_id)
+               free(app_id);
+       if (sql_dc_temp)
+       {
+               if (sql_dc_temp->provider_id)
+                       free(sql_dc_temp->provider_id);
+               if (sql_dc_temp->data_id)
+                       free(sql_dc_temp->data_id);
+               free(sql_dc_temp);
+       }
+
+       return ret;
+}
+
+int
+datacontrol_sql_unregister_response_cb(datacontrol_h provider)
+{
+       int ret = DATACONTROL_ERROR_NONE;
+
+       sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(sizeof(sql_response_cb_s),1);
+
+       if (!sql_dc_temp)
+       {
+               LOGE("unable to create a temporary sql data control");
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+       sql_dc_temp->provider_id = strdup(provider->provider_id);
+       if (!sql_dc_temp->provider_id)
+       {
+               LOGE("unable to assign provider_id to sql data control: %d", errno);
+               ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
+               goto EXCEPTION;
+       }
+
+
+       void *sql_dc_returned = NULL;
+
+       sql_dc_returned = tdelete(sql_dc_temp, &datacontrol_sql_tree_root, datacontrol_sql_instance_compare);
+       if (sql_dc_returned == NULL)
+       {
+               LOGE("invalid parameter");
+               ret = DATACONTROL_ERROR_INVALID_PARAMETER;
+               goto EXCEPTION;
+       }
+
+
+EXCEPTION:
+       if (sql_dc_temp)
+       {
+               if (sql_dc_temp->provider_id)
+                       free(sql_dc_temp->provider_id);
+               free(sql_dc_temp);
+        }
+
+       return ret;
+
+}
+
+static void
+bundle_foreach_check_arg_size_cb(const char *key, const int type, const bundle_keyval_t *kv, void *arg_size)
+{
+       char *value = NULL;
+       size_t value_len = 0;
+       bundle_keyval_get_basic_val((bundle_keyval_t*)kv, (void**)&value, &value_len);
+
+       arg_size += (strlen(key) + value_len) * sizeof(wchar_t);
+       return;
+}
+
+static void
+bundle_foreach_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
+{
+       if (!key || !kv || !user_data)
+       {
+               return;
+       }
+
+       int fd = *(int *)user_data;
+
+       int key_len = strlen(key);
+       char *value = NULL;
+       size_t value_len = 0;
+       bundle_keyval_get_basic_val((bundle_keyval_t*)kv, (void**)&value, &value_len);
+
+       // Write a key
+       if (write(fd, &key_len, sizeof(int)) == -1)
+       {
+               LOGE("Writing a key_len to a file descriptor is failed. errno = %d", errno);
+       }
+       if (write(fd, key, key_len)  == -1)
+       {
+               LOGE("Writing a key to a file descriptor is failed. errno = %d", errno);
+       }
+       // Write a value
+       if (write(fd, &value_len, sizeof(int)) == -1)
+       {
+               LOGE("Writing a value_len to a file descriptor is failed. errno = %d", errno);
+       }
+       if (write(fd, value, value_len) == -1)
+       {
+               LOGE("Writing a value to a file descriptor is failed. errno = %d", errno);
+       }
+
+       return;
+}
+
+char *
+__get_provider_pkgid(char* provider_id)
+{
+       char* access = NULL;
+       char *provider_appid = NULL;
+       char *provider_pkgid = NULL;
+       pkgmgrinfo_appinfo_h app_info_handle = NULL;
+
+       int ret = pkgmgrinfo_appinfo_get_datacontrol_info(provider_id, "Sql", &provider_appid, &access);
+       if (ret != PMINFO_R_OK)
+       {
+               LOGE("unable to get sql data control information: %d", ret);
+               return NULL;
+       }
+
+       pkgmgrinfo_appinfo_get_appinfo(provider_appid, &app_info_handle);
+       pkgmgrinfo_appinfo_get_pkgname(app_info_handle, &provider_pkgid);
+       SECURE_LOGI("provider pkg id : %s", provider_pkgid);
+
+       if (access)
+       {
+               free(access);
+       }
+       if (provider_appid)
+       {
+               free(provider_appid);
+       }
+       return provider_pkgid ? strdup(provider_pkgid) : NULL;
+}
+
+int
+datacontrol_sql_insert(datacontrol_h provider, const bundle* insert_data, int *request_id)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || insert_data == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       SECURE_LOGI("SQL data control, insert to provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
+
+       int ret = 0;
+
+       char caller_app_id[256] = {0, };
+       pid_t pid = getpid();
+
+       if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0)
+       {
+               SECURE_LOGE("Failed to get appid by pid(%d).", pid);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       // Check size of arguments
+       long long arg_size = 0;
+       bundle_foreach((bundle*)insert_data, bundle_foreach_check_arg_size_cb, &arg_size);
+       arg_size += strlen(provider->data_id) * sizeof(wchar_t);
+       if (arg_size > MAX_REQUEST_ARGUMENT_SIZE)
+       {
+               LOGE("The size of the request argument exceeds the limit, 1M.");
+               return DATACONTROL_ERROR_MAX_EXCEEDED;
+       }
+
+       int reqId = _datacontrol_create_request_id();
+       SECURE_LOGI("request id: %d", reqId);
+       char insert_map_file[REQUEST_PATH_MAX] = {0, };
+       ret = snprintf(insert_map_file, REQUEST_PATH_MAX, "%s/%s_%d", DATACONTROL_REQUEST_FILE_PREFIX, caller_app_id, reqId);
+       if (ret < 0)
+       {
+               LOGE("unable to write formatted output to insert_map_file. errno = %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       SECURE_LOGI("insert_map_file : %s", insert_map_file);
+
+       int fd = 0;
+       char *provider_pkgid = __get_provider_pkgid(provider->provider_id);
+
+       /* TODO - shoud be changed to solve security concerns */
+       fd = open(insert_map_file, O_WRONLY | O_CREAT, 644);
+       if (fd == -1) {
+               SECURE_LOGE("unable to open insert_map file: %d", errno);
+               free(provider_pkgid);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       free(provider_pkgid);
+
+       int count = bundle_get_count((bundle*)insert_data);
+       LOGI("Insert column counts: %d", count);
+
+       bundle_foreach((bundle*)insert_data, bundle_foreach_cb, &fd);
+
+       fsync(fd);
+       close(fd);
+
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       char insert_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, };
+       ret = snprintf(insert_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", count);
+       if (ret < 0)
+       {
+               LOGE("unable to convert insert column count to string: %d", errno);
+               bundle_free(b);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       const char* arg_list[3];
+       arg_list[0] = provider->data_id;
+       arg_list[1] = insert_column_count;
+       arg_list[2] = insert_map_file;
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, 3);
+
+       // Set the request id
+       *request_id = reqId;
+
+       ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_INSERT, b, reqId);
+       if (ret != DATACONTROL_ERROR_NONE)
+       {
+               ret = remove(insert_map_file);
+               if (ret == -1)
+               {
+                       SECURE_LOGE("unable to remove the insert_map_file. errno = %d", errno);
+               }
+       }
+       bundle_free(b);
+       return ret;
+}
+
+int
+datacontrol_sql_delete(datacontrol_h provider, const char *where, int *request_id)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       const char* arg_list[2];
+       arg_list[0] = provider->data_id;
+
+       if (where)
+       {
+               arg_list[1] = where;
+       }
+       else
+       {
+               arg_list[1] = DATACONTROL_EMPTY;
+       }
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, 2);
+
+       // Set the request id
+       int reqId = _datacontrol_create_request_id();
+       *request_id = reqId;
+
+       int ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_DELETE, b, reqId);
+       bundle_free(b);
+       return ret;
+}
+
+int
+datacontrol_sql_select(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id)
+{
+       return datacontrol_sql_select_with_page(provider, column_list, column_count, where, order, 1, 20, request_id);
+}
+
+int
+datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGI("SQL data control, select to provider_id: %s, data_id: %s, col_count: %d, where: %s, order: %s, page_number: %d, per_page: %d", provider->provider_id, provider->data_id, column_count, where, order, page_number, count_per_page);
+
+       if (column_list == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       int total_arg_count = -1;
+       int ret = 0;
+
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       char page[32] = {0, };
+       ret = snprintf(page, 32, "%d", page_number);
+       if (ret < 0)
+       {
+               LOGE("unable to convert page no to string: %d", errno);
+               bundle_free(b);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       char count_per_page_no[32] = {0, };
+       ret = snprintf(count_per_page_no, 32, "%d", count_per_page);
+       if (ret < 0)
+       {
+               LOGE("unable to convert count per page no to string: %d", errno);
+               bundle_free(b);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       total_arg_count = column_count + DATACONTROL_SELECT_EXTRA_COUNT;
+       const char** arg_list = (const char**)malloc(total_arg_count * (sizeof(char *)));
+
+       LOGI("total arg count %d", total_arg_count);
+
+       arg_list[0] = provider->data_id; // arg[0]: data ID
+       int i = 1;
+       if (column_list)
+       {
+               char select_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, };
+               ret = snprintf(select_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", column_count);
+               if(ret < 0)
+               {
+                       LOGE("unable to convert select col count to string: %d", errno);
+                       free(arg_list);
+                       bundle_free(b);
+                       return DATACONTROL_ERROR_IO_ERROR;
+               }
+
+
+               arg_list[i] = select_column_count; // arg[1]: selected column count
+
+               ++i;
+               int select_col = 0;
+               while (select_col < column_count)
+               {
+                       arg_list[i++] = column_list[select_col++];
+               }
+       }
+       else
+       {
+               arg_list[i++] = DATACONTROL_EMPTY;
+       }
+
+       if (where)      // arg: where clause
+       {
+               arg_list[i++] = where;
+       }
+       else
+       {
+               arg_list[i++] = DATACONTROL_EMPTY;
+       }
+
+       if (order)      // arg: order clause
+       {
+               arg_list[i++] = order;
+       }
+       else
+       {
+               arg_list[i++] = DATACONTROL_EMPTY;
+       }
+
+
+       arg_list[i++] = page;  // arg: page number
+
+       arg_list[i] = count_per_page_no;  // arg: count per page
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, total_arg_count);
+       free(arg_list);
+
+       int reqId = _datacontrol_create_request_id();
+       *request_id = reqId;
+
+       ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_SELECT, b, reqId);
+       bundle_free(b);
+       return ret;
+}
+
+
+int
+datacontrol_sql_update(datacontrol_h provider, const bundle* update_data, const char *where, int *request_id)
+{
+       if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || update_data == NULL || where == NULL)
+       {
+               LOGE("Invalid parameter");
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = 0;
+
+       char caller_app_id[256] = {0, };
+       pid_t pid = getpid();
+
+       if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0)
+       {
+               SECURE_LOGE("Failed to get appid by pid(%d).", pid);
+               return DATACONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       // Check size of arguments
+       long long arg_size = 0;
+       bundle_foreach((bundle*)update_data, bundle_foreach_check_arg_size_cb, &arg_size);
+       arg_size += strlen(provider->data_id) * sizeof(wchar_t);
+       if (arg_size > MAX_REQUEST_ARGUMENT_SIZE)
+       {
+               LOGE("The size of the request argument exceeds the limit, 1M.");
+               return DATACONTROL_ERROR_MAX_EXCEEDED;
+       }
+
+       int reqId = _datacontrol_create_request_id();
+
+       char update_map_file[REQUEST_PATH_MAX] = {0, };
+       ret = snprintf(update_map_file, REQUEST_PATH_MAX, "%s/%s_%d", DATACONTROL_REQUEST_FILE_PREFIX, caller_app_id, reqId);
+       if (ret < 0)
+       {
+               LOGE("unable to write formatted output to update_map_file: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       SECURE_LOGI("update_map_file : %s", update_map_file);
+
+       int fd = 0;
+       char *provider_pkgid = __get_provider_pkgid(provider->provider_id);
+
+       /* TODO - shoud be changed to solve security concerns */
+       fd = open(update_map_file, O_WRONLY | O_CREAT, 644);
+       if (fd == -1)
+       {
+               SECURE_LOGE("unable to open update_map file: %d", errno);
+               free(provider_pkgid);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       free(provider_pkgid);
+
+       int count = bundle_get_count((bundle*)update_data);
+       bundle_foreach((bundle*)update_data, bundle_foreach_cb, &fd);
+
+       fsync(fd);
+       close(fd);
+
+       bundle *b = bundle_create();
+       if (!b)
+       {
+               LOGE("unable to create bundle: %d", errno);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+       bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+       char update_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, };
+       ret = snprintf(update_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", count);
+       if (ret < 0)
+       {
+               LOGE("unable to convert update col count to string: %d", errno);
+               bundle_free(b);
+               return DATACONTROL_ERROR_IO_ERROR;
+       }
+
+       const char* arg_list[4];
+       arg_list[0] = provider->data_id; // list(0): data ID
+       arg_list[1] = update_column_count;
+       arg_list[2] = update_map_file;
+       arg_list[3] = where;
+
+       bundle_add_str_array(b, OSP_K_ARG, arg_list, 4);
+
+       *request_id = reqId;
+
+       ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_UPDATE, b, reqId);
+       if (ret != DATACONTROL_ERROR_NONE)
+       {
+               ret = remove(update_map_file);
+               if (ret == -1)
+               {
+                       SECURE_LOGE("unable to remove the update_map file: %d", errno);
+               }
+       }
+       bundle_free(b);
+       return ret;
+}
diff --git a/src/data_control_internal.c b/src/data_control_internal.c
new file mode 100644 (file)
index 0000000..e5ef1b1
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+#include <dlog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <unistd.h>
+
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include "data_control_internal.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_DATA_CONTROL"
+
+#define _LOGE(fmt, arg...) LOGE(fmt,##arg)
+#define _LOGD(fmt, arg...) LOGD(fmt, ##arg)
+
+static const char *data_control_error_to_string(data_control_error_e error)
+{
+       switch (error) {
+               case DATA_CONTROL_ERROR_NONE:
+                       return "NONE";
+               case DATA_CONTROL_ERROR_INVALID_PARAMETER:
+                       return "INVALID_PARAMETER";
+               case DATA_CONTROL_ERROR_OUT_OF_MEMORY:
+                       return "OUT_OF_MEMORY";
+               case DATA_CONTROL_ERROR_IO_ERROR:
+                       return "IO_ERROR";
+               case DATA_CONTROL_ERROR_PERMISSION_DENIED:
+                       return "PERMISSION_DENIED";
+               case DATA_CONTROL_ERROR_MAX_EXCEEDED:
+                       return "Too long argument";
+               default:
+                       return "UNKNOWN";
+       }
+}
+
+int convert_to_tizen_error(datacontrol_error_e error)
+{
+       switch (error) {
+               case DATACONTROL_ERROR_NONE:
+                       return DATA_CONTROL_ERROR_NONE;
+               case DATACONTROL_ERROR_INVALID_PARAMETER:
+                       return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+               case DATACONTROL_ERROR_OUT_OF_MEMORY:
+                       return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+               case DATACONTROL_ERROR_IO_ERROR:
+                       return DATA_CONTROL_ERROR_IO_ERROR;
+               case DATACONTROL_ERROR_PERMISSION_DENIED:
+                       return DATA_CONTROL_ERROR_PERMISSION_DENIED;
+               case DATACONTROL_ERROR_MAX_EXCEEDED:
+                       return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+               default:
+                       return error;
+       }
+}
+
+int data_control_error(data_control_error_e error,
+               const char *function, const char *description)
+{
+       if (description) {
+               _LOGE("[%s] %s(0x%08x) : %s", function,
+                               data_control_error_to_string(error), error,
+                               description);
+       } else {
+               _LOGE("[%s] %s(0x%08x)", function,
+                               data_control_error_to_string(error), error);
+       }
+
+       return error;
+}
+
diff --git a/src/data_control_log.h b/src/data_control_log.h
new file mode 100644 (file)
index 0000000..29165fc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+#ifndef __TIZEN_APPFW_DATA_CONTROL_LOG_H__
+#define __TIZEN_APPFW_DATA_CONTROL_LOG_H__
+
+#include <dlog.h>
+
+#ifdef __GNUC__
+#   ifndef EXPORT_API
+#       define EXPORT_API __attribute__((visibility("default")))
+#   endif
+#else
+#   define EXPORT_API
+#endif
+
+#undef LOG_TAG
+#define LOG_TAG "DATA_CONTROL"
+
+#define _LOGE(fmt, arg...) LOGE(fmt, ##arg)
+#define _LOGI(fmt, arg...) LOGI(fmt, ##arg)
+
+#define _SECURE_LOGE(fmt, arg...) SECURE_LOGE(fmt, ##arg)
+#define _SECURE_LOGI(fmt, arg...) SECURE_LOGI(fmt, ##arg)
+
+#endif /* __TIZEN_APPFW_DATA_CONTROL_LOG_H__ */
diff --git a/src/data_control_map.c b/src/data_control_map.c
new file mode 100644 (file)
index 0000000..99258d6
--- /dev/null
@@ -0,0 +1,207 @@
+#include <dlog.h>
+#include <bundle.h>
+#include <errno.h>
+#include <glib.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <data-control-map.h>
+#include "data_control_internal.h"
+#include "data_control_map.h"
+#include "data_control_log.h"
+
+struct data_control_s {
+       char *provider_id;
+       char *data_id;
+};
+
+struct datacontrol_s {
+       char *provider_id;
+       char *data_id;
+};
+
+
+static GHashTable *response_table = NULL;
+
+datacontrol_map_response_cb datacontrol_map_cb;
+
+void
+__map_get_response(int request_id, datacontrol_h provider,
+               char **result_value_list, int result_value_count, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("map_get_response");
+
+       data_control_map_response_cb *callback = (data_control_map_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->get_cb(request_id, (data_control_h)provider, result_value_list, result_value_count, provider_result, error, user_data);
+       }
+}
+
+void
+__map_set_response(int request_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("map_set_response");
+
+       data_control_map_response_cb *callback = (data_control_map_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->set_cb(request_id, (data_control_h)provider, provider_result, error, user_data);
+       }
+}
+
+void
+__map_add_response(int request_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("map_add_response");
+
+       data_control_map_response_cb *callback = (data_control_map_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->add_cb(request_id, (data_control_h)provider, provider_result, error, user_data);
+       }
+}
+
+void
+__map_remove_response(int request_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("map_remove_response");
+
+       data_control_map_response_cb *callback = (data_control_map_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->remove_cb(request_id, (data_control_h)provider, provider_result, error, user_data);
+       }
+}
+
+static void
+__free_data(gpointer data)
+{
+       if (data)
+       {
+               g_free(data);
+               data = NULL;
+       }
+}
+
+static void
+__initialize(void)
+{
+       response_table = g_hash_table_new_full(g_str_hash, g_str_equal, __free_data, __free_data);
+
+       datacontrol_map_cb.get = __map_get_response;
+       datacontrol_map_cb.set = __map_set_response;
+       datacontrol_map_cb.add = __map_add_response;
+       datacontrol_map_cb.remove = __map_remove_response;
+}
+
+EXPORT_API int
+data_control_map_create(data_control_h *provider)
+{
+       return convert_to_tizen_error(datacontrol_map_create((datacontrol_h*)provider));
+}
+
+EXPORT_API int
+data_control_map_destroy(data_control_h provider)
+{
+       return convert_to_tizen_error(datacontrol_map_destroy((datacontrol_h)provider));
+}
+
+EXPORT_API int
+data_control_map_set_provider_id(data_control_h provider, const char *provider_id)
+{
+       return convert_to_tizen_error(datacontrol_map_set_provider_id((datacontrol_h)provider, provider_id));
+}
+
+EXPORT_API int
+data_control_map_get_provider_id(data_control_h provider, char **provider_id)
+{
+       return convert_to_tizen_error(datacontrol_map_get_provider_id((datacontrol_h)provider, provider_id));
+}
+
+EXPORT_API int
+data_control_map_set_data_id(data_control_h provider, const char *data_id)
+{
+       return convert_to_tizen_error(datacontrol_map_set_data_id((datacontrol_h)provider, data_id));
+}
+
+EXPORT_API int
+data_control_map_get_data_id(data_control_h provider, char **data_id)
+{
+       return convert_to_tizen_error(datacontrol_map_get_data_id((datacontrol_h)provider, data_id));
+}
+
+EXPORT_API int
+data_control_map_register_response_cb(data_control_h provider, data_control_map_response_cb* callback, void *user_data)
+{
+
+       if (response_table == NULL)
+       {
+               __initialize();
+       }
+
+       if (callback == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       char *id = strdup(provider->provider_id);
+       if (id == NULL)
+       {
+               return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       data_control_map_response_cb *cb
+               = (data_control_map_response_cb *)malloc(sizeof(data_control_map_response_cb));
+       if (cb == NULL)
+       {
+               free(id);
+               return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       memcpy(cb, callback, sizeof(data_control_map_response_cb));
+       g_hash_table_insert(response_table, id, cb);
+
+       return convert_to_tizen_error(datacontrol_map_register_response_cb((datacontrol_h)provider, &datacontrol_map_cb, user_data));
+}
+
+EXPORT_API int
+data_control_map_unregister_response_cb(data_control_h provider)
+{
+       if (provider->provider_id)
+       {
+               g_hash_table_remove(response_table, provider->provider_id);
+       }
+
+       return convert_to_tizen_error(datacontrol_map_unregister_response_cb((datacontrol_h)provider));
+}
+
+EXPORT_API int
+data_control_map_get(data_control_h provider, const char *key, int *request_id)
+{
+       return convert_to_tizen_error(datacontrol_map_get((datacontrol_h)provider, key, request_id));
+}
+
+EXPORT_API int
+data_control_map_get_with_page(data_control_h provider, const char *key, int *request_id, int page_number, int count_per_page)
+{
+       return convert_to_tizen_error(datacontrol_map_get_with_page((datacontrol_h)provider, key, request_id, page_number, count_per_page));
+}
+
+EXPORT_API int
+data_control_map_set(data_control_h provider, const char *key, const char *old_value, const char *new_value, int *request_id)
+{
+       return convert_to_tizen_error(datacontrol_map_set((datacontrol_h)provider, key, old_value, new_value, request_id));
+}
+
+EXPORT_API int
+data_control_map_add(data_control_h provider, const char *key, const char *value, int *request_id)
+{
+       return convert_to_tizen_error(datacontrol_map_add((datacontrol_h)provider, key, value, request_id));
+}
+
+EXPORT_API int
+data_control_map_remove(data_control_h provider, const char *key, const char *value, int *request_id)
+{
+       return convert_to_tizen_error(datacontrol_map_remove((datacontrol_h)provider, key, value, request_id));
+}
diff --git a/src/data_control_provider.c b/src/data_control_provider.c
new file mode 100644 (file)
index 0000000..e58d3dd
--- /dev/null
@@ -0,0 +1,616 @@
+#include <stdlib.h>
+
+#include <dlog.h>
+#include <bundle.h>
+
+#include <data-control-provider.h>
+
+#include "data_control_provider.h"
+#include "data_control_sql.h"
+#include "data_control_log.h"
+#include "data_control_internal.h"
+
+#define INSERT_STMT_CONST_LEN 25
+#define DELETE_STMT_CONST_LEN 12
+#define UPDATE_STMT_CONST_LEN 15
+#define SELECT_STMT_CONST_LEN 13
+#define WHERE_COND_CONST_LEN 7
+#define ORDER_CLS_CONST_LEN 10
+
+struct data_control_s {
+       char *provider_id;
+       char *data_id;
+};
+
+struct datacontrol_s {
+       char *provider_id;
+       char *data_id;
+};
+
+typedef struct
+{
+       int no_of_elements;
+       int length;
+       char** keys;
+       char** vals;
+}key_val_pair;
+
+static data_control_provider_sql_cb sql_provider_callback;
+static data_control_provider_map_cb map_provider_callback;
+
+datacontrol_provider_sql_cb sql_internal_callback;
+datacontrol_provider_map_cb map_internal_callback;
+
+void
+__sql_insert_request_cb(int request_id, datacontrol_h provider, bundle *insert_data, void *user_data)
+{
+       _LOGI("sql_insert_request");
+
+       if (sql_provider_callback.insert_cb)
+       {
+               sql_provider_callback.insert_cb(request_id, (data_control_h)provider, insert_data, user_data);
+       }
+}
+
+void
+__sql_update_request_cb(int request_id, datacontrol_h provider, bundle *update_data, const char *where, void *user_data)
+{
+       _LOGI("sql_update_request");
+
+       if (sql_provider_callback.update_cb)
+       {
+               sql_provider_callback.update_cb(request_id, (data_control_h)provider, update_data, where, user_data);
+       }
+}
+
+void
+__sql_delete_request_cb(int request_id, datacontrol_h provider, const char *where, void *user_data)
+{
+       _LOGI("sql_delete_request");
+
+       if (sql_provider_callback.delete_cb)
+       {
+               sql_provider_callback.delete_cb(request_id, (data_control_h)provider, where, user_data);
+       }
+}
+
+void
+__sql_select_request_cb(int request_id, datacontrol_h provider, const char **column_list, int column_count, const char *where, const char *order, void *user_data)
+{
+       _LOGI("sql_select_request");
+
+       if (sql_provider_callback.select_cb)
+       {
+               sql_provider_callback.select_cb(request_id, (data_control_h)provider, column_list, column_count, where, order, user_data);
+       }
+}
+
+void
+__map_get_request_cb(int request_id, datacontrol_h provider, const char *key, void *user_data)
+{
+       _LOGI("map_get_request");
+
+       if (map_provider_callback.get_cb)
+       {
+               map_provider_callback.get_cb(request_id, (data_control_h)provider, key, user_data);
+       }
+}
+
+void
+__map_set_request_cb(int request_id, datacontrol_h provider, const char *key, const char *old_value, const char *new_value, void *user_data)
+{
+       _LOGI("map_set_request");
+
+       if (map_provider_callback.set_cb)
+       {
+               map_provider_callback.set_cb(request_id, (data_control_h)provider, key, old_value, new_value, user_data);
+       }
+}
+
+void
+__map_add_request_cb(int request_id, datacontrol_h provider, const char *key, const char *value, void *user_data)
+{
+       _LOGI("map_add_request");
+
+       if (map_provider_callback.add_cb)
+       {
+               map_provider_callback.add_cb(request_id, (data_control_h)provider, key, value, user_data);
+       }
+}
+
+void
+__map_remove_request_cb(int request_id, datacontrol_h provider, const char *key, const char *value, void *user_data)
+{
+       _LOGI("map_remove_request");
+
+       if (map_provider_callback.remove_cb)
+       {
+               map_provider_callback.remove_cb(request_id, (data_control_h)provider, key, value, user_data);
+       }
+}
+
+EXPORT_API int
+data_control_provider_sql_register_cb(data_control_provider_sql_cb *callback, void *user_data)
+{
+       if (!callback)
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+       sql_provider_callback = *callback;
+
+       sql_internal_callback.insert = __sql_insert_request_cb;
+       sql_internal_callback.update = __sql_update_request_cb;
+       sql_internal_callback.delete = __sql_delete_request_cb;
+       sql_internal_callback.select = __sql_select_request_cb;
+
+       return datacontrol_provider_sql_register_cb(&sql_internal_callback, user_data);
+}
+
+EXPORT_API int
+data_control_provider_sql_unregister_cb(void)
+{
+       memset(&sql_provider_callback, 0, sizeof(data_control_provider_sql_cb));
+
+       return datacontrol_provider_sql_unregister_cb();
+}
+
+EXPORT_API int
+data_control_provider_map_register_cb(data_control_provider_map_cb *callback, void *user_data)
+{
+       if (!callback)
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+       map_provider_callback = *callback;
+
+       map_internal_callback.get = __map_get_request_cb;
+       map_internal_callback.set = __map_set_request_cb;
+       map_internal_callback.add = __map_add_request_cb;
+       map_internal_callback.remove = __map_remove_request_cb;
+
+       return datacontrol_provider_map_register_cb(&map_internal_callback, user_data);
+}
+
+EXPORT_API int
+data_control_provider_map_unregister_cb(void)
+{
+       memset(&map_provider_callback, 0, sizeof(data_control_provider_map_cb));
+
+       return datacontrol_provider_map_unregister_cb();
+}
+
+EXPORT_API int
+data_control_provider_get_client_appid(int request_id, char **appid)
+{
+       return datacontrol_provider_get_client_appid(request_id, appid);
+}
+
+EXPORT_API int
+data_control_provider_send_select_result(int request_id, void *db_handle)
+{
+       return datacontrol_provider_send_select_result(request_id, db_handle);
+}
+
+EXPORT_API int
+data_control_provider_send_insert_result(int request_id, long long row_id)
+{
+       return datacontrol_provider_send_insert_result(request_id, row_id);
+}
+
+EXPORT_API int
+data_control_provider_send_update_result(int request_id)
+{
+       return datacontrol_provider_send_update_result(request_id);
+}
+
+EXPORT_API int
+data_control_provider_send_delete_result(int request_id)
+{
+       return datacontrol_provider_send_delete_result(request_id);
+}
+
+EXPORT_API int
+data_control_provider_send_error(int request_id, const char *error)
+{
+       return datacontrol_provider_send_error(request_id, error);
+}
+
+static void bundle_foreach_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
+{
+       if (!key || !kv || !user_data)
+       {
+               return;
+       }
+
+       key_val_pair* pair = (key_val_pair *)user_data;
+       int index = pair->no_of_elements;
+
+       pair->keys[index] = strdup(key);
+
+       char *value = NULL;
+       size_t value_len = 0;
+
+       bundle_keyval_get_basic_val((bundle_keyval_t *)kv, (void**)&value, &value_len);
+       pair->vals[index] = strdup(value);
+       pair->length += strlen(key) + value_len;
+
+       ++(pair->no_of_elements);
+
+       return;
+}
+
+EXPORT_API char*
+data_control_provider_create_insert_statement(data_control_h provider, bundle *insert_map)
+{
+       int row_count = bundle_get_count(insert_map);
+       if (provider == NULL || row_count == 0)
+       {
+               set_last_result(DATA_CONTROL_ERROR_INVALID_PARAMETER);
+               return NULL;
+       }
+
+       key_val_pair *cols = (key_val_pair *) calloc(sizeof(key_val_pair), 1);
+       if (cols == NULL)
+       {
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+
+       cols->no_of_elements = 0;
+       cols->length = 0;
+       cols->keys = (char **) calloc(sizeof(char *), row_count);
+       if (cols->keys == NULL)
+       {
+               free(cols);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+
+       cols->vals = (char **) calloc(sizeof(char *), row_count);
+       if (cols->vals == NULL)
+       {
+               free(cols->keys);
+               free(cols);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+
+       int index = 0;
+       bundle_foreach(insert_map, bundle_foreach_cb, (void*)(cols));
+
+       char* data_id = NULL;
+       data_control_sql_get_data_id(provider, &data_id);
+
+       int sql_len = INSERT_STMT_CONST_LEN + strlen(data_id) + (row_count - 1) * 4 + (cols->length) + 1;
+
+       _LOGI("SQL statement length: %d", sql_len);
+
+       char* sql = (char *) calloc(sizeof(char), sql_len);
+       if (sql == NULL)
+       {
+               free(data_id);
+               free(cols->keys);
+               free(cols->vals);
+               free(cols);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+       memset(sql, 0, sql_len);
+
+       sprintf(sql, "INSERT INTO %s (", data_id);
+       free(data_id);
+
+       for(index = 0; index < row_count - 1; index++)
+       {
+               strcat(sql, cols->keys[index]);
+               strcat(sql, ", ");
+       }
+
+       strcat(sql, cols->keys[index]);
+       strcat(sql, ") VALUES (");
+
+       for(index = 0; index < row_count - 1; index++)
+       {
+               strcat(sql, cols->vals[index]);
+               strcat(sql, ", ");
+       }
+
+       strcat(sql, cols->vals[index]);
+       strcat(sql, ")");
+
+       _LOGI("SQL statement is: %s", sql);
+
+       for(index = 0; index < row_count; index++)
+       {
+               free(cols->keys[index]);
+               free(cols->vals[index]);
+       }
+       free(cols->keys);
+       free(cols->vals);
+       free(cols);
+
+       return sql;
+}
+
+EXPORT_API char*
+data_control_provider_create_delete_statement(data_control_h provider, const char *where)
+{
+       char* data_id = NULL;
+
+       if (provider == NULL)
+       {
+               set_last_result(DATA_CONTROL_ERROR_INVALID_PARAMETER);
+               return NULL;
+       }
+
+       data_control_sql_get_data_id(provider, &data_id);
+
+       int cond_len = (where != NULL) ? (WHERE_COND_CONST_LEN + strlen(where)) : 0;
+       int sql_len = DELETE_STMT_CONST_LEN + strlen(data_id) + cond_len + 1;
+
+       _LOGI("SQL statement length: %d", sql_len);
+
+       char* sql = (char *) calloc(sizeof(char), sql_len);
+       if (sql == NULL)
+       {
+               free(data_id);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+       memset(sql, 0, sql_len);
+
+       sprintf(sql, "DELETE FROM %s", data_id);
+       if (where)
+       {
+               strcat(sql, " WHERE ");
+               strcat(sql, where);
+       }
+
+       _LOGI("SQL statement is: %s", sql);
+
+       free(data_id);
+       return sql;
+}
+
+EXPORT_API char*
+data_control_provider_create_update_statement(data_control_h provider, bundle *update_map, const char *where)
+{
+       int row_count = bundle_get_count(update_map);
+       if (provider == NULL || row_count == 0)
+       {
+               set_last_result(DATA_CONTROL_ERROR_INVALID_PARAMETER);
+               return NULL;
+       }
+
+       key_val_pair *cols = (key_val_pair *) calloc(sizeof(key_val_pair), 1);
+       if (cols == NULL)
+       {
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+
+       cols->no_of_elements = 0;
+       cols->length = 0;
+       cols->keys = (char **) calloc(sizeof(char *), row_count);
+       if (cols->keys == NULL)
+       {
+               free(cols);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+       cols->vals = (char **) calloc(sizeof(char *), row_count);
+       if (cols->vals == NULL)
+       {
+               free(cols->keys);
+               free(cols);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+
+       int index = 0;
+       bundle_foreach(update_map, bundle_foreach_cb, (void*)(cols));
+
+       char* data_id = NULL;
+       data_control_sql_get_data_id(provider, &data_id);
+
+       int cond_len = (where != NULL) ? (WHERE_COND_CONST_LEN + strlen(where)) : 0;
+       int sql_len = UPDATE_STMT_CONST_LEN + strlen(data_id) + (cols->length) + (row_count - 1) * 5 + cond_len + 1;
+
+       _LOGI("SQL statement length: %d", sql_len);
+
+       char* sql = (char *) calloc(sizeof(char), sql_len);
+       if (sql == NULL)
+       {
+               free(data_id);
+               free(cols->keys);
+               free(cols->vals);
+               free(cols);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+       memset(sql, 0, sql_len);
+
+       sprintf(sql, "UPDATE %s SET ", data_id);
+       free(data_id);
+
+       for(index = 0; index < row_count - 1; index++)
+       {
+               strcat(sql, cols->keys[index]);
+               strcat(sql, " = ");
+               strcat(sql, cols->vals[index]);
+               strcat(sql, ", ");
+       }
+
+       strcat(sql, cols->keys[index]);
+       strcat(sql, " = ");
+       strcat(sql, cols->vals[index]);
+
+       if (where)
+       {
+               strcat(sql, " WHERE ");
+               strcat(sql, where);
+       }
+
+       _LOGI("SQL statement is: %s", sql);
+
+       for(index = 0; index < row_count; index++)
+       {
+               free(cols->keys[index]);
+               free(cols->vals[index]);
+       }
+       free(cols->keys);
+       free(cols->vals);
+       free(cols);
+
+       return sql;
+}
+
+EXPORT_API char*
+data_control_provider_create_select_statement(data_control_h provider, const char **column_list, int column_count, const char *where, const char *order)
+{
+       int index = 0;
+       int col_name_length = 0;
+       if (provider == NULL)
+       {
+               set_last_result(DATA_CONTROL_ERROR_INVALID_PARAMETER);
+               return NULL;
+       }
+
+       if (column_list)
+       {
+               for (index = 0; index < column_count; index++)
+               {
+                       col_name_length += strlen(column_list[index]);
+               }
+               if (column_count > 0)
+               {
+                       col_name_length += (column_count - 1) * 2;
+               }
+       }
+       else
+       {
+               col_name_length = 1;
+       }
+
+       char* data_id = NULL;
+       data_control_sql_get_data_id(provider, &data_id);
+
+       int cond_len = (where != NULL) ? (WHERE_COND_CONST_LEN + strlen(where)) : 0;
+       int order_len = (order != NULL) ? (ORDER_CLS_CONST_LEN + strlen(order)) : 0;
+       int sql_len = SELECT_STMT_CONST_LEN + col_name_length + strlen(data_id) + cond_len + order_len + 1;
+
+       _LOGI("SQL statement length: %d", sql_len);
+
+       char* sql = (char *) calloc(sizeof(char), sql_len);
+       if (sql == NULL)
+       {
+               free(data_id);
+               set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY);
+               return NULL;
+       }
+       memset(sql, 0, sql_len);
+
+       strcpy(sql, "SELECT ");
+       if (!column_list)
+       {
+               strcat(sql, "*");
+       }
+       else
+       {
+               for (index = 0; index < column_count - 1; index++)
+               {
+                       strcat(sql, column_list[index]);
+                       strcat(sql, ", ");
+               }
+               strcat(sql, column_list[index]);
+       }
+
+       strcat(sql, " FROM ");
+       strcat(sql, data_id);
+
+       if (where)
+       {
+               strcat(sql, " WHERE ");
+               strcat(sql, where);
+       }
+       if (order)
+       {
+               strcat(sql, " ORDER BY ");
+               strcat(sql, order);
+       }
+
+       _LOGI("SQL statement is: %s", sql);
+
+       free(data_id);
+       return sql;
+}
+
+EXPORT_API bool
+data_control_provider_match_provider_id(data_control_h provider, const char *provider_id)
+{
+       int ret = DATA_CONTROL_ERROR_NONE;
+       char* prov_id = NULL;
+       if(provider == NULL || provider_id == NULL)
+       {
+               set_last_result(DATA_CONTROL_ERROR_INVALID_PARAMETER);
+               return false;
+       }
+
+       ret = data_control_sql_get_provider_id(provider, &prov_id);
+       set_last_result(ret);
+       if (ret != DATA_CONTROL_ERROR_NONE)
+       {
+               return false;
+       }
+
+       if (strcmp(prov_id, provider_id) == 0)
+       {
+               free(prov_id);
+               return true;
+       }
+       else
+       {
+               free(prov_id);
+               return false;
+       }
+}
+
+EXPORT_API bool
+data_control_provider_match_data_id(data_control_h provider, const char *data_id)
+{
+       int ret = DATA_CONTROL_ERROR_NONE;
+       char* data = NULL;
+       if(provider == NULL || data_id == NULL)
+       {
+               set_last_result(DATA_CONTROL_ERROR_INVALID_PARAMETER);
+               return false;
+       }
+
+       ret = data_control_sql_get_data_id(provider, &data);
+       set_last_result(ret);
+       if (ret != DATA_CONTROL_ERROR_NONE)
+       {
+               return false;
+       }
+
+       if (strcmp(data, data_id) == 0)
+       {
+               free(data);
+               return true;
+       }
+       else
+       {
+               free(data);
+               return false;
+       }
+}
+
+EXPORT_API int
+data_control_provider_send_map_result(int request_id)
+{
+       return datacontrol_provider_send_map_result(request_id);
+}
+
+EXPORT_API int
+data_control_provider_send_map_get_value_result(int request_id, char **value_list, int value_count)
+{
+       return datacontrol_provider_send_map_get_value_result(request_id, value_list, value_count);
+}
diff --git a/src/data_control_sql.c b/src/data_control_sql.c
new file mode 100644 (file)
index 0000000..72ff21e
--- /dev/null
@@ -0,0 +1,207 @@
+#include <dlog.h>
+#include <bundle.h>
+#include <errno.h>
+#include <glib.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <data-control-sql.h>
+#include "data_control_internal.h"
+#include "data_control_sql.h"
+#include "data_control_log.h"
+
+struct data_control_s {
+       char *provider_id;
+       char *data_id;
+};
+
+struct datacontrol_s {
+       char *provider_id;
+       char *data_id;
+};
+
+
+static GHashTable *response_table = NULL;
+
+datacontrol_sql_response_cb datacontrol_sql_cb;
+
+void
+__sql_insert_response(int req_id, datacontrol_h provider, long long insert_rowid, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("sql_insert_response");
+
+       data_control_sql_response_cb *callback = (data_control_sql_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->insert_cb(req_id, (data_control_h)provider, insert_rowid, provider_result, error, user_data);
+       }
+}
+
+void
+__sql_update_response(int req_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("sql_update_response");
+
+       data_control_sql_response_cb *callback = (data_control_sql_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->update_cb(req_id, (data_control_h)provider, provider_result, error, user_data);
+       }
+}
+
+void
+__sql_delete_response(int req_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("sql_delete_response");
+
+       data_control_sql_response_cb *callback = (data_control_sql_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->delete_cb(req_id, (data_control_h)provider, provider_result, error, user_data);
+       }
+}
+
+void
+__sql_select_response(int req_id, datacontrol_h provider, resultset_cursor* enumerator, bool provider_result, const char *error, void *user_data)
+{
+       _LOGI("sql_select_response");
+
+       data_control_sql_response_cb *callback = (data_control_sql_response_cb*)g_hash_table_lookup(response_table, provider->provider_id);
+       if (callback)
+       {
+               callback->select_cb(req_id, (data_control_h)provider, (result_set_cursor)enumerator, provider_result, error, user_data);
+       }
+}
+
+static void
+__free_data(gpointer data)
+{
+       if (data)
+       {
+               g_free(data);
+               data = NULL;
+       }
+}
+
+static void
+__initialize(void)
+{
+       response_table = g_hash_table_new_full(g_str_hash, g_str_equal, __free_data, __free_data);
+
+       datacontrol_sql_cb.insert = __sql_insert_response;
+       datacontrol_sql_cb.delete = __sql_delete_response;
+       datacontrol_sql_cb.select = __sql_select_response;
+       datacontrol_sql_cb.update = __sql_update_response;
+}
+
+EXPORT_API int
+data_control_sql_create(data_control_h *provider)
+{
+       return datacontrol_sql_create((datacontrol_h*)provider);
+}
+
+EXPORT_API int
+data_control_sql_destroy(data_control_h provider)
+{
+       return datacontrol_sql_destroy((datacontrol_h)provider);
+}
+
+EXPORT_API int
+data_control_sql_set_provider_id(data_control_h provider, const char *provider_id)
+{
+       return datacontrol_sql_set_provider_id((datacontrol_h)provider, provider_id);
+}
+
+EXPORT_API int
+data_control_sql_get_provider_id(data_control_h provider, char **provider_id)
+{
+       return datacontrol_sql_get_provider_id((datacontrol_h)provider, provider_id);
+}
+
+EXPORT_API int
+data_control_sql_set_data_id(data_control_h provider, const char *data_id)
+{
+       return datacontrol_sql_set_data_id((datacontrol_h)provider, data_id);
+}
+
+EXPORT_API int
+data_control_sql_get_data_id(data_control_h provider, char **data_id)
+{
+       return datacontrol_sql_get_data_id((datacontrol_h)provider, data_id);
+}
+
+EXPORT_API int
+data_control_sql_register_response_cb(data_control_h provider, data_control_sql_response_cb* callback, void *user_data)
+{
+       if (response_table == NULL)
+       {
+               __initialize();
+       }
+
+       if (callback == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+
+       char *id = strdup(provider->provider_id);
+       if (id == NULL)
+       {
+               return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       data_control_sql_response_cb *cb
+               = (data_control_sql_response_cb *)malloc(sizeof(data_control_sql_response_cb));
+       if (cb == NULL)
+       {
+               free(id);
+               return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+       }
+
+       memcpy(cb, callback, sizeof(data_control_sql_response_cb));
+       g_hash_table_insert(response_table, id, cb);
+
+       return datacontrol_sql_register_response_cb((datacontrol_h)provider, &datacontrol_sql_cb, user_data);
+}
+
+EXPORT_API int
+data_control_sql_unregister_response_cb(data_control_h provider)
+{
+       if (provider->provider_id)
+       {
+               g_hash_table_remove(response_table, provider->provider_id);
+       }
+
+       return datacontrol_sql_unregister_response_cb((datacontrol_h)provider);
+}
+
+EXPORT_API int
+data_control_sql_insert(data_control_h provider, const bundle* insert_data, int *request_id)
+{
+       return datacontrol_sql_insert((datacontrol_h)provider, insert_data, request_id);
+}
+
+EXPORT_API int
+data_control_sql_delete(data_control_h provider, const char *where, int *request_id)
+{
+       return datacontrol_sql_delete((datacontrol_h)provider, where, request_id);
+}
+
+EXPORT_API int
+data_control_sql_select(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id)
+{
+       return datacontrol_sql_select((datacontrol_h)provider, column_list, column_count, where, order, request_id);
+}
+
+EXPORT_API int
+data_control_sql_select_with_page(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id)
+{
+       return datacontrol_sql_select_with_page((datacontrol_h)provider, column_list, column_count, where, order, page_number, count_per_page, request_id);
+}
+
+
+EXPORT_API int
+data_control_sql_update(data_control_h provider, const bundle* update_data, const char *where, int *request_id)
+{
+       return datacontrol_sql_update((datacontrol_h)provider, update_data, where, request_id);
+}
+
diff --git a/src/data_control_sql_cursor.c b/src/data_control_sql_cursor.c
new file mode 100644 (file)
index 0000000..cd12bfb
--- /dev/null
@@ -0,0 +1,158 @@
+
+#include <dlog.h>
+#include <data-control-sql-cursor.h>
+
+#include "data_control_sql_cursor.h"
+
+struct result_set_s
+{
+       int result_set_fd;
+       int result_set_row_count;
+       int result_set_col_count;
+       int result_set_col_type_offset;
+       int result_set_col_name_offset;
+       int result_set_content_offset;
+       int result_set_current_offset;
+       int result_set_current_row_count;
+       char* result_set_path;
+};
+
+EXPORT_API int
+data_control_sql_step_next(result_set_cursor cursor)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_step_next((resultset_cursor*)cursor);
+}
+
+EXPORT_API int
+data_control_sql_step_last(result_set_cursor cursor)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_step_last((resultset_cursor*)cursor);
+}
+
+
+EXPORT_API int
+data_control_sql_step_first(result_set_cursor cursor)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_step_first((resultset_cursor*)cursor);
+}
+
+
+EXPORT_API int
+data_control_sql_step_previous(result_set_cursor cursor)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_step_previous((resultset_cursor*)cursor);
+}
+
+
+EXPORT_API int
+data_control_sql_get_column_count(result_set_cursor cursor)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_column_count((resultset_cursor*)cursor);
+}
+
+EXPORT_API int
+data_control_sql_get_column_name(result_set_cursor cursor, int column_index, char *name)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_column_name((resultset_cursor*)cursor, column_index, name);
+}
+
+
+EXPORT_API int
+data_control_sql_get_column_item_size(result_set_cursor cursor, int column_index)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_column_item_size((resultset_cursor*)cursor, column_index);
+}
+
+
+EXPORT_API int
+data_control_sql_get_column_item_type(result_set_cursor cursor, int column_index, data_control_sql_column_type_e* col_type)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_column_item_type((resultset_cursor*)cursor, column_index, (datacontrol_sql_column_type*)col_type);
+}
+
+
+EXPORT_API int
+data_control_sql_get_blob_data(result_set_cursor cursor, int column_index, void *buffer, int data_size)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_blob_data((resultset_cursor*)cursor, column_index, buffer, data_size);
+}
+
+
+EXPORT_API int
+data_control_sql_get_int_data(result_set_cursor cursor, int column_index, int *data)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_int_data((resultset_cursor*)cursor, column_index, data);
+}
+
+
+EXPORT_API int
+data_control_sql_get_int64_data(result_set_cursor cursor, int column_index, long long *data)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_int64_data((resultset_cursor*)cursor, column_index, data);
+}
+
+EXPORT_API int
+data_control_sql_get_double_data(result_set_cursor cursor, int column_index, double *data)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_double_data((resultset_cursor*)cursor, column_index, data);
+}
+
+
+EXPORT_API int
+data_control_sql_get_text_data(result_set_cursor cursor, int column_index, char *buffer)
+{
+       if (cursor == NULL)
+       {
+               return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+       }
+       return datacontrol_sql_get_text_data((resultset_cursor*)cursor, column_index, buffer);
+}
+