REGISTER_SYNC("ContactManager_updateBatch", ContactManager_updateBatch);
REGISTER_SYNC("ContactManager_remove", ContactManager_remove);
REGISTER_SYNC("ContactManager_removeBatch", ContactManager_removeBatch);
- REGISTER_SYNC("ContactManager_find", ContactManager_find);
+ REGISTER_ASYNC("ContactManager_find", ContactManager_find);
REGISTER_SYNC("ContactManager_importFromVCard", ContactManager_importFromVCard);
REGISTER_SYNC("ContactManager_startListening", ContactManager_startListening);
REGISTER_SYNC("ContactManager_stopListening", ContactManager_stopListening);
auto get_response = [this, callback_id](const std::shared_ptr <JsonValue>& response) {
picojson::object& obj = response->get<picojson::object>();
obj.insert(std::make_pair("callbackId", callback_id));
- LoggerD("response is %s", response->serialize().c_str());
PostMessage(response->serialize().c_str());
};
ReportSuccess(val, out);
}
-void ContactInstance::ContactManager_update(const JsonValue& args,
- JsonObject& out) {
+void ContactInstance::ContactManager_update(const JsonValue& args, JsonObject& out) {
JsonValue val{JsonObject{}};
- ContactManager::ContactManager_update(common::JsonCast<JsonObject>(args),
- val.get<JsonObject>());
+ ContactManager::ContactManager_update(common::JsonCast<JsonObject>(args), val.get<JsonObject>());
ReportSuccess(out);
}
-void ContactInstance::ContactManager_updateBatch(const JsonValue& args,
- JsonObject& out) {
+void ContactInstance::ContactManager_updateBatch(const JsonValue& args, JsonObject& out) {
// @todo implement
}
-void ContactInstance::ContactManager_remove(const JsonValue& args,
- JsonObject& out) {
+void ContactInstance::ContactManager_remove(const JsonValue& args, JsonObject& out) {
JsonValue val{JsonObject{}};
- ContactManager::ContactManager_remove(common::JsonCast<JsonObject>(args),
- val.get<JsonObject>());
+ ContactManager::ContactManager_remove(common::JsonCast<JsonObject>(args), val.get<JsonObject>());
ReportSuccess(out);
}
-void ContactInstance::ContactManager_removeBatch(const JsonValue& args,
- JsonObject& out) {
+void ContactInstance::ContactManager_removeBatch(const JsonValue& args, JsonObject& out) {
// @todo implement
}
-void ContactInstance::ContactManager_find(const JsonValue& args,
- JsonObject& out) {
- // @todo implement
+void ContactInstance::ContactManager_find(const JsonValue &args, JsonObject &out) {
+ LoggerD("entered");
+
+ const double callback_id = args.get("callbackId").get<double>();
+
+ auto get = [this, args](const std::shared_ptr <JsonValue> &response) -> void {
+ try {
+ JsonValue result = JsonValue(JsonArray());
+ ContactManager::ContactManager_find(common::JsonCast<JsonObject>(args),
+ result.get<JsonArray>());
+ ReportSuccess(result, response->get<picojson::object>());
+ } catch (const PlatformException &e) {
+ ReportError(e, response->get<picojson::object>());
+ }
+ };
+
+ auto get_response = [this, callback_id](const std::shared_ptr <JsonValue> &response) {
+ picojson::object &obj = response->get<picojson::object>();
+ obj.insert(std::make_pair("callbackId", callback_id));
+ PostMessage(response->serialize().c_str());
+ };
+
+ TaskQueue::GetInstance().Queue<JsonValue>(get, get_response,
+ std::shared_ptr<JsonValue>(new JsonValue(JsonObject())));
}
-void ContactInstance::ContactManager_importFromVCard(const JsonValue& args,
- JsonObject& out) {
+void ContactInstance::ContactManager_importFromVCard(const JsonValue& args, JsonObject& out) {
JsonValue val{JsonObject{}};
ContactManager::ContactManager_importFromVCard(
common::JsonCast<JsonObject>(args), val.get<JsonObject>());
#include "common/converter.h"
#include "common/picojson.h"
#include "common/logger.h"
+#include "common/filter-utils.h"
#include <contacts.h>
#include "contact/contact_instance.h"
}
}
-void ContactManager_find(const JsonObject& args, JsonObject& out) {
+void ContactManager_find(const JsonObject &args, JsonArray &out) {
ContactUtil::CheckDBConnection();
- // @todo implement
- throw common::NotFoundException("Not implemented");
+ contacts_query_h contacts_query = nullptr;
+ int error_code = contacts_query_create(_contacts_person._uri, &contacts_query);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_create");
+
+ ContactUtil::ContactsQueryHPtr contacts_query_ptr(&contacts_query,
+ ContactUtil::ContactsQueryDeleter);
+
+ // Add filter to query
+ std::vector<std::vector<ContactUtil::ContactsFilterPtr>> intermediate_filters(1);
+ if (!IsNull(args, "filter")) {
+ FilterVisitor visitor;
+ visitor.SetOnAttributeFilter([&](const std::string &name,
+ AttributeMatchFlag match_flag,
+ const JsonValue &match_value) {
+
+ const Person::PersonProperty &property = Person::PersonProperty_fromString(name);
+
+ contacts_filter_h contacts_filter = nullptr;
+ int error_code = contacts_filter_create(_contacts_person._uri, &contacts_filter);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_filter");
+ ContactUtil::ContactsFilterPtr contacts_filter_ptr(
+ contacts_filter, ContactUtil::ContactsFilterDeleter);
+
+ if (property.type == kPrimitiveTypeBoolean) {
+ bool value = true;
+ if (AttributeMatchFlag::kExists != match_flag) {
+ value = JsonCast<bool>(match_value);
+ }
+ error_code = contacts_filter_add_bool(contacts_filter, property.propertyId, value);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_bool");
+ } else if (property.type == kPrimitiveTypeString) {
+ std::string value = JsonCast<std::string>(match_value);
+
+ contacts_match_str_flag_e flag = CONTACTS_MATCH_EXISTS;
+ if (AttributeMatchFlag::kExactly == match_flag) {
+ flag = CONTACTS_MATCH_EXACTLY;
+ } else if (AttributeMatchFlag::kFullString == match_flag) {
+ flag = CONTACTS_MATCH_FULLSTRING;
+ } else if (AttributeMatchFlag::kContains == match_flag) {
+ flag = CONTACTS_MATCH_CONTAINS;
+ } else if (AttributeMatchFlag::kStartsWith == match_flag) {
+ flag = CONTACTS_MATCH_STARTSWITH;
+ } else if (AttributeMatchFlag::kEndsWith == match_flag) {
+ flag = CONTACTS_MATCH_ENDSWITH;
+ } else if (AttributeMatchFlag::kExists == match_flag) {
+ flag = CONTACTS_MATCH_EXISTS;
+ value = "";
+ }
+ error_code = contacts_filter_add_str(contacts_filter, property.propertyId,
+ flag, value.c_str());
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+ } else if (property.type == kPrimitiveTypeLong ||
+ property.type == kPrimitiveTypeId) {
+ int value;
+ if (property.type == kPrimitiveTypeLong) {
+ value = static_cast<int>(JsonCast<double>(match_value));
+ } else {
+ value = common::stol(JsonCast<std::string>(match_value));
+ }
+ if (value < 0) {
+ throw InvalidValuesException("Match value cannot be less than 0");
+ }
+ contacts_match_int_flag_e flag;
+ if (AttributeMatchFlag::kExists == match_flag) {
+ flag = CONTACTS_MATCH_GREATER_THAN_OR_EQUAL;
+ value = 0;
+ } else if (AttributeMatchFlag::kStartsWith == match_flag ||
+ AttributeMatchFlag::kContains == match_flag) {
+ flag = CONTACTS_MATCH_GREATER_THAN_OR_EQUAL;
+ } else if (AttributeMatchFlag::kEndsWith == match_flag) {
+ flag = CONTACTS_MATCH_LESS_THAN_OR_EQUAL;
+ } else {
+ flag = CONTACTS_MATCH_EQUAL;
+ }
+
+ error_code = contacts_filter_add_int(contacts_filter, property.propertyId, flag, value);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+ } else {
+ throw UnknownException("Invalid primitive type!");
+ }
+ intermediate_filters[intermediate_filters.size() - 1]
+ .push_back(std::move(contacts_filter_ptr));
+ });
+
+ visitor.SetOnAttributeRangeFilter([&](const std::string &name,
+ const JsonValue &initial_value,
+ const JsonValue &end_value) {
+
+ const Person::PersonProperty &property = Person::PersonProperty_fromString(name);
+
+ contacts_filter_h contacts_filter = nullptr;
+ int error_code = contacts_filter_create(_contacts_person._uri, &contacts_filter);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_filter");
+ ContactUtil::ContactsFilterPtr contacts_filter_ptr(
+ contacts_filter, ContactUtil::ContactsFilterDeleter);
+
+ bool initial_value_exists = (!IsNull(initial_value));
+ bool end_value_exists = (!IsNull(end_value));
+
+ if (property.type == kPrimitiveTypeBoolean) {
+ bool initial_value_bool = false;
+ bool end_value_bool = false;
+
+ if (initial_value_exists) {
+ initial_value_bool = JsonCast<bool>(initial_value);
+ }
+ if (end_value_exists) {
+ end_value_bool = JsonCast<bool>(end_value);
+ }
+
+ if (initial_value_exists && end_value_exists) {
+ if (initial_value_bool == end_value_bool) {
+ error_code = contacts_filter_add_bool(
+ contacts_filter, property.propertyId, initial_value_bool);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_bool");
+ }
+ } else if (initial_value_exists) {
+ if (initial_value_bool) {
+ error_code = contacts_filter_add_bool(contacts_filter, property.propertyId, true);
+ ContactUtil::ErrorChecker(error_code,
+ "Failed contacts_filter_add_bool");
+ }
+ } else if (end_value_exists) {
+ if (!end_value_bool) {
+ error_code = contacts_filter_add_bool(contacts_filter, property.propertyId, false);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_bool");
+ }
+ }
+ } else if (property.type == kPrimitiveTypeString) {
+ std::string initial_value_str;
+ std::string end_value_str;
+
+ if (initial_value_exists) {
+ initial_value_str = JsonCast<std::string>(initial_value);
+ }
+
+ if (end_value_exists) {
+ end_value_str = JsonCast<std::string>(end_value);
+ }
+
+ if (initial_value_exists && end_value_exists) {
+ contacts_filter_h sub_filter = NULL;
+
+ error_code = contacts_filter_create(_contacts_person._uri, &sub_filter);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+
+ ContactUtil::ContactsFilterPtr sub_filter_ptr(
+ sub_filter, ContactUtil::ContactsFilterDeleter);
+
+ error_code = contacts_filter_add_str(sub_filter, property.propertyId,
+ CONTACTS_MATCH_STARTSWITH,
+ initial_value_str.c_str());
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+ error_code = contacts_filter_add_operator(sub_filter,
+ CONTACTS_FILTER_OPERATOR_AND);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+
+ error_code = contacts_filter_add_str(sub_filter, property.propertyId,
+ CONTACTS_MATCH_ENDSWITH,
+ end_value_str.c_str());
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+
+ error_code = contacts_filter_add_filter(contacts_filter, sub_filter);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+ } else if (initial_value_exists) {
+ error_code = contacts_filter_add_str(
+ contacts_filter, property.propertyId, CONTACTS_MATCH_STARTSWITH,
+ initial_value_str.c_str());
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+ } else if (end_value_exists) {
+ error_code = contacts_filter_add_str(
+ contacts_filter, property.propertyId, CONTACTS_MATCH_ENDSWITH,
+ end_value_str.c_str());
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_str");
+ }
+ } else if (property.type == kPrimitiveTypeLong || property.type == kPrimitiveTypeId) {
+ int initial_value_int = 0;
+ int end_value_int = 0;
+
+ if (initial_value_exists) {
+ if (property.type == kPrimitiveTypeLong) {
+ initial_value_int = static_cast<int>(JsonCast<double>(initial_value));
+ } else {
+ initial_value_int = common::stol(JsonCast<std::string>(initial_value));
+ }
+ }
+
+ if (end_value_exists) {
+ if (property.type == kPrimitiveTypeLong) {
+ end_value_int = static_cast<int>(JsonCast<double>(end_value));
+ } else {
+ end_value_int = common::stol(JsonCast<std::string>(end_value));
+ }
+ }
+
+ if (initial_value_exists && end_value_exists) {
+ contacts_filter_h sub_filter = NULL;
+
+ error_code = contacts_filter_create(_contacts_person._uri, &sub_filter);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_bool");
+ ContactUtil::ContactsFilterPtr sub_filter_ptr(
+ sub_filter, ContactUtil::ContactsFilterDeleter);
+
+ error_code = contacts_filter_add_int(
+ sub_filter, property.propertyId,
+ CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initial_value_int);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_int");
+
+ error_code = contacts_filter_add_operator(sub_filter,
+ CONTACTS_FILTER_OPERATOR_AND);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_operator");
+
+ error_code = contacts_filter_add_int(sub_filter, property.propertyId,
+ CONTACTS_MATCH_LESS_THAN_OR_EQUAL,
+ end_value_int);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_int");
+
+ error_code = contacts_filter_add_filter(contacts_filter, sub_filter);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_filter");
+ } else if (initial_value_exists) {
+ error_code = contacts_filter_add_int(
+ contacts_filter, property.propertyId,
+ CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initial_value_int);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_int");
+ } else if (end_value_exists) {
+ error_code = contacts_filter_add_int(
+ contacts_filter, property.propertyId,
+ CONTACTS_MATCH_LESS_THAN_OR_EQUAL, end_value_int);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_filter_add_int");
+ }
+ } else {
+ throw UnknownException("Invalid primitive type!");
+ }
+ intermediate_filters[intermediate_filters.size() - 1]
+ .push_back(std::move(contacts_filter_ptr));
+ });
+
+ visitor.SetOnCompositeFilterBegin([&](CompositeFilterType type) {
+ intermediate_filters.push_back(std::vector<ContactUtil::ContactsFilterPtr>());
+ });
+
+ visitor.SetOnCompositeFilterEnd([&](CompositeFilterType type) {
+ if (intermediate_filters.size() == 0) {
+ throw UnknownException("Reached stack size equal to 0!");
+ }
+
+ contacts_filter_h merged_filter = nullptr;
+ int error_code = contacts_filter_create(_contacts_person._uri, &merged_filter);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_filter");
+ ContactUtil::ContactsFilterPtr merged_filter_ptr(
+ merged_filter, ContactUtil::ContactsFilterDeleter);
+
+ for (std::size_t i = 0; i < intermediate_filters.back().size(); ++i) {
+ error_code = contacts_filter_add_filter(
+ merged_filter, intermediate_filters.back().at(i).get());
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_filter");
+ if (CompositeFilterType::kIntersection == type) {
+ error_code = contacts_filter_add_operator(merged_filter,
+ CONTACTS_FILTER_OPERATOR_AND);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_filter");
+ } else if (CompositeFilterType::kUnion == type) {
+ error_code = contacts_filter_add_operator(merged_filter,
+ CONTACTS_FILTER_OPERATOR_OR);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_filter");
+ } else {
+ throw InvalidValuesException("Invalid union type!");
+ }
+ }
+
+ intermediate_filters.pop_back();
+ intermediate_filters.back().push_back(std::move(merged_filter_ptr));
+ });
+
+ visitor.Visit(FromJson<JsonObject>(args, "filter"));
+ // Should compute only one filter always.
+ if ((intermediate_filters.size() != 1) || (intermediate_filters[0].size() != 1)) {
+ LoggerE("Bad filter evaluation!");
+ throw UnknownException("Bad filter evaluation!");
+ }
+ // Filter is generated
+ error_code = contacts_query_set_filter(contacts_query, intermediate_filters[0][0].get());
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_query_set_filter");
+ }
+
+ contacts_list_h person_list = nullptr;
+ error_code = contacts_db_get_records_with_query(contacts_query, 0, 0, &person_list);
+
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_db_get_records_with_query");
+
+ ContactUtil::ContactsListHPtr person_list_ptr(&person_list, ContactUtil::ContactsListDeleter);
+
+ int record_count = 0;
+ error_code = contacts_list_get_count(person_list, &record_count);
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_list_get_count");
+
+ contacts_list_first(person_list);
+
+ for (unsigned 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 (error_code != CONTACTS_ERROR_NONE || contacts_record == NULL) {
+ LoggerW("Failed group record (ret:%d)", error_code);
+ continue;
+ }
+
+ int id_value = 0;
+ error_code = contacts_record_get_int(contacts_record, _contacts_person.id, &id_value);
+
+ ContactUtil::ErrorChecker(error_code, "Failed contacts_record_get_int");
+
+ out.push_back(JsonValue(static_cast<double>(id_value)));
+
+ contacts_list_next(person_list);
+ }
}
void ContactManager_importFromVCard(const JsonObject& args, JsonObject& out) {