[Contact] Added method for finding by usageCount
authorPiotr Kosko <p.kosko@samsung.com>
Thu, 17 Mar 2016 14:11:45 +0000 (15:11 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Wed, 23 Mar 2016 07:51:08 +0000 (08:51 +0100)
[Feautre] added implementation of findByUsageCount() method.

[Verification] Checked in console.

Change-Id: I8429b883e81c80394317a852ec5ad539d883198c
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
src/contact/addressbook.h
src/contact/contact_instance.cc
src/contact/contact_instance.h
src/contact/contact_manager.cc
src/contact/contact_manager.h
src/contact/js/contact_manager.js

index 96bc52e14fc67d1f1cbe378bce5913c274801abb..583635787bfc9761bbbc0d0db5e3cbb52c7651a8 100644 (file)
@@ -39,6 +39,8 @@ common::PlatformResult AddressBookUpdate(const JsonObject& args,
 common::PlatformResult AddressBookRemove(const JsonObject& args, JsonObject&);
 common::PlatformResult AddressBookFind(const JsonObject& args,
                                        JsonArray& array);
+common::PlatformResult AddressBookFindByUsageCount(const JsonObject& args,
+                                                   JsonArray& array);
 common::PlatformResult AddressBookAddGroup(const JsonObject& args,
                                            JsonObject& out);
 common::PlatformResult AddressBookGetGroup(const JsonObject& args,
index 229a1114a66e7d8622b9c7b64efbe21f43937046..fa43fce04457d6e4ef348a51d76f63b240b0d88e 100755 (executable)
@@ -60,6 +60,7 @@ ContactInstance::ContactInstance()
   REGISTER_SYNC("ContactManager_remove", ContactManagerRemove);
   REGISTER_ASYNC("ContactManager_removeBatch", ContactManagerRemoveBatch);
   REGISTER_ASYNC("ContactManager_find", ContactManagerFind);
+  REGISTER_ASYNC("ContactManager_findByUsageCount", ContactManagerFindByUsageCount);
   REGISTER_SYNC("ContactManager_importFromVCard",
                 ContactManagerImportFromVCard);
   REGISTER_SYNC("ContactManager_startListening", ContactManagerStartListening);
@@ -537,6 +538,36 @@ void ContactInstance::ContactManagerFind(const JsonValue& args,
       get, get_response, data);
 }
 
+void ContactInstance::ContactManagerFindByUsageCount(const JsonValue& args, JsonObject& out) {
+  LoggerD("entered");
+  CHECK_PRIVILEGE_ACCESS(kPrivilegeContactRead, &out);
+  const double callback_id = args.get("callbackId").get<double>();
+
+  auto get = [this, args](const std::shared_ptr<JsonValue>& response) -> void {
+    JsonValue result = JsonValue(JsonArray());
+
+    PlatformResult status = ContactManager::ContactManagerFindByUsageCount(
+        common::JsonCast<JsonObject>(args), result.get<JsonArray>());
+    if (status.IsSuccess()) {
+      ReportSuccess(result, response->get<JsonObject>());
+    } else {
+      LogAndReportError(status, &response->get<JsonObject>());
+    }
+  };
+
+  auto get_response =
+      [this, callback_id](const std::shared_ptr<JsonValue>& response) {
+    JsonObject& obj = response->get<JsonObject>();
+    obj["callbackId"] = picojson::value(static_cast<double>(callback_id));
+    Instance::PostMessage(this, response->serialize().c_str());
+  };
+
+  auto data = std::shared_ptr<JsonValue>(new JsonValue(JsonObject()));
+
+  TaskQueue::GetInstance().Queue<JsonValue>(
+      get, get_response, data);
+}
+
 void ContactInstance::ContactManagerImportFromVCard(const JsonValue& args,
                                                     JsonObject& out) {
   JsonValue val{JsonObject{}};
index c2aee67797446ccd3263ac03140ccaa97a338eb5..a79c0f850c86363e0488c4a4e3651a1b00fa4ace 100755 (executable)
@@ -186,6 +186,8 @@ class ContactInstance : public common::ParsedInstance {
    */
   void ContactManagerFind(const JsonValue& args, JsonObject& out);
 
+  void ContactManagerFindByUsageCount(const JsonValue& args, JsonObject& out);
+
   /**
    * Signature: @code void getAddressBook(contactString); @endcode
    * JSON: @code data: {method: 'ContactManager_importFromVCard',
index 10ba538c61e4ab53cd0ad42bae44d22ff9508b73..252aaa36eb501b4332a0c492ac1329539b6ed2f9 100755 (executable)
@@ -423,8 +423,6 @@ PlatformResult ContactManagerFind(const JsonObject& args, JsonArray& out) {
   if (status.IsError()) return status;
 
   contacts_query_h contacts_query = nullptr;
-  ContactUtil::ContactsQueryHPtr contacts_query_ptr(
-      &contacts_query, ContactUtil::ContactsQueryDeleter);
 
   int error_code = CONTACTS_ERROR_NONE;
 
@@ -456,6 +454,8 @@ PlatformResult ContactManagerFind(const JsonObject& args, JsonArray& out) {
     status = ContactUtil::ErrorChecker(error_code, "Failed contacts_query_create");
     if (status.IsError()) return status;
   }
+  ContactUtil::ContactsQueryHPtr contacts_query_ptr(
+      &contacts_query, ContactUtil::ContactsQueryDeleter);
 
   // Add filter to query
   std::vector<std::vector<ContactUtil::ContactsFilterPtr>> intermediate_filters(
@@ -870,6 +870,197 @@ PlatformResult ContactManagerFind(const JsonObject& args, JsonArray& out) {
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult ContactManagerFindByUsageCount(const JsonObject& args, JsonArray& out) {
+  LoggerD("Enter");
+  PlatformResult status = ContactUtil::CheckDBConnection();
+  if (status.IsError()) return status;
+  contacts_query_h contacts_query = nullptr;
+  int ret = contacts_query_create(_contacts_person_usage._uri, &contacts_query);
+  status = ContactUtil::ErrorChecker(ret, "Failed contacts_query_create");
+  if (!status) {
+    return status;
+  }
+  ContactUtil::ContactsQueryHPtr query_ptr(&contacts_query, ContactUtil::ContactsQueryDeleter);
+  int error_code = CONTACTS_ERROR_NONE;
+  // parse filter
+  const auto filter_it = args.find("filter");
+  if (args.end() == filter_it || !filter_it->second.is<picojson::object>()){
+    LoggerD("Filter is invalid.");
+    return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Filter is invalid");
+  }
+
+  const auto filter = filter_it->second;
+  std::string filter_type = filter.get("filterType").to_str();
+  std::string attribute_name = filter.get("attributeName").to_str();
+
+  // set sort mode
+  // default sort is descending
+  bool is_asc = false;
+  const auto sort_mode_it = args.find("sortModeOrder");
+  if (args.end() != sort_mode_it && sort_mode_it->second.is<std::string>()) {
+    const auto& sort_mode = sort_mode_it->second.get<std::string>();
+
+    is_asc = ("ASC" == sort_mode);
+  }
+  error_code = contacts_query_set_sort(contacts_query,
+                                       _contacts_person_usage.times_used, is_asc);
+  status = ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_sort");
+  if (status.IsError()) return status;
+
+  // Create filter
+  contacts_filter_h filter_handle = nullptr;
+  ret = contacts_filter_create(_contacts_person_usage._uri, &filter_handle);
+  status = ContactUtil::ErrorChecker(ret, "Failed contacts_filter_create");
+  if (!status) {
+    return status;
+  }
+  ContactUtil::ContactsFilterPtr filter_ptr(filter_handle, ContactUtil::ContactsFilterDeleter);
+
+  bool is_added = false;
+  // adding values filtering
+  if ("AttributeFilter" == filter_type) {
+    // Attribute filter handling, only EQUAL is supported for ints (other are ignored)
+    int match_value = 0;
+    const auto& match = filter.get("matchValue");
+    if (match.is<double>()){
+      match_value = static_cast<int>(match.get<double>());
+      ret = contacts_filter_add_int(filter_handle,
+                                    _contacts_person_usage.times_used,
+                                    CONTACTS_MATCH_EQUAL,
+                                    match_value);
+      status = ContactUtil::ErrorChecker(ret, "Failed contacts_filter_add_int");
+      if (!status) {
+        return status;
+      }
+      is_added = true;
+    }
+  } else {
+    // Range filter handling
+    int initial_value = 0;
+    int end_value = 0;
+
+    // inital value handling
+    const auto& initial = filter.get("initialValue");
+    if (initial.is<double>()){
+      initial_value = static_cast<int>(initial.get<double>());
+
+      ret = contacts_filter_add_int(filter_handle,
+                                    _contacts_person_usage.times_used,
+                                    CONTACTS_MATCH_GREATER_THAN_OR_EQUAL,
+                                    initial_value);
+      status = ContactUtil::ErrorChecker(ret, "Failed contacts_filter_add_int");
+      if (!status) {
+        return status;
+      }
+      is_added = true;
+    }
+    // end value handling
+    const auto& end = filter.get("endValue");
+    if (end.is<double>()){
+      end_value = static_cast<int>(end.get<double>());
+
+      if (is_added){
+        ret = contacts_filter_add_operator(filter_handle, CONTACTS_FILTER_OPERATOR_AND);
+        status = ContactUtil::ErrorChecker(ret, "Failed contacts_filter_add_operator");
+        if (!status) {
+          return status;
+        }
+      }
+      ret = contacts_filter_add_int(filter_handle,
+                                    _contacts_person_usage.times_used,
+                                    CONTACTS_MATCH_LESS_THAN_OR_EQUAL,
+                                    end_value);
+      status = ContactUtil::ErrorChecker(ret, "Failed contacts_filter_add_int");
+      if (!status) {
+        return status;
+      }
+      is_added = true;
+    }
+  }
+
+  // if some filtering is already added, use AND operator
+  if (is_added){
+    ret = contacts_filter_add_operator(filter_handle, CONTACTS_FILTER_OPERATOR_AND);
+    status = ContactUtil::ErrorChecker(ret, "Failed contacts_filter_add_operator");
+    if (!status) {
+      return status;
+    }
+  }
+  // adding usage type to filter
+  contacts_usage_type_e type = Person::UsageTypeFromString(attribute_name);
+  ret = contacts_filter_add_int(filter_handle,
+                                _contacts_person_usage.usage_type,
+                                CONTACTS_MATCH_EQUAL,
+                                type);
+  status = ContactUtil::ErrorChecker(ret, "Failed contacts_filter_add_int");
+  if (!status) {
+    return status;
+  }
+  // Setting filter
+  ret = contacts_query_set_filter(contacts_query, filter_handle);
+  status = ContactUtil::ErrorChecker(ret, "Failed contacts_query_set_filter");
+  if (!status) {
+    return status;
+  }
+
+  // check limit
+  int limit = 0;
+  const auto limit_it = args.find("limit");
+  if (args.end() != limit_it && limit_it->second.is<double>()) {
+    limit = static_cast<int>(limit_it->second.get<double>());
+  }
+
+  // check offset
+  int offset = 0;
+  const auto offset_it = args.find("offset");
+  if (args.end() != offset_it && offset_it->second.is<double>()) {
+    offset = static_cast<int>(offset_it->second.get<double>());
+  }
+
+  contacts_list_h person_list = nullptr;
+  error_code =
+      contacts_db_get_records_with_query(contacts_query, offset, limit, &person_list);
+
+  status = ContactUtil::ErrorChecker(
+      error_code, "Failed contacts_db_get_records_with_query");
+  if (status.IsError()) return status;
+
+  ContactUtil::ContactsListHPtr person_list_ptr(
+      &person_list, ContactUtil::ContactsListDeleter);
+
+  int record_count = 0;
+  error_code = contacts_list_get_count(person_list, &record_count);
+  status =
+      ContactUtil::ErrorChecker(error_code, "Failed contacts_list_get_count");
+  if (status.IsError()) return status;
+
+  contacts_list_first(person_list);
+
+  for (int i = 0; i < record_count; i++) {
+    contacts_record_h contacts_record;
+    error_code =
+        contacts_list_get_current_record_p(person_list, &contacts_record);
+    if (CONTACTS_ERROR_NONE != error_code || nullptr == contacts_record) {
+      LoggerW("Failed group record (ret:%d)", error_code);
+      continue;
+    }
+
+    int id_value = 0;
+    error_code = contacts_record_get_int(contacts_record, _contacts_person_usage.person_id,
+                                         &id_value);
+
+    status =
+        ContactUtil::ErrorChecker(error_code, "Failed contacts_record_get_int");
+    if (status.IsError()) return status;
+
+    out.push_back(JsonValue(static_cast<double>(id_value)));
+
+    contacts_list_next(person_list);
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 PlatformResult ContactManagerImportFromVCard(const JsonObject& args,
                                              JsonObject& out) {
   LoggerD("Enter");
index 8f74e9bbc4e7a0ff1b00ca385beb2fb3452eaabe..1da013281849bb6c8d3d96e5c8cf84cf74e657a8 100755 (executable)
@@ -51,6 +51,9 @@ common::PlatformResult ContactManagerRemove(const JsonObject& args,
 common::PlatformResult ContactManagerFind(const JsonObject& args,
                                           JsonArray& out);
 
+common::PlatformResult ContactManagerFindByUsageCount(const JsonObject& args,
+                                                      JsonArray& out);
+
 common::PlatformResult ContactManagerImportFromVCard(const JsonObject& args,
                                                      JsonObject& out);
 
index c00b9ad890c15895affd9946321cdff7adcf90ed..12123c31c8060aed76564a4d9904edcfc52ba91c 100755 (executable)
@@ -409,6 +409,76 @@ ContactManager.prototype.find = function() {
   _checkError(result);
 };
 
+ContactManager.prototype.findByUsageCount = function() {
+  var args = validator_.validateArgs(arguments, [
+    {
+      name: 'filter',
+      type: types_.PLATFORM_OBJECT,
+      values: [tizen.AttributeFilter,
+        tizen.AttributeRangeFilter],
+        optional: false,
+        nullable: false
+    },
+    {
+      name: 'successCallback',
+      type: types_.FUNCTION,
+      optional: false,
+      nullable: false
+    },
+    {
+      name: 'errorCallback',
+      type: types_.FUNCTION,
+      optional: true,
+      nullable: true
+    },
+    {
+      name: 'sortModeOrder',
+      type: types_.ENUM,
+      values: ['ASC', 'DESC'],
+      optional: true,
+      nullable: true
+    },
+    {
+      name: 'limit',
+      type: types_.UNSIGNED_LONG,
+      optional: true,
+      nullable: true
+    },
+    {
+      name: 'offset',
+      type: types_.UNSIGNED_LONG,
+      optional: true,
+      nullable: true
+    }
+  ]);
+
+  var data = {
+    filter: utils_.repackFilter(args.filter),
+    sortModeOrder: args.sortModeOrder,
+    limit: args.limit,
+    offset: args.offset
+  };
+
+  var self = this;
+
+  var callback = function(result) {
+    if (native_.isSuccess(result)) {
+      var _result = native_.getResultObject(result);
+      var retval = [];
+      for (var i = 0; i < _result.length; ++i) {
+        retval.push(self.get(String(_result[i])));
+      }
+      args.successCallback(retval);
+    } else {
+      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+    }
+  };
+
+  var result = native_.call('ContactManager_findByUsageCount', data, callback);
+
+  _checkError(result);
+};
+
 // Subscribes to receive notifications about persons' changes.
 ContactManager.prototype.addChangeListener = function() {
   var args = validator_.validateArgs(arguments, [