[Datacontrol] add datacontrol api
authorpius.lee <pius.lee@samsung.com>
Fri, 16 Jan 2015 05:32:23 +0000 (14:32 +0900)
committerpius.lee <pius.lee@samsung.com>
Fri, 16 Jan 2015 13:48:52 +0000 (22:48 +0900)
[Verification] Not Available TC. every method verified with self made app

Change-Id: I97307b1610b6b481933f189033f842e145f52061
Signed-off-by: pius.lee <pius.lee@samsung.com>
packaging/webapi-plugins.spec
src/datacontrol/datacontrol.gyp [new file with mode: 0644]
src/datacontrol/datacontrol_api.js [new file with mode: 0644]
src/datacontrol/datacontrol_extension.cc [new file with mode: 0644]
src/datacontrol/datacontrol_extension.h [new file with mode: 0644]
src/datacontrol/datacontrol_instance.cc [new file with mode: 0644]
src/datacontrol/datacontrol_instance.h [new file with mode: 0644]
src/tizen-wrt.gyp

index e4acca0..80e3b57 100644 (file)
@@ -171,6 +171,7 @@ BuildRequires: pkgconfig(capi-system-info)
 BuildRequires: pkgconfig(capi-system-runtime-info)
 BuildRequires: pkgconfig(capi-network-connection)
 BuildRequires: pkgconfig(capi-system-device)
+BuildRequires: pkgconfig(capi-data-control)
 BuildRequires: pkgconfig(capi-system-system-settings)
 BuildRequires: pkgconfig(capi-network-bluetooth)
 BuildRequires: pkgconfig(capi-network-wifi)
diff --git a/src/datacontrol/datacontrol.gyp b/src/datacontrol/datacontrol.gyp
new file mode 100644 (file)
index 0000000..7e82920
--- /dev/null
@@ -0,0 +1,27 @@
+{
+  'includes':[
+    '../common/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'tizen_datacontrol',
+      'type': 'loadable_module',
+      'sources': [
+        'datacontrol_api.js',
+        'datacontrol_extension.cc',
+        'datacontrol_extension.h',
+        'datacontrol_instance.cc',
+        'datacontrol_instance.h'
+      ],
+      'conditions': [
+        ['tizen == 1', {
+          'variables': {
+            'packages': [
+              'capi-data-control'
+            ]
+          },
+        }],
+      ],
+    },
+  ],
+}
diff --git a/src/datacontrol/datacontrol_api.js b/src/datacontrol/datacontrol_api.js
new file mode 100644 (file)
index 0000000..25fd05a
--- /dev/null
@@ -0,0 +1,419 @@
+/* global tizen, xwalk, extension */
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+tizen.debug = extension;
+
+var validator_ = xwalk.utils.validator;
+var types_ = validator_.Types;
+
+
+var callbackId = 0;
+var callbacks = {};
+
+extension.setMessageListener(function(json) {
+  var result = JSON.parse(json);
+  var callback = callbacks[result['callbackId']];
+  callback(result);
+});
+
+function nextCallbackId() {
+  return callbackId++;
+}
+
+function callNative(cmd, args) {
+  var json = {'cmd': cmd, 'args': args};
+  var argjson = JSON.stringify(json);
+  var resultString = extension.internal.sendSyncMessage(argjson);
+  var result = JSON.parse(resultString);
+
+  if (typeof result !== 'object') {
+    throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+  }
+
+  if (result['status'] == 'success') {
+    if (result['result']) {
+      return result['result'];
+    }
+    return true;
+  } else if (result['status'] == 'error') {
+    var err = result['error'];
+    if (err) {
+      throw new tizen.WebAPIException(err.name, err.message);
+    }
+    return false;
+  }
+}
+
+
+function callNativeWithCallback(cmd, args, callback) {
+  if (callback) {
+    var id = nextCallbackId();
+    args['callbackId'] = id;
+    callbacks[id] = callback;
+  }
+
+  return callNative(cmd, args);
+}
+
+function SetReadOnlyProperty(obj, n, v) {
+  Object.defineProperty(obj, n, {value: v, writable: false});
+}
+
+var DataType = {
+  'MAP': 'MAP',
+  'SQL': 'SQL'
+};
+
+function DataControlManager() {
+  // constructor of DataControlManager
+}
+
+
+DataControlManager.prototype.getDataControlConsumer = function(providerId, dataId, type) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'providerId', 'type': types_.STRING},
+    {'name': 'dataId', 'type': types_.STRING},
+    {'name': 'type', 'type': types_.ENUM, 'values': ['MAP', 'SQL']}
+  ]);
+
+  var returnObject = null;
+  if (type === 'SQL') {
+    returnObject = new SQLDataControlConsumer();
+  } else if (type === 'MAP') {
+    returnObject = new MappedDataControlConsumer();
+  }
+  SetReadOnlyProperty(returnObject, 'type', type); // read only property
+  SetReadOnlyProperty(returnObject, 'providerId', providerId); // read only property
+  SetReadOnlyProperty(returnObject, 'dataId', dataId); // read only property
+
+  return returnObject;
+};
+
+
+function DataControlConsumerObject() {
+  // constructor of DataControlConsumerObject
+}
+
+
+
+function SQLDataControlConsumer() {
+  // constructor of SQLDataControlConsumer
+}
+
+SQLDataControlConsumer.prototype = new DataControlConsumerObject();
+SQLDataControlConsumer.prototype.constructor = SQLDataControlConsumer;
+
+SQLDataControlConsumer.prototype.insert = function(reqId, insertionData) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'insertionData', 'type': types_.DICTIONARY},
+    {'name': 'successCallback', 'type': types_.FUNCTION, optional: true, nullable: true},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'insertionData': insertionData
+  };
+  try {
+    var syncResult =
+        callNativeWithCallback('SQLDataControlConsumer_insert', nativeParam, function(result) {
+      if (result.status == 'success') {
+        if (args.successCallback) {
+          args.successCallback(result['requestId'], result['result']);
+        }
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+  } catch (e) {
+    throw e;
+  }
+};
+
+SQLDataControlConsumer.prototype.update = function(reqId, updateData, where) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'updateData', 'type': types_.DICTIONARY},
+    {'name': 'where', 'type': types_.STRING},
+    {'name': 'successCallback', 'type': types_.FUNCTION, optional: true, nullable: true},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'where': args.where,
+    'updateData': args.updateData
+  };
+  try {
+    var syncResult =
+        callNativeWithCallback('SQLDataControlConsumer_update', nativeParam, function(result) {
+      if (result.status == 'success') {
+        if (args.successCallback) {
+          args.successCallback(result['requestId']);
+        }
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+  } catch (e) {
+    throw e;
+  }
+
+};
+
+SQLDataControlConsumer.prototype.remove = function(reqId, where) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'where', 'type': types_.STRING},
+    {'name': 'successCallback', 'type': types_.FUNCTION, optional: true, nullable: true},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'where': args.where
+  };
+  try {
+    var syncResult =
+        callNativeWithCallback('SQLDataControlConsumer_remove', nativeParam, function(result) {
+      if (result.status == 'success') {
+        if (args.successCallback) {
+          args.successCallback(result['requestId']);
+        }
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+  } catch (e) {
+    throw e;
+  }
+
+};
+
+SQLDataControlConsumer.prototype.select = function(reqId, columns, where, successCallback) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'columns', 'type': types_.ARRAY},
+    {'name': 'where', 'type': types_.STRING},
+    {'name': 'successCallback', 'type': types_.FUNCTION},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true},
+    {'name': 'page', 'type': types_.LONG, optional: true},
+    {'name': 'maxNumberPerPage', 'type': types_.LONG, optional: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'columns': args.columns,
+    'where': args.where
+  };
+  if (args['page']) {
+    nativeParam['page'] = args.page;
+  }
+  if (args['maxNumberPerPage']) {
+    nativeParam['maxNumberPerPage'] = args.maxNumberPerPage;
+  }
+  try {
+    var syncResult =
+        callNativeWithCallback('SQLDataControlConsumer_select', nativeParam, function(result) {
+      if (result.status == 'success') {
+        args.successCallback(result['result'], result['requestId']);
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+    // if you need synchronous result from native function using 'syncResult'.
+  } catch (e) {
+    throw e;
+  }
+
+};
+
+
+function MappedDataControlConsumer() {
+  // constructor of MappedDataControlConsumer
+}
+
+MappedDataControlConsumer.prototype = new DataControlConsumerObject();
+MappedDataControlConsumer.prototype.constructor = MappedDataControlConsumer;
+
+MappedDataControlConsumer.prototype.addValue = function(reqId, key, value) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'key', 'type': types_.STRING},
+    {'name': 'value', 'type': types_.STRING},
+    {'name': 'successCallback', 'type': types_.FUNCTION, optional: true, nullable: true},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'key': args.key,
+    'value': args.value
+  };
+  try {
+    var syncResult =
+        callNativeWithCallback('MappedDataControlConsumer_addValue', nativeParam, function(result) {
+      if (result.status == 'success') {
+        if (args.successCallback) {
+          args.successCallback(result['requestId']);
+        }
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+  } catch (e) {
+    throw e;
+  }
+
+};
+
+MappedDataControlConsumer.prototype.removeValue = function(reqId, key, value, successCallback) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'key', 'type': types_.STRING},
+    {'name': 'value', 'type': types_.STRING},
+    {'name': 'successCallback', 'type': types_.FUNCTION},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'key': args.key,
+    'value': args.value
+  };
+  try {
+    var syncResult =
+        callNativeWithCallback('MappedDataControlConsumer_removeValue', nativeParam, function(result) {
+      if (result.status == 'success') {
+        args.successCallback(result['requestId']);
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+  } catch (e) {
+    throw e;
+  }
+
+};
+
+MappedDataControlConsumer.prototype.getValue = function(reqId, key, successCallback) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'key', 'type': types_.STRING},
+    {'name': 'successCallback', 'type': types_.FUNCTION},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'key': args.key
+  };
+  try {
+    var syncResult = callNativeWithCallback('MappedDataControlConsumer_getValue', nativeParam, function(result) {
+      if (result.status == 'success') {
+        args.successCallback(result['result'], result['requestId']);
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+  } catch (e) {
+    throw e;
+  }
+
+};
+
+MappedDataControlConsumer.prototype.updateValue = function(
+        reqId, key, oldValue, newValue, successCallback) {
+  var args = validator_.validateArgs(arguments, [
+    {'name': 'reqId', 'type': types_.LONG},
+    {'name': 'key', 'type': types_.STRING},
+    {'name': 'oldValue', 'type': types_.STRING},
+    {'name': 'newValue', 'type': types_.STRING},
+    {'name': 'successCallback', 'type': types_.FUNCTION},
+    {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
+  ]);
+
+  var nativeParam = {
+    'providerId': this.providerId,
+    'dataId': this.dataId,
+    'reqId': args.reqId,
+    'key': args.key,
+    'oldValue': args.oldValue,
+    'newValue': args.newValue
+  };
+  try {
+    var syncResult =
+        callNativeWithCallback('MappedDataControlConsumer_updateValue', nativeParam, function(result) {
+      if (result.status == 'success') {
+        args.successCallback(result['requestId']);
+      }
+      if (result.status == 'error') {
+        if (args.errorCallback) {
+          var err = result['result'];
+          var e = new tizen.WebAPIException(err.name, err.message);
+          args.errorCallback(result['requestId'], e);
+        }
+      }
+    });
+  } catch (e) {
+    throw e;
+  }
+
+};
+
+
+
+exports = new DataControlManager();
+
diff --git a/src/datacontrol/datacontrol_extension.cc b/src/datacontrol/datacontrol_extension.cc
new file mode 100644 (file)
index 0000000..967c433
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datacontrol/datacontrol_extension.h"
+
+#include "datacontrol/datacontrol_instance.h"
+
+// This will be generated from datacontrol_api.js
+extern const char kSource_datacontrol_api[];
+
+common::Extension* CreateExtension() {
+  return new DatacontrolExtension;
+}
+
+DatacontrolExtension::DatacontrolExtension() {
+  SetExtensionName("tizen.datacontrol");
+  SetJavaScriptAPI(kSource_datacontrol_api);
+}
+
+DatacontrolExtension::~DatacontrolExtension() {}
+
+common::Instance* DatacontrolExtension::CreateInstance() {
+  return new extension::datacontrol::DatacontrolInstance;
+}
\ No newline at end of file
diff --git a/src/datacontrol/datacontrol_extension.h b/src/datacontrol/datacontrol_extension.h
new file mode 100644 (file)
index 0000000..ba2f4a1
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATACONTROL_DATACONTROL_EXTENSION_H_
+#define DATACONTROL_DATACONTROL_EXTENSION_H_
+
+#include "common/extension.h"
+
+class DatacontrolExtension : public common::Extension {
+ public:
+  DatacontrolExtension();
+  virtual ~DatacontrolExtension();
+
+ private:
+  virtual common::Instance* CreateInstance();
+};
+
+#endif // DATACONTROL_DATACONTROL_EXTENSION_H_
diff --git a/src/datacontrol/datacontrol_instance.cc b/src/datacontrol/datacontrol_instance.cc
new file mode 100644 (file)
index 0000000..45b4956
--- /dev/null
@@ -0,0 +1,802 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "datacontrol/datacontrol_instance.h"
+
+#include <functional>
+
+#include "common/picojson.h"
+#include "common/logger.h"
+#include "common/platform_exception.h"
+
+#include "common/scope_exit.h"
+#include <memory>
+
+#include <glib.h>
+
+namespace extension {
+namespace datacontrol {
+
+namespace {
+// The privileges that required in Datacontrol API
+const std::string kPrivilegeDatacontrol = "";
+
+} // namespace
+
+using namespace common;
+using namespace extension::datacontrol;
+
+struct DatacontrolInformation {
+  int callbackId;
+  int requestId;
+  int userDefinedRequestId;
+};
+static DatacontrolInstance *Self = NULL;
+static std::map<int, DatacontrolInformation*> IdMap;
+
+DatacontrolInstance::DatacontrolInstance() {
+  using namespace std::placeholders;
+  #define REGISTER_SYNC(c,x) \
+    RegisterSyncHandler(c, std::bind(&DatacontrolInstance::x, this, _1, _2));
+  REGISTER_SYNC("SQLDataControlConsumer_update", SQLDataControlConsumerUpdate);
+  REGISTER_SYNC("MappedDataControlConsumer_addValue", MappedDataControlConsumerAddvalue);
+  REGISTER_SYNC("SQLDataControlConsumer_select", SQLDataControlConsumerSelect);
+  REGISTER_SYNC("SQLDataControlConsumer_remove", SQLDataControlConsumerRemove);
+  REGISTER_SYNC("MappedDataControlConsumer_removeValue", MappedDataControlConsumerRemovevalue);
+  REGISTER_SYNC("MappedDataControlConsumer_updateValue", MappedDataControlConsumerUpdatevalue);
+  REGISTER_SYNC("DataControlManager_getDataControlConsumer", DataControlManagerGetdatacontrolconsumer);
+  REGISTER_SYNC("SQLDataControlConsumer_insert", SQLDataControlConsumerInsert);
+  REGISTER_SYNC("MappedDataControlConsumer_getValue", MappedDataControlConsumerGetvalue);
+  #undef REGISTER_SYNC
+
+  Self = this;
+}
+
+DatacontrolInstance::~DatacontrolInstance() {
+  Self = NULL;
+}
+
+static void ReplyAsync(int callbackId, bool isSuccess, picojson::object& param) {
+  param["callbackId"] = picojson::value(static_cast<double>(callbackId));
+  param["status"] = picojson::value(isSuccess ? "success" : "error");
+  
+  picojson::value result = picojson::value(param);
+  
+  if(Self) {
+    Self->PostMessage(result.serialize().c_str());
+  } else {
+    LoggerE("Current Instance is not registed");
+  }
+}
+
+static bool SQLColumnName(result_set_cursor cursor, int columnIndex, picojson::value& name) {
+  char buffer[4096];
+  int result = data_control_sql_get_column_name(cursor, columnIndex, buffer);
+  if (result != DATA_CONTROL_ERROR_NONE) {
+    LoggerE("Getting column item type is failed with error : %d", result);
+    return false;
+  }
+  name = picojson::value(buffer);
+  return true;
+}
+
+static bool SQLColumnValue(result_set_cursor cursor, int columnIndex, picojson::value& val) {
+  data_control_sql_column_type_e type = DATA_CONTROL_SQL_COLUMN_TYPE_UNDEFINED;
+  int result = data_control_sql_get_column_item_type(cursor, columnIndex, &type);
+  if (result != DATA_CONTROL_ERROR_NONE) {
+    LoggerE("Getting column item type is failed with error : %d", result);
+    return false;
+  }
+  switch (type) {
+    case DATA_CONTROL_SQL_COLUMN_TYPE_INT64: {
+      long long data = 0;
+      result = data_control_sql_get_int64_data(cursor, columnIndex, &data);
+      if (result != DATA_CONTROL_ERROR_NONE) break;
+      val = picojson::value(static_cast<double>(data));
+      break;
+    }
+    case DATA_CONTROL_SQL_COLUMN_TYPE_DOUBLE: {
+      double data = 0;
+      result = data_control_sql_get_double_data(cursor, columnIndex, &data);
+      if (result != DATA_CONTROL_ERROR_NONE) break;
+      val = picojson::value(data);
+      break;
+    }
+    case DATA_CONTROL_SQL_COLUMN_TYPE_TEXT: {
+      int size = data_control_sql_get_column_item_size(cursor, columnIndex);
+      char *buffer = new char[size];
+      result = data_control_sql_get_text_data(cursor, columnIndex, buffer);
+      if (result != DATA_CONTROL_ERROR_NONE) {
+        LoggerE("Getting Text value failed : %s", get_error_message(result));
+        break;
+      }
+      val = picojson::value(buffer);
+      delete[] buffer;
+      break;
+    }
+    case DATA_CONTROL_SQL_COLUMN_TYPE_BLOB: {
+      int size = data_control_sql_get_column_item_size(cursor, columnIndex);
+      char *buffer = new char[size];
+      result = data_control_sql_get_blob_data(cursor, columnIndex, buffer, size);
+      if (result != DATA_CONTROL_ERROR_NONE) break;
+      val = picojson::value(buffer);
+      delete[] buffer;
+      break;
+    }
+    case DATA_CONTROL_SQL_COLUMN_TYPE_NULL: {
+      val = picojson::value();
+      break;
+    }
+    default: {
+      LoggerE("%th column is undefined column type", columnIndex);
+      return false;
+    }
+  }
+  if (result != DATA_CONTROL_ERROR_NONE) {
+    LoggerE("Getting column item value is failed with error : %s", ::get_error_message(result));
+    return false;
+  } else {
+    return true;
+  }
+}
+
+static void MAPAddResponseCallback(int requestId, data_control_h handle,
+                                   bool providerResult,
+                                   const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  }
+
+  ReplyAsync(info->callbackId, providerResult, obj);
+  delete info;
+  IdMap.erase(requestId);
+}
+
+static void MAPSetResponseCallback(int requestId, data_control_h handle,
+                                   bool providerResult,
+                                   const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  }
+
+  ReplyAsync(info->callbackId, providerResult, obj);
+  delete info;
+  IdMap.erase(requestId);
+}
+
+static void MAPGetResponseCallback(int requestId, data_control_h handle,
+                                   char **result_value_list, int result_value_count,
+                                   bool providerResult,
+                                   const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  } else {
+    picojson::array result;
+    for (int i=0; i<result_value_count; i++) {
+      result.push_back(picojson::value(result_value_list[i]));
+    }
+    obj["result"] = picojson::value(result);
+  }
+
+  ReplyAsync(info->callbackId, providerResult, obj);
+  delete info;
+  IdMap.erase(requestId);
+}
+
+static void MAPRemoveReponseCallback(int requestId, data_control_h handle,
+                                     bool providerResult,
+                                     const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  }
+
+  ReplyAsync(info->callbackId, providerResult, obj);
+  delete info;
+  IdMap.erase(requestId);
+}
+
+
+static void SQLSelectResponseCallback(int requestId, data_control_h handle, 
+                                      result_set_cursor cursor,
+                                      bool providerResult,
+                                      const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  } else {
+    picojson::array result;
+
+    while (data_control_sql_step_next(cursor) == DATA_CONTROL_ERROR_NONE)
+    {
+      int columnSize = 0;
+      picojson::object rowData;
+      picojson::array columns;
+      picojson::array values;
+      int columnCount = data_control_sql_get_column_count(cursor);
+      for (int i=0; i<columnCount; i++) {
+        picojson::value column;
+        picojson::value value;
+        if (SQLColumnName(cursor, i, column) && SQLColumnValue(cursor, i, value)) {
+          std::string& name = column.get<std::string>();
+          std::string& val = value.get<std::string>();
+          columns.push_back(column);
+          values.push_back(value);
+        }
+      }
+      rowData["columns"] = picojson::value(columns);
+      rowData["values"] = picojson::value(values);
+      result.push_back(picojson::value(rowData));
+    }
+    obj["result"] = picojson::value(result);
+  }
+  ReplyAsync(info->callbackId, providerResult, obj); 
+  delete info;
+  IdMap.erase(requestId);
+}
+
+static void SQLInsertResponseCallback(int requestId, data_control_h handle,
+                                      long long inserted_row_id, 
+                                      bool providerResult,
+                                      const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  } else {
+    obj["result"] = picojson::value(static_cast<double>(inserted_row_id));
+  }
+
+  ReplyAsync(info->callbackId, providerResult, obj);
+  delete info;
+  IdMap.erase(requestId);
+}
+
+static void SQLUpdateResponseCallback(int requestId, data_control_h handle,
+                                      bool providerResult, 
+                                      const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  }
+
+  ReplyAsync(info->callbackId, providerResult, obj);
+  delete info;
+  IdMap.erase(requestId);
+}
+
+static void SQLDeleteResponseCallback(int requestId, data_control_h handle,
+                                      bool providerResult,
+                                      const char *error, void *user_data) {
+  DatacontrolInformation *info = IdMap[requestId];
+  if (info == NULL) {
+    LoggerE("Invalid context");
+    return;
+  }
+
+  picojson::object obj;
+  obj["requestId"] = picojson::value(static_cast<double>(info->userDefinedRequestId));
+  if (!providerResult) {
+    obj["result"] = InvalidValuesException(error).ToJSON();
+  }
+
+  ReplyAsync(info->callbackId, providerResult, obj);
+  delete info;
+  IdMap.erase(requestId);
+}
+
+static data_control_sql_response_cb sqlResponseCallback = {
+  SQLSelectResponseCallback,
+  SQLInsertResponseCallback,
+  SQLUpdateResponseCallback,
+  SQLDeleteResponseCallback
+};
+static data_control_map_response_cb mapResponseCallback = {
+  MAPGetResponseCallback,
+  MAPSetResponseCallback,
+  MAPAddResponseCallback,
+  MAPRemoveReponseCallback
+};
+
+#define RETURN_IF_FAIL(result, msg) \
+    do {\
+      if (result != DATA_CONTROL_ERROR_NONE) {\
+        LoggerE(msg" : %s", ::get_error_message(result));\
+        return result;\
+      }\
+    } while (0)\
+
+int DatacontrolInstance::RunMAPDataControlJob(const std::string& providerId, const std::string& dataId, 
+                                              int callbackId, int userRequestId, DataControlJob job) {
+  int result = DATA_CONTROL_ERROR_NONE;
+  std::unique_ptr<DatacontrolInformation> info {new DatacontrolInformation()};
+  info->callbackId = callbackId;
+  info->userDefinedRequestId = userRequestId;
+  data_control_h handle;
+
+  SCOPE_EXIT {
+    result = ::data_control_map_destroy(handle);
+    RETURN_IF_FAIL(result, "Destroying map data control handle is failed with error");
+  };
+
+  result = ::data_control_map_create(&handle);
+  RETURN_IF_FAIL(result, "Creating map data control handle is failed with error");
+
+  result = ::data_control_map_set_provider_id(handle, providerId.c_str());
+  RETURN_IF_FAIL(result, "Setting provider id is failed with error");
+
+  result = ::data_control_map_set_data_id(handle, dataId.c_str());
+  RETURN_IF_FAIL(result, "Setting data id is failed th error");
+
+  result = ::data_control_map_register_response_cb(handle, &mapResponseCallback, NULL);
+  RETURN_IF_FAIL(result, "Setting result Callback failed with error");
+
+  result = job(handle, &info->requestId);
+  RETURN_IF_FAIL(result, "Doing job failed with error");
+
+  IdMap[info->requestId] = info.get();
+
+  info.release();
+
+  return result;
+}
+int DatacontrolInstance::RunSQLDataControlJob(const std::string& providerId, const std::string& dataId, 
+                                               int callbackId, int userRequestId, DataControlJob job) {
+  int result = DATA_CONTROL_ERROR_NONE;
+  std::unique_ptr<DatacontrolInformation> info {new DatacontrolInformation()};
+  info->callbackId = callbackId;
+  info->userDefinedRequestId = userRequestId;
+  data_control_h handle;
+
+  SCOPE_EXIT {
+    result = ::data_control_sql_destroy(handle);
+    RETURN_IF_FAIL(result, "Destroying sql data control handle is failed with error");
+  };
+
+  result = ::data_control_sql_create(&handle);
+  RETURN_IF_FAIL(result, "Creating sql data control handle is failed with error");
+
+  result = ::data_control_sql_set_provider_id(handle, providerId.c_str());
+  RETURN_IF_FAIL(result, "Setting provider id is failed with error");
+
+  result = ::data_control_sql_set_data_id(handle, dataId.c_str());
+  RETURN_IF_FAIL(result, "Setting data id is failed th error");
+
+  result = ::data_control_sql_register_response_cb(handle, &sqlResponseCallback, NULL);
+  RETURN_IF_FAIL(result, "Setting result Callback failed with error");
+
+  result = job(handle, &info->requestId);
+  RETURN_IF_FAIL(result, "Doing job failed with error");
+
+  IdMap[info->requestId] = info.get();
+
+  info.release();
+
+  return result;
+}
+
+#define CHECK_EXIST(args, name, out) \
+    if (!args.contains(name)) {\
+      ReportError(TypeMismatchException(name" is required argument"), out);\
+      return;\
+    }
+
+void DatacontrolInstance::DataControlManagerGetdatacontrolconsumer(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+
+  // implement it
+
+
+  // if success
+  // ReportSuccess(out);
+  // if error
+  // ReportError(out);
+}
+void DatacontrolInstance::SQLDataControlConsumerInsert(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+  CHECK_EXIST(args, "insertionData", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+  picojson::object insertionData = args.get("insertionData").get<picojson::object>();
+
+  if (!insertionData.count("columns") || !insertionData.count("values")) {
+    ReportError(TypeMismatchException("columns and values is required insertionData argument"), out);
+    return;
+  }
+  if (!insertionData["columns"].is<picojson::array>() || 
+      !insertionData["values"].is<picojson::array>()) {
+    ReportError(TypeMismatchException("columns and values type must be array"), out);
+    return;
+  }
+
+  int result = RunSQLDataControlJob(providerId, dataId, callbackId, reqId, 
+                                    [&](data_control_h& handle, int *requestId) -> int {
+    picojson::array columns = insertionData["columns"].get<picojson::array>();
+    picojson::array values = insertionData["values"].get<picojson::array>();
+
+    picojson::array::size_type columnsLength = columns.size();
+    picojson::array::size_type valuesLength = values.size();
+
+    picojson::array::size_type size = std::min(columnsLength, valuesLength);
+
+    bundle * b = ::bundle_create();
+    SCOPE_EXIT {
+      bundle_free(b);
+    };
+    for (unsigned i=0; i<size; i++) {
+      picojson::value& column = columns[i];
+      picojson::value& value = values[i];
+
+      if(!column.is<std::string>() || !value.is<std::string>()) {
+        break;
+      }
+
+      std::string& columnName = column.get<std::string>();
+      std::string valueString = "\""+value.get<std::string>()+"\"";
+
+      bundle_add_str(b, columnName.c_str(), valueString.c_str());
+    }
+
+    return ::data_control_sql_insert(handle, b, requestId);
+  });
+
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+void DatacontrolInstance::SQLDataControlConsumerUpdate(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "where", out)
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+  CHECK_EXIST(args, "updateData", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+  const std::string& where = args.get("where").get<std::string>();
+  picojson::object updateData = args.get("updateData").get<picojson::object>();
+
+  if (!updateData.count("columns") || !updateData.count("values")) {
+    ReportError(TypeMismatchException("columns and values is required updateData argument"), out);
+    return;
+  }
+
+  if (!updateData["columns"].is<picojson::array>() ||
+      !updateData["values"].is<picojson::array>()) {
+    ReportError(TypeMismatchException("columns and values type must be array"), out);
+    return;
+  }
+
+  int result = RunSQLDataControlJob(providerId, dataId, callbackId, reqId,
+                                    [&](data_control_h& handle, int *requestId) -> int {
+    picojson::array columns = updateData["columns"].get<picojson::array>();
+    picojson::array values = updateData["values"].get<picojson::array>();
+
+    picojson::array::size_type columnsLength = columns.size();
+    picojson::array::size_type valuesLength = values.size();
+
+    picojson::array::size_type size = std::min(columnsLength, valuesLength);
+
+    bundle * b = ::bundle_create();
+    SCOPE_EXIT {
+      bundle_free(b);
+    };
+    for (unsigned i=0; i<size; i++) {
+      picojson::value& column = columns[i];
+      picojson::value& value = values[i];
+
+      if(!column.is<std::string>() || !value.is<std::string>()) {
+        break;
+      }
+
+      std::string& columnName = column.get<std::string>();
+      std::string valueString = "\""+value.get<std::string>()+"\"";
+
+      bundle_add_str(b, columnName.c_str(), valueString.c_str());
+    }
+
+    return ::data_control_sql_update(handle, b, where.c_str(), requestId);
+  });
+
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+
+void DatacontrolInstance::SQLDataControlConsumerRemove(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "where", out)
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+  const std::string& where = args.get("where").get<std::string>();
+
+  int result = RunSQLDataControlJob(providerId, dataId, callbackId, reqId,
+                                    [&](data_control_h& handle, int *requestId) -> int {
+    return ::data_control_sql_delete(handle, where.c_str(), requestId);
+  });
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+
+void DatacontrolInstance::SQLDataControlConsumerSelect(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "columns", out)
+  CHECK_EXIST(args, "where", out)
+
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  const picojson::array columns = args.get("columns").get<picojson::array>();
+  const std::string& where = args.get("where").get<std::string>();
+
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+
+  int page = 0, maxNumberPerPage = 0;
+  if (args.contains("page")) {
+    page = static_cast<int>(args.get("page").get<double>());
+  }
+  if (args.contains("maxNumberPerPage")) {
+    maxNumberPerPage = static_cast<int>(args.get("maxNumberPerPage").get<double>());
+  }
+
+  int result = RunSQLDataControlJob(providerId, dataId, callbackId, reqId, [&](data_control_h& handle, int *requestId) -> int {
+    std::vector<const char*> temp;
+    for (auto& s: columns) temp.push_back(s.get<std::string>().c_str());
+    int columnCount = static_cast<int>(temp.size());
+    char** cColumns = const_cast<char**>(&*temp.begin());
+
+    if (page > 0 && maxNumberPerPage > 0) {
+      return ::data_control_sql_select_with_page(handle, cColumns, columnCount, where.c_str(), 
+                                       "1 ASC", page, maxNumberPerPage, requestId);
+    } else {
+      return ::data_control_sql_select(handle, cColumns, columnCount, where.c_str(), 
+                                       "1 ASC", requestId);
+    }
+  });
+
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+void DatacontrolInstance::MappedDataControlConsumerAddvalue(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "key", out)
+  CHECK_EXIST(args, "value", out)
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+  const std::string& key = args.get("key").get<std::string>();
+  const std::string& value = args.get("value").get<std::string>();
+
+  int result = RunMAPDataControlJob(providerId, dataId, callbackId, reqId,
+                                    [&](data_control_h& handle, int *requestId) -> int {
+    return ::data_control_map_add(handle, key.c_str() , value.c_str(), requestId);
+  });
+
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+void DatacontrolInstance::MappedDataControlConsumerRemovevalue(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "key", out)
+  CHECK_EXIST(args, "value", out)
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+  const std::string& key = args.get("key").get<std::string>();
+  const std::string& value = args.get("value").get<std::string>();
+
+  int result = RunMAPDataControlJob(providerId, dataId, callbackId, reqId,
+                                    [&](data_control_h& handle, int *requestId) -> int {
+    return ::data_control_map_remove(handle, key.c_str(), value.c_str(), requestId);
+  });
+
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+void DatacontrolInstance::MappedDataControlConsumerGetvalue(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "key", out)
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+  const std::string& key = args.get("key").get<std::string>();
+
+  int result = RunMAPDataControlJob(providerId, dataId, callbackId, reqId,
+                                    [&](data_control_h& handle, int *requestId) -> int {
+    return ::data_control_map_get(handle, key.c_str(), requestId);
+  });
+
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+void DatacontrolInstance::MappedDataControlConsumerUpdatevalue(const picojson::value& args, picojson::object& out) {
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "reqId", out)
+  CHECK_EXIST(args, "key", out)
+  CHECK_EXIST(args, "oldValue", out)
+  CHECK_EXIST(args, "newValue", out)
+  CHECK_EXIST(args, "providerId", out)
+  CHECK_EXIST(args, "dataId", out)
+
+  const std::string& providerId = args.get("providerId").get<std::string>();
+  const std::string& dataId = args.get("dataId").get<std::string>();
+  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  int reqId = static_cast<int>(args.get("reqId").get<double>());
+  const std::string& key = args.get("key").get<std::string>();
+  const std::string& oldValue = args.get("oldValue").get<std::string>();
+  const std::string& newValue = args.get("newValue").get<std::string>();
+
+  int result = RunMAPDataControlJob(providerId, dataId, callbackId, reqId,
+                                    [&](data_control_h& handle, int *requestId) -> int {
+    return ::data_control_map_set(handle, key.c_str(), oldValue.c_str(), newValue.c_str(), requestId);
+  });
+
+  if(result == DATA_CONTROL_ERROR_NONE) {
+    ReportSuccess(out);
+  } else {
+    if (result == DATA_CONTROL_ERROR_IO_ERROR) {
+      ReportError(IOException(get_error_message(result)), out);
+    } else if (result == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+      ReportError(SecurityException(get_error_message(result)), out);
+    } else {
+      ReportError(UnknownException(get_error_message(result)), out);
+    }
+  }
+}
+
+
+#undef CHECK_EXIST
+
+} // namespace datacontrol
+} // namespace extension
diff --git a/src/datacontrol/datacontrol_instance.h b/src/datacontrol/datacontrol_instance.h
new file mode 100644 (file)
index 0000000..7c68530
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DATACONTROL_DATACONTROL_INSTANCE_H_
+#define DATACONTROL_DATACONTROL_INSTANCE_H_
+
+#include "common/extension.h"
+
+#include <data_control.h>
+
+namespace extension {
+namespace datacontrol {
+
+class DatacontrolInstance : public common::ParsedInstance {
+ public:
+  DatacontrolInstance();
+  virtual ~DatacontrolInstance();
+
+  typedef std::function< int (data_control_h& handle, int *requestId) > DataControlJob;
+  int RunMAPDataControlJob(const std::string& providerId, const std::string& dataId, 
+                            int callbackId, int userRequestId, DataControlJob job);
+  int RunSQLDataControlJob(const std::string& providerId, const std::string& dataId, 
+                            int callbackId, int userRequestId, DataControlJob job);
+
+ private:
+  void DataControlManagerGetdatacontrolconsumer(const picojson::value& args, picojson::object& out);
+  void SQLDataControlConsumerInsert(const picojson::value& args, picojson::object& out);
+  void SQLDataControlConsumerUpdate(const picojson::value& args, picojson::object& out);
+  void SQLDataControlConsumerRemove(const picojson::value& args, picojson::object& out);
+  void SQLDataControlConsumerSelect(const picojson::value& args, picojson::object& out);
+  void MappedDataControlConsumerAddvalue(const picojson::value& args, picojson::object& out);
+  void MappedDataControlConsumerRemovevalue(const picojson::value& args, picojson::object& out);
+  void MappedDataControlConsumerGetvalue(const picojson::value& args, picojson::object& out);
+  void MappedDataControlConsumerUpdatevalue(const picojson::value& args, picojson::object& out);
+};
+
+} // namespace datacontrol
+} // namespace extension
+
+#endif // DATACONTROL_DATACONTROL_INSTANCE_H_
index fc8e24b..138ab77 100644 (file)
@@ -26,6 +26,7 @@
               'callhistory/callhistory.gyp:*',
               'contact/contact.gyp:*',
               'calendar/calendar.gyp:*',
+              'datacontrol/datacontrol.gyp:*',
               'datasync/datasync.gyp:*',
               'messaging/messaging.gyp:*',
               'nfc/nfc.gyp:*',