TizenRefApp-7253 Implement Person Comparator for the Search 24/90124/1
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Tue, 27 Sep 2016 08:40:29 +0000 (11:40 +0300)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Wed, 28 Sep 2016 10:48:58 +0000 (13:48 +0300)
Change-Id: Ic5d9ba12a1d240efa43841539871dc54206cd365
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
lib-contacts/inc/Contacts/List/Model/Person.h
lib-contacts/inc/Contacts/List/Model/PersonComparator.h [new file with mode: 0644]
lib-contacts/src/Contacts/List/Model/PersonComparator.cpp [new file with mode: 0644]

index 982630e..e879d1e 100644 (file)
@@ -50,9 +50,14 @@ namespace Contacts
                                 */
                                enum PersonField
                                {
-                                       PersonFieldSortValue = FieldMax, /**< Sort value*/
-                                       PersonFieldContact,              /**< Contact field */
-                                       PersonFieldMax                   /**< Sentinel value */
+                                       FieldSortValue = FieldMax, /**< Sort value*/
+                                       FieldContact,              /**< Contact field */
+                                       FieldCompany,              /* FIXME: Move contact fields to corresponding object */
+                                       FieldEmail,
+                                       FieldAddress,
+                                       FieldNickname,
+                                       FieldNote,
+                                       PersonFieldMax             /**< Sentinel value */
                                };
 
                                /**
@@ -61,8 +66,8 @@ namespace Contacts
                                 */
                                enum PersonChangedInfo
                                {
-                                       ChangedSortValue = 1 << PersonFieldSortValue,   /**< Sort value has changed */
-                                       ChangedContact   = 1 << PersonFieldContact      /**< Whole contact has changed */
+                                       ChangedSortValue = 1 << FieldSortValue,   /**< Sort value has changed */
+                                       ChangedContact   = 1 << FieldContact      /**< Whole contact has changed */
                                };
 
                                /**
diff --git a/lib-contacts/inc/Contacts/List/Model/PersonComparator.h b/lib-contacts/inc/Contacts/List/Model/PersonComparator.h
new file mode 100644 (file)
index 0000000..c548f44
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015-2016 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 CONTACTS_LIST_MODEL_PERSON_COMPARATOR_H
+#define CONTACTS_LIST_MODEL_PERSON_COMPARATOR_H
+
+#include "Model2/SearchData.h"
+#include "Contacts/List/Model/Person.h"
+
+namespace Contacts
+{
+       namespace List
+       {
+               namespace Model
+               {
+                       class PersonComparator
+                       {
+                       public:
+                               /**
+                                * @see Model2::SearchComparator
+                                */
+                               Model2::SearchResultPtr operator()(const Person &, const std::string &);
+
+                       private:
+                               typedef Model2::SearchResultPtr (*Comparator)(const Person &, const std::string &);
+
+                               static Model2::SearchResultPtr compareName(const Person &person, const std::string &str);
+                               static Model2::SearchResultPtr compareNickname(const Person &person, const std::string &str);
+                               static Model2::SearchResultPtr compareNote(const Person &person, const std::string &str);
+                               static Model2::SearchResultPtr compareOrganization(const Person &person, const std::string &str);
+                               static Model2::SearchResultPtr compareAddress(const Person &person, const std::string &str);
+                               static Model2::SearchResultPtr compareEmail(const Person &person, const std::string &str);
+                               static Model2::SearchResultPtr compareNumber(const Person &person, const std::string &str);
+
+                               static Model2::SearchResultPtr caseCompare(const char *fieldValue, const std::string &str,
+                                               int matchedField);
+                               static Model2::SearchResultPtr fieldsCompare(Person::ContactChildRecords records, unsigned propertyId,
+                                               const std::string &str, int matchedField);
+
+                               static Comparator getCompFunc(size_t i);
+                       };
+               }
+       }
+}
+
+#endif /* CONTACTS_LIST_MODEL_PERSON_COMPARATOR_H */
diff --git a/lib-contacts/src/Contacts/List/Model/PersonComparator.cpp b/lib-contacts/src/Contacts/List/Model/PersonComparator.cpp
new file mode 100644 (file)
index 0000000..7d6b00d
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2015-2016 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 "Contacts/List/Model/PersonComparator.h"
+#include "Common/Database/RecordUtils.h"
+
+#include <cstring>
+
+using namespace Model2;
+using namespace Contacts::Model;
+using namespace Contacts::List::Model;
+using namespace Common::Database;
+using namespace std::placeholders;
+
+namespace
+{
+       enum PersonSubField
+       {
+               PersonName,
+               PersonNickname,
+               PersonOrganization,
+               PersonAddress,
+               PersonEmail,
+               PersonNote,
+               PersonNumber,
+               PersonMax
+       };
+}
+
+SearchResultPtr PersonComparator::operator()(const Person &person, const std::string &str)
+{
+       if (str.empty()) {
+               return SearchResultPtr(new SearchResult());
+       }
+
+       for (size_t subField = PersonName; subField < PersonMax; ++subField) {
+               SearchResultPtr result = getCompFunc(subField)(person, str);
+               if (result) {
+                       return result;
+               }
+       }
+
+       return nullptr;
+}
+
+SearchResultPtr PersonComparator::compareName(const Person &person, const std::string &str)
+{
+       const char *name = person.getName();
+       while (name && *name) {
+               const char *delim = strchr(name, ' ');
+
+               if (strncasecmp(name, str.c_str(), str.size()) == 0) {
+                       return SearchResultPtr(new SearchResult(Person::FieldName, person.getName(), { name, str.size() }));
+               }
+
+               if (delim) {
+                       name = delim + 1;
+               } else {
+                       return nullptr;
+               }
+       }
+
+       return nullptr;
+}
+
+SearchResultPtr PersonComparator::compareNickname(const Person &person, const std::string &str)
+{
+       return caseCompare(person.getNickname(), str, Person::FieldNickname);
+}
+
+SearchResultPtr PersonComparator::compareNote(const Person &person, const std::string &str)
+{
+       return caseCompare(person.getNote(), str, Person::FieldNote);
+}
+
+SearchResultPtr PersonComparator::compareOrganization(const Person &person, const std::string &str)
+{
+       contacts_record_h record = person.getOrganization();
+       auto nameResult = caseCompare(getRecordStr(record, _contacts_company.name), str, Person::FieldCompany);
+
+       return nameResult ? std::move(nameResult) :
+               std::move(caseCompare(getRecordStr(record, _contacts_company.job_title), str, Person::FieldCompany));
+}
+
+SearchResultPtr PersonComparator::compareAddress(const Person &person, const std::string &str)
+{
+       return fieldsCompare(person.getAddresses(), _contacts_address.street, str, Person::FieldAddress);
+}
+
+SearchResultPtr PersonComparator::compareEmail(const Person &person, const std::string &str)
+{
+       return fieldsCompare(person.getEmails(), _contacts_email.email, str, Person::FieldEmail);
+}
+
+SearchResultPtr PersonComparator::compareNumber(const Person &person, const std::string &str)
+{
+       for (auto &&numberRange : person.getNumbers()) {
+               for (auto &&numberRecord : numberRange) {
+                       const char *number = getRecordStr(numberRecord, _contacts_number.number);
+                       const char *pos = strstr(number, str.c_str());
+
+                       if (pos) {
+                               return SearchResultPtr(new SearchResult(Person::FieldNumber, number, { pos, str.size() }));
+                       }
+
+               }
+       }
+
+       return nullptr;
+}
+
+SearchResultPtr PersonComparator::caseCompare(const char *fieldValue, const std::string &str, int matchedField)
+{
+       if (fieldValue) {
+               if (strncasecmp(fieldValue, str.c_str(), str.size()) == 0) {
+                       return SearchResultPtr(new SearchResult(matchedField, fieldValue, { fieldValue, str.size() }));
+               }
+       }
+
+       return nullptr;
+}
+
+SearchResultPtr PersonComparator::fieldsCompare(Person::ContactChildRecords records,
+               unsigned propertyId, const std::string &str, int matchedField)
+{
+       for (auto &&range : records) {
+               for (auto &&record : range) {
+                       SearchResultPtr result = caseCompare(getRecordStr(record, propertyId), str, matchedField);
+                       if (result) {
+                               return result;
+                       }
+               }
+       }
+
+       return nullptr;
+}
+
+PersonComparator::Comparator PersonComparator::getCompFunc(size_t i)
+{
+       static Comparator comparators[] = {
+               /* PersonName         = */ &PersonComparator::compareName,
+               /* PersonNickname     = */ &PersonComparator::compareNickname,
+               /* PersonOrganization = */ &PersonComparator::compareOrganization,
+               /* PersonAddress      = */ &PersonComparator::compareAddress,
+               /* PersonEmail        = */ &PersonComparator::compareEmail,
+               /* PersonNote         = */ &PersonComparator::compareNote,
+               /* PersonNumber       = */ &PersonComparator::compareNumber,
+       };
+
+       return comparators[i];
+}