Update change log and spec for wrt-plugins-tizen_0.4.50
[framework/web/wrt-plugins-tizen.git] / src / Contact / ContactSearchEngine.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        ContactSearchEngine.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @brief
23  */
24
25 #include "ContactSearchEngine.h"
26
27 #include <contacts.h>
28 #include <ctime>
29 #include <algorithm>
30 #include <limits>
31 #include <iomanip>
32 #include <Commons/Exception.h>
33 #include "Contact.h"
34 #include "ContactObjectP2AConverter.h"
35 #include "ContactUtility.h"
36 #include <Logger.h>
37
38 #define _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter) \
39         do { \
40                 if((errorCode = contacts_query_create(view_uri, &query)) != CONTACTS_ERROR_NONE) \
41                         ThrowMsg(PlatformException, "contacts_query_create error : " << errorCode << " (" << __FUNCTION__ << ")"); \
42                 if((errorCode = contacts_filter_create(view_uri, &filter)) != CONTACTS_ERROR_NONE) \
43                         ThrowMsg(PlatformException, "contacts_filter_create error : " << errorCode << " (" << __FUNCTION__ << ")"); \
44         } while(0)
45
46 #define _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result) \
47         do { \
48                 if((errorCode = contacts_query_set_filter(query, filter)) != CONTACTS_ERROR_NONE) \
49                         ThrowMsg(PlatformException, "contacts_query_set_filter error : " << errorCode << " (" << __FUNCTION__ << ")"); \
50                 if((errorCode = contacts_db_get_records_with_query(query, 0, 0, &list)) != CONTACTS_ERROR_NONE) \
51                         ThrowMsg(PlatformException, "contacts_db_get_records_with_query error : " << errorCode << " (" << __FUNCTION__ << ")"); \
52                 unsigned int record_count = 0; \
53                 if((errorCode = contacts_list_get_count(list, &record_count)) != CONTACTS_ERROR_NONE) \
54                         ThrowMsg(PlatformException, "contacts_list_get_count error : " << errorCode << " (" << __FUNCTION__ << ")"); \
55                 contacts_list_first(list); \
56                 for(unsigned int i=0; i<record_count; i++) { \
57                         contacts_record_h record; \
58                         if((errorCode = contacts_list_get_current_record_p(list, &record)) != CONTACTS_ERROR_NONE) \
59                                 ThrowMsg(PlatformException, "contacts_list_get_current_record_p error : " << errorCode << " (" << __FUNCTION__ << ")"); \
60                         int value = 0; \
61                         if((errorCode = contacts_record_get_int(record, property_contact_id, &value)) != CONTACTS_ERROR_NONE) \
62                                 ThrowMsg(PlatformException, "contacts_record_get_int error : " << errorCode << " (" << __FUNCTION__ << ")"); \
63                         result->insert(value); \
64                         contacts_list_next(list); \
65                 } \
66                 if(list != NULL) \
67                         contacts_list_destroy(list, true); \
68                 if(filter != NULL) \
69                         contacts_filter_destroy(filter); \
70                 if(query != NULL) \
71                         contacts_query_destroy(query); \
72         } while(0)
73
74
75 namespace DeviceAPI {
76 namespace Contact {
77
78 using namespace WrtDeviceApis::Commons;
79 using namespace DeviceAPI::Tizen;
80 using namespace std;
81
82 ContactSearchEngine::AttributePropertiesMap ContactSearchEngine::attributePropertiesMap = {
83                 {"id",                      { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
84                 {"personId",                { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.person_id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
85                 {"addressBookId",           { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.address_book_id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
86                 {"lastUpdated",             { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.changed_time, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Time } },
87                 {"isFavorite",              { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.is_favorite, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
88                 {"name.prefix",             { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.prefix, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
89                 {"name.suffix",             { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.suffix, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
90                 {"name.firstName",          { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.first, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
91                 {"name.middleName",         { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.addition, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
92                 {"name.lastName",           { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.last, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
93                 {"name.nicknames",          { _contacts_nickname._uri, _contacts_nickname.contact_id, _contacts_nickname.name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
94                 {"name.phoneticFirstName",  { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_first, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
95                 {"name.phoneticMiddleName",  { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_middle, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
96                 {"name.phoneticLastName",   { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_last, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
97                 {"name.displayName",        { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.display_name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
98                 {"addresses.country",       { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.country, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
99                 {"addresses.region",        { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.region, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
100                 {"addresses.city",          { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.locality, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
101                 {"addresses.streetAddress", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.street, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
102                 {"addresses.additionalInformation", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.extended, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
103                 {"addresses.postalCode",    { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.postal_code, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
104                 {"addresses.isDefault",     { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.is_default, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
105                 {"addresses.types",         { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
106                 {"photoURI",                { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.image_thumbnail_path, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
107                 {"phoneNumbers.number",     { _contacts_number._uri, _contacts_number.contact_id, _contacts_number.number, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
108                 {"phoneNumbers.isDefault",  { _contacts_number._uri, _contacts_number.contact_id, _contacts_number.is_default, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
109                 {"phoneNumbers.types",      { _contacts_number._uri, _contacts_number.contact_id, _contacts_number.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
110                 {"emails.email",            { _contacts_email._uri, _contacts_email.contact_id, _contacts_email.email, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
111                 {"emails.isDefault",        { _contacts_email._uri, _contacts_email.contact_id, _contacts_email.is_default, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
112                 {"emails.types",            { _contacts_email._uri, _contacts_email.contact_id, _contacts_email.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
113                 {"birthday",                { _contacts_event._uri, _contacts_event.contact_id, _contacts_event.date, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
114                 {"anniversaries.date",      { _contacts_event._uri, _contacts_event.contact_id, _contacts_event.date, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
115                 {"anniversaries.label",     { _contacts_event._uri, _contacts_event.contact_id, _contacts_event.label, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
116                 {"organizations.name",      { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
117                 {"organizations.department",{ _contacts_company._uri, _contacts_company.contact_id, _contacts_company.department, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
118                 {"organizations.title",     { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.job_title, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
119                 {"organizations.role",      { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.role, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
120                 {"organizations.logoURI",   { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.logo, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
121                 {"organizations.assistant", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.assistant_name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
122                 {"organizations.location",  { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.location, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
123                 {"organizations.description",  { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.description, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
124                 {"organizations.phoneticName", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.phonetic_name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
125                 {"organizations.type",      { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.type, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_Long } },
126                 {"notes",                   { _contacts_note._uri, _contacts_note.contact_id, _contacts_note.note, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
127                 {"urls.url",                { _contacts_url._uri, _contacts_url.contact_id, _contacts_url.url, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
128                 {"urls.type",               { _contacts_url._uri, _contacts_url.contact_id, _contacts_url.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
129                 {"ringtoneURI",             { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.ringtone_path, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
130                 {"groupIds",                { _contacts_group_relation._uri, _contacts_group_relation.contact_id, _contacts_group_relation.group_id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } }
131 };
132
133 ContactSearchEngine::ContactSearchEngine() :
134                 m_addressBookId(0),
135                 m_isAddressBookIdSet(false),
136                 m_isFilterSet(false),
137                 m_isSortModeSet(false),
138                 m_sortOrder(ASCENDING_SORT_ORDER)
139 {
140 }
141
142 ContactSearchEngine::~ContactSearchEngine()
143 {
144 }
145
146 void ContactSearchEngine::setAddressBookId(int id)
147 {
148         m_addressBookId = id;
149         m_isAddressBookIdSet = true;
150 }
151
152 void ContactSearchEngine::setCondition(FilterPtr filter)
153 {
154         if(!filter)
155                 return;
156
157         IFilterVisitorPtr filterQuery = DPL::StaticPointerCast<IFilterVisitor>(SharedFromThis());
158         filter->travel(filterQuery);
159
160         if(m_filteredContactIds != NULL)
161                 m_isFilterSet = true;
162 }
163
164 void ContactSearchEngine::setSortMode(SortModePtr attr)
165 {
166         if(!attr)
167                 return;
168
169         m_sortOrder = attr->getOrder();
170         m_attributeNameForSort = attr->getAttributeName();
171
172         AttributePropertiesMap::iterator iter =
173                         attributePropertiesMap.find(m_attributeNameForSort);
174         if(iter == attributePropertiesMap.end())
175                 ThrowMsg(NotFoundException, "There is no attribute name for sorting : " << m_attributeNameForSort);
176
177         m_isSortModeSet = true;
178 }
179
180 ContactArrayPtr ContactSearchEngine::getContactSearchResult()
181 {
182         ContactArrayPtr result(NULL);
183         unsigned int length = 0;
184
185         LoggerD("entered");
186         if(m_isFilterSet)
187         {
188                 if(m_isSortModeSet)
189                 {
190                         ContactIdArrayPtr ids = ContactIdArrayPtr(new ContactIdArray());
191
192                         AttributePropertiesMap::iterator iter =
193                                         attributePropertiesMap.find(m_attributeNameForSort);
194                         AttributeProperties &property = iter->second;
195
196                         length = m_filteredContactIds->size();
197                         LoggerD("length : " << length);
198
199                         if(length != 0)
200                         {
201                                 if(m_sortOrder == ASCENDING_SORT_ORDER)
202                                         sortContacts(property, ids, true, m_filteredContactIds);
203                                 else
204                                         sortContacts(property, ids, false, m_filteredContactIds);
205
206                                 result = getContacts(ids);
207                         }else{
208                                 ContactArrayPtr contacts(new ContactArray());
209                                 result = contacts;
210                         }
211                 }
212                 else
213                 {
214                         length = m_filteredContactIds->size();
215                         LoggerD("length : " << length);
216                         if(length != 0)
217                         {
218                                 result = getContacts(m_filteredContactIds);
219                         }else{
220                                 ContactArrayPtr contacts(new ContactArray());
221                                 result = contacts;
222                         }
223                 }
224         }
225         else
226         {
227                 if(m_isSortModeSet)
228                 {
229                         AttributePropertiesMap::iterator iter =
230                                         attributePropertiesMap.find(m_attributeNameForSort);
231                         AttributeProperties &property = iter->second;
232
233                         if(m_sortOrder == ASCENDING_SORT_ORDER)
234                                 result = getAllContactsSorted(property, true);
235                         else
236                                 result = getAllContactsSorted(property, false);
237                 }
238                 else
239                 {
240                         result = getAllContacts();
241                 }
242         }
243         LoggerD("End");
244
245         return result;
246 }
247
248 void ContactSearchEngine::visitPreComposite(FilterType& type, int depth)
249 {
250         ContactIdSetArrayPtr idSets = ContactIdSetArrayPtr(new ContactIdSetArray());
251
252         m_contactIdSetArrayStack.push(idSets);
253 }
254
255 void ContactSearchEngine::visitInComposite(FilterType& type, int depth)
256 {
257         // Nothing to do
258 }
259
260 void ContactSearchEngine::visitPostComposite(FilterType& type, int depth)
261 {
262         ContactIdSetArrayPtr idSets = m_contactIdSetArrayStack.top();
263         m_contactIdSetArrayStack.pop();
264
265         ContactIdSetPtr idSet = ContactIdSetPtr(new ContactIdSet());
266
267         if(type == UNION_FILTER)
268                 getUnion(idSets, idSet);
269         else if(type == INTERSECTION_FILTER)
270                 getIntersection(idSets, idSet);
271
272         if(depth == 0)
273         {
274                 m_filteredContactIds = idSet;
275         }
276         else
277         {
278                 if(idSet != NULL)
279                 {
280                         ContactIdSetArrayPtr parentIdSets = m_contactIdSetArrayStack.top();
281                         parentIdSets->push_back(idSet);
282                 }
283         }
284 }
285
286 void ContactSearchEngine::visitAttribute(string& attrName, MatchFlag& matchFlag, AnyPtr& matchValue, int depth)
287 {
288         if(matchValue == NULL || matchValue->isNullOrUndefined())
289                 matchFlag = MATCH_EXISTS;
290
291         ContactIdSetPtr idSet = ContactIdSetPtr(new ContactIdSet());
292
293         if(attrName == "id")
294         {
295                 if(matchFlag != MATCH_EXISTS){
296                         string value = matchValue->getString();
297                         idSet->insert(ContactUtility::strToInt(value));
298
299                         if(depth == 0)
300                                 m_filteredContactIds = idSet;
301                         else
302                         {
303                                 ContactIdSetArrayPtr parentIdSets = m_contactIdSetArrayStack.top();
304                                 parentIdSets->push_back(idSet);
305                         }
306                 }
307
308                 return;
309         }
310         else if(attrName == "addresses.types" ||
311                         attrName == "emails.types" ||
312                         attrName == "phoneNumbers.types" ||
313                         attrName == "urls.type")
314         {
315                 if(depth == 0)
316                         m_filteredContactIds = ContactIdSetPtr(NULL);
317
318                 return;
319         }
320
321         AttributePropertiesMap::iterator iter =
322                         attributePropertiesMap.find(attrName);
323         if(iter == attributePropertiesMap.end())
324                 ThrowMsg(NotFoundException, "There is no attribute name for filter : " << attrName);
325         AttributeProperties &properties = iter->second;
326
327         if(properties.type == ContactSvcPrimitiveType_Boolean)
328         {
329                 bool value = true;
330                 if(matchFlag != MATCH_EXISTS)
331                         value = matchValue->getBool();
332
333                 queryAttributeBool(properties, idSet, value);
334         }
335         else if(properties.type == ContactSvcPrimitiveType_String)
336         {
337                 string value;
338
339                 if(matchFlag != MATCH_EXISTS)
340                 {
341                         if(attrName == "photoURI" || attrName == "ringtoneURI" || attrName == "organizations.logoURI")
342                                 value = ContactUtility::convertUriToPath(matchValue->getString());
343                         else
344                                 value = matchValue->getString();
345                 }else
346                         value = "";
347
348                 contacts_match_str_flag_e flag = CONTACTS_MATCH_EXISTS;
349
350                 if(matchFlag == MATCH_EXACTLY)
351                         flag = CONTACTS_MATCH_EXACTLY;
352                 else if(matchFlag == MATCH_FULLSTRING)
353                         flag = CONTACTS_MATCH_FULLSTRING;
354                 else if(matchFlag == MATCH_CONTAINS)
355                         flag = CONTACTS_MATCH_CONTAINS;
356                 else if(matchFlag == MATCH_STARTSWITH)
357                         flag = CONTACTS_MATCH_STARTSWITH;
358                 else if(matchFlag == MATCH_ENDSWITH)
359                         flag = CONTACTS_MATCH_ENDSWITH;
360                 else if(matchFlag == MATCH_EXISTS)
361                         flag = CONTACTS_MATCH_EXISTS;
362
363                 queryAttributeString(properties, idSet, flag, value.c_str());
364         }
365         else if(properties.type == ContactSvcPrimitiveType_Int)
366         {
367                 int value;
368
369                 if(matchFlag != MATCH_EXISTS)
370                 {
371                         if(attrName == "id" || attrName == "personId"){
372                                 value = ContactUtility::strToInt(matchValue->getString());
373                         }else if(attrName == "lastUpdated"){
374                                 time_t tmpTime = mktime(matchValue->getDateTm());
375                                 value = (int)tmpTime;
376                         }else if(attrName == "birthday" || attrName == "anniversaries.date"){
377                                 value = ContactUtility::toDateDbInt(*matchValue->getDateTm());
378                         }else{
379                                 value = matchValue->getLong();
380                         }
381                 }
382
383                 contacts_match_int_flag_e flag;
384                 if(matchFlag == MATCH_EXISTS)
385                 {
386                         flag = CONTACTS_MATCH_GREATER_THAN_OR_EQUAL;
387                         value = 0;
388                 }else if(matchFlag == MATCH_STARTSWITH || matchFlag == MATCH_CONTAINS){
389                         flag = CONTACTS_MATCH_GREATER_THAN_OR_EQUAL;
390                 }else if(matchFlag == MATCH_ENDSWITH){
391                         flag = CONTACTS_MATCH_LESS_THAN_OR_EQUAL;
392                 }else{
393                         flag = CONTACTS_MATCH_EQUAL;
394                 }
395
396                 if(attrName == "birthday" || attrName == "anniversaries.date"){
397                         queryAttributeDate(attrName, properties, idSet, flag, value);
398                 }else{
399                         queryAttributeInt(properties, idSet, flag, value);
400                 }
401
402         }
403
404         if(depth == 0)
405         {
406                 m_filteredContactIds = idSet;
407         }
408         else
409         {
410                 if(idSet != NULL)
411                 {
412                         ContactIdSetArrayPtr parentIdSets = m_contactIdSetArrayStack.top();
413                         parentIdSets->push_back(idSet);
414                 }
415         }
416 }
417
418 void ContactSearchEngine::visitAttributeRange(string& attrName, AnyPtr& initialValue, AnyPtr& endValue, int depth)
419 {
420         ContactIdSetPtr idSet = ContactIdSetPtr(new ContactIdSet());
421
422         bool initialValueIsSet = false;
423         bool endValueIsSet = false;
424
425         if(initialValue != NULL || initialValue->isNullOrUndefined())
426                 initialValueIsSet = false;
427
428         if(endValue != NULL || endValue->isNullOrUndefined())
429                 endValueIsSet = false;
430
431         if(!initialValueIsSet && !endValueIsSet)
432         {
433                 if(depth == 0)
434                         m_filteredContactIds = ContactIdSetPtr(NULL);
435
436                 return;
437         }
438
439         if(attrName == "id")
440         {
441                 if(depth == 0)
442                         m_filteredContactIds = idSet;
443                 else
444                 {
445                         ContactIdSetArrayPtr parentIdSets = m_contactIdSetArrayStack.top();
446                         parentIdSets->push_back(idSet);
447                 }
448
449                 return;
450         }
451         else if(attrName == "addresses.types" ||
452                         attrName == "emails.types" ||
453                         attrName == "phoneNumbers.types" ||
454                         attrName == "urls.type")
455         {
456                 if(depth == 0)
457                         m_filteredContactIds = ContactIdSetPtr(NULL);
458
459                 return;
460         }
461
462         AttributePropertiesMap::iterator iter =
463                         attributePropertiesMap.find(attrName);
464         if(iter == attributePropertiesMap.end())
465                 ThrowMsg(NotFoundException, "There is no attribute name for filter : " << attrName);
466         AttributeProperties &properties = iter->second;
467
468         if(properties.type == ContactSvcPrimitiveType_Boolean)
469         {
470                 bool initialValueBool = false;
471                 bool endValueBool = false;
472
473                 if(initialValueIsSet)
474                         initialValueBool = initialValue->getBool();
475                 if(endValueIsSet)
476                         endValueBool = endValue->getBool();
477
478                 queryAttributeRangeBool(properties, idSet, initialValueIsSet, initialValueBool, endValueIsSet, endValueBool);
479         }
480         else if(properties.type == ContactSvcPrimitiveType_String)
481         {
482                 const char *initialValueCStr = NULL;
483                 const char *endValueCStr = NULL;
484
485                 string initialValueStr;
486                 string endValueStr;
487
488                 if(initialValueIsSet)
489                 {
490                         initialValueStr = initialValue->getString();
491                         initialValueCStr = initialValueStr.c_str();
492                 }
493                 if(endValueIsSet)
494                 {
495                         endValueStr = endValue->getString();
496                         endValueCStr = endValueStr.c_str();
497                 }
498
499                 queryAttributeRangeString(properties, idSet, initialValueCStr, endValueCStr);
500         }
501         else if(properties.type == ContactSvcPrimitiveType_Int)
502         {
503                 int initialValueInt = 0;
504                 int endValueInt = 0;
505
506                 if(attrName == "id" || attrName == "personId")
507                 {
508                         if(initialValueIsSet)
509                                 initialValueInt = ContactUtility::strToInt(initialValue->getString());
510                         if(endValueIsSet)
511                                 endValueInt = ContactUtility::strToInt(endValue->getString());
512                 }
513                 else if(attrName == "lastUpdated"){
514                         if(initialValueIsSet){
515                                 time_t tmpTime = mktime(initialValue->getDateTm());
516                                 initialValueInt = (int)tmpTime;
517                         }
518                         if(endValueIsSet){
519                                 time_t tmpTime = mktime(endValue->getDateTm());
520                                 endValueInt = (int)tmpTime;
521                         }
522                 }else if(attrName == "birthday" || attrName == "anniversaries.date"){
523                         if(initialValueIsSet){
524                                 initialValueInt = ContactUtility::toDateDbInt(*initialValue->getDateTm());
525                         }
526                         if(endValueIsSet){
527                                 endValueInt = ContactUtility::toDateDbInt(*initialValue->getDateTm());
528                         }
529                 }
530                 else
531                 {
532                         if(initialValueIsSet)
533                                 initialValueInt = initialValue->getLong();
534                         if(endValueIsSet)
535                                 endValueInt = endValue->getLong();
536                 }
537
538                 queryAttributeRangeInt(properties, idSet, initialValueIsSet, initialValueInt, endValueIsSet, endValueInt);
539         }
540
541         if(depth == 0)
542         {
543                 m_filteredContactIds = idSet;
544         }
545         else
546         {
547                 ContactIdSetArrayPtr parentIdSets = m_contactIdSetArrayStack.top();
548                 parentIdSets->push_back(idSet);
549         }
550 }
551
552 ContactArrayPtr ContactSearchEngine::getAllContactsSorted(AttributeProperties& attributeProperties, bool is_ascending)
553 {
554         ContactArrayPtr contacts = ContactArrayPtr(new ContactArray());
555
556         ContactArrayPtr allContacts = getAllContacts();
557         ContactIdArrayPtr sortedIds = ContactIdArrayPtr(new ContactIdArray());
558
559         sortContacts(attributeProperties, sortedIds, is_ascending);
560
561         map<int,ContactPtr> contactMap;
562
563         ContactArray::iterator citer;
564         for(citer=allContacts->begin(); citer!=allContacts->end(); citer++)
565         {
566                 ContactPtr contact = *citer;
567                 int id = ContactUtility::strToInt(contact->getId());
568                 contactMap.insert(pair<int,ContactPtr>(id, contact));
569         }
570
571         ContactIdArray::iterator iter;
572         for(iter=sortedIds->begin(); iter!=sortedIds->end(); iter++)
573         {
574                 int id = *iter;
575
576                 map<int,ContactPtr>::iterator idPair = contactMap.find(id);
577                 if(idPair == contactMap.end())
578                 {
579                         LoggerW("no contact id : " << id);
580                         continue;
581                 }
582                 contacts->push_back(idPair->second);
583         }
584
585         return contacts;
586 }
587
588 ContactArrayPtr ContactSearchEngine::getAllContacts()
589 {
590         int errorCode = 0;
591
592         ContactArrayPtr contacts(new ContactArray());
593         contacts_list_h list = NULL;
594
595         if(!m_isAddressBookIdSet)
596         {
597                 errorCode = contacts_db_get_all_records(_contacts_contact._uri, 0, 0, &list);
598                 if(errorCode != CONTACTS_ERROR_NONE)
599                         ThrowMsg(PlatformException, "contacts_db_get_all_records error : " << errorCode << " (" << __FUNCTION__ << ")");
600         }
601         else
602         {
603                 contacts_query_h query = NULL;
604                 contacts_filter_h filter = NULL;
605
606                 errorCode = contacts_query_create(_contacts_contact._uri, &query);
607                 if(errorCode != CONTACTS_ERROR_NONE)
608                         ThrowMsg(PlatformException, "Fail to get contacts_query_create (ret:" << errorCode << ")");
609
610                 errorCode = contacts_filter_create(_contacts_contact._uri, &filter);
611                 if(errorCode != CONTACTS_ERROR_NONE)
612                         ThrowMsg(PlatformException, "Fail to get contacts_filter_create (ret:" << errorCode << ")");
613
614                 errorCode = contacts_filter_add_int(filter, _contacts_contact.address_book_id, CONTACTS_MATCH_EQUAL, m_addressBookId);
615                 if(errorCode != CONTACTS_ERROR_NONE)
616                         ThrowMsg(PlatformException, "Fail to get contacts_filter_add_int (ret:" << errorCode << ")");
617
618                 errorCode = contacts_query_set_filter(query, filter);
619                 if(errorCode != CONTACTS_ERROR_NONE)
620                         ThrowMsg(PlatformException, "Fail to get contacts_query_set_filter (ret:" << errorCode << ")");
621
622                 errorCode = contacts_db_get_records_with_query(query, 0, 0, &list);
623                 if(errorCode != CONTACTS_ERROR_NONE)
624                         ThrowMsg(PlatformException, "Fail to get contacts_db_get_records_with_query (ret:" << errorCode << ")");
625
626                 errorCode = contacts_filter_destroy(filter);
627                 if(errorCode != CONTACTS_ERROR_NONE)
628                         ThrowMsg(PlatformException, "Fail to get contacts_filter_destroy (ret:" << errorCode << ")");
629
630                 errorCode = contacts_query_destroy(query);
631                 if(errorCode != CONTACTS_ERROR_NONE)
632                         ThrowMsg(PlatformException, "Fail to get contacts_query_destroy (ret:" << errorCode << ")");
633         }
634
635         unsigned int record_count = 0;
636         errorCode = contacts_list_get_count(list, &record_count);
637         if(errorCode != CONTACTS_ERROR_NONE)
638                 ThrowMsg(PlatformException, "Fail to get contacts_list_get_count : " << errorCode << " (" << __FUNCTION__ << ")");
639         LoggerD("END: pure contact-svc");
640
641         contacts_list_first(list);
642         for(unsigned int i=0; i<record_count; i++)
643         {
644                 contacts_record_h record;
645                 errorCode = contacts_list_get_current_record_p(list, &record);
646                 if(errorCode != CONTACTS_ERROR_NONE || record == NULL)
647                 {
648                         LoggerW("contacts_list_get_current_record_p error : " << errorCode << " (" << __FUNCTION__ << ")");
649                         continue;
650                 }
651
652                 ContactPtr contact(NULL);
653                 Try
654                 {
655                         ContactObjectP2AConverterPtr contactObjConverter(
656                                         new ContactObjectP2AConverter(record, false));
657
658                         contact = contactObjConverter->getAbstractContact();
659                 }
660                 Catch(Exception)
661                 {
662                         LoggerW("fail to convert contact");
663                         continue;
664                 }
665
666                 contacts->push_back(contact);
667
668                 contacts_list_next(list);
669         }
670
671         if(list != NULL)
672                 contacts_list_destroy(list, true);
673
674         LoggerD("END: convertToPlugin Objects");
675
676         return contacts;
677 }
678
679 ContactArrayPtr ContactSearchEngine::getContacts(ContactIdArrayPtr& ids)
680 {
681         ContactArrayPtr contacts(new ContactArray());
682
683         ContactIdArray::iterator iter;
684         for(iter=ids->begin(); iter!=ids->end(); iter++)
685         {
686                 Try
687                 {
688                         ContactPtr contact = getContact(*iter);
689                         if(contact != NULL)
690                                 contacts->push_back(contact);
691                 }
692                 Catch(Exception)
693                 {
694                         LoggerW(_rethrown_exception.GetMessage());
695                         continue;
696                 }
697         }
698
699         return contacts;
700 }
701
702 ContactArrayPtr ContactSearchEngine::getContacts(ContactIdSetPtr& ids)
703 {
704         ContactArrayPtr contacts(new ContactArray());
705
706         ContactIdSet::iterator iter;
707         for(iter=ids->begin(); iter!=ids->end(); iter++)
708         {
709                 Try
710                 {
711                         ContactPtr contact = getContact(*iter);
712                         if(contact != NULL)
713                                 contacts->push_back(contact);
714                 }
715                 Catch(Exception)
716                 {
717                         LoggerW(_rethrown_exception.GetMessage());
718                         continue;
719                 }
720         }
721         return contacts;
722 }
723
724 ContactPtr ContactSearchEngine::getContact(int id)
725 {
726         int errorCode = 0;
727         contacts_record_h record = NULL;
728
729         errorCode = contacts_db_get_record(_contacts_contact._uri, id, &record);
730         if(errorCode != CONTACTS_ERROR_NONE)
731         {
732                 LoggerE("No contact 1 : " << errorCode << " (" << __FUNCTION__ << ")");
733                 return ContactPtr(NULL);
734         }
735
736         if(m_isAddressBookIdSet)
737         {
738                 int addressBookId = 0;
739
740                 errorCode = contacts_record_get_int(record, _contacts_contact.address_book_id, &addressBookId);
741                 if(errorCode != CONTACTS_ERROR_NONE)
742                 {
743                         LoggerE("No contact 2 : " << errorCode << " (" << __FUNCTION__ << ")");
744                         return ContactPtr(NULL);
745                 }
746
747                 if(addressBookId != m_addressBookId)
748                         return ContactPtr(NULL);
749         }
750
751         ContactObjectP2AConverterPtr contactObjConverter(
752                         new ContactObjectP2AConverter(record, false));
753         ContactPtr contact = contactObjConverter->getAbstractContact();
754
755         return contact;
756 }
757
758 void ContactSearchEngine::queryAttributeBool(AttributeProperties& attributeProperties, ContactIdSetPtr& result,
759                 bool match_value)
760 {
761         const char* view_uri = attributeProperties.viewUri;
762         unsigned int property_contact_id = attributeProperties.propertyContactId;
763         unsigned int property_id = attributeProperties.propertyId;
764
765         int errorCode = 0;
766         contacts_query_h query = NULL;
767         contacts_filter_h filter = NULL;
768         contacts_list_h list = NULL;
769
770         _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter);
771
772         errorCode = contacts_filter_add_bool(filter, property_id, match_value);
773         if(errorCode != CONTACTS_ERROR_NONE)
774         {
775                 ThrowMsg(PlatformException, "contacts_filter_add_bool error : " << errorCode << " (" << __FUNCTION__ << ")");
776         }
777
778         _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result);
779 }
780
781 void ContactSearchEngine::queryAttributeInt(AttributeProperties& attributeProperties, ContactIdSetPtr& result,
782                 contacts_match_int_flag_e match, int match_value)
783 {
784         const char* view_uri = attributeProperties.viewUri;
785         unsigned int property_contact_id = attributeProperties.propertyContactId;
786         unsigned int property_id = attributeProperties.propertyId;
787
788         int errorCode = 0;
789         contacts_query_h query = NULL;
790         contacts_filter_h filter = NULL;
791         contacts_list_h list = NULL;
792
793         _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter);
794
795         errorCode = contacts_filter_add_int(filter, property_id, match, match_value);
796         if(errorCode != CONTACTS_ERROR_NONE)
797         {
798                 ThrowMsg(PlatformException, "contacts_filter_add_int error : " << errorCode << " (" << __FUNCTION__ << ")");
799         }
800
801         _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result);
802 }
803
804 void ContactSearchEngine::queryAttributeDate(string& attrName, AttributeProperties& attributeProperties, ContactIdSetPtr& result,
805                 contacts_match_int_flag_e match, int match_value)
806 {
807         const char* view_uri = attributeProperties.viewUri;
808         unsigned int property_contact_id = attributeProperties.propertyContactId;
809         unsigned int property_id = attributeProperties.propertyId;
810
811         int errorCode = 0;
812         contacts_query_h query = NULL;
813         contacts_filter_h filter = NULL;
814         contacts_list_h list = NULL;
815
816         _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter);
817
818         errorCode = contacts_filter_add_int(filter, property_id, match, match_value);
819         if(errorCode != CONTACTS_ERROR_NONE)
820                 ThrowMsg(PlatformException, "contacts_filter_add_int error : " << errorCode << " (" << __FUNCTION__ << ")");
821
822         LoggerD("attrName" << attrName);
823
824         if(attrName == "birthday"){
825                 errorCode = contacts_filter_add_operator( filter, CONTACTS_FILTER_OPERATOR_AND);
826                 if(errorCode != CONTACTS_ERROR_NONE)
827                         ThrowMsg(PlatformException, "contacts_filter_add_int error : " << errorCode << " (" << __FUNCTION__ << ")");
828
829                 errorCode = contacts_filter_add_int(filter, _contacts_event.type, CONTACTS_MATCH_EQUAL, CONTACTS_EVENT_TYPE_BIRTH);
830                 if(errorCode != CONTACTS_ERROR_NONE)
831                         ThrowMsg(PlatformException, "contacts_filter_add_int error : " << errorCode << " (" << __FUNCTION__ << ")");
832
833         }else if(attrName == "anniversaries.date"){
834                 errorCode = contacts_filter_add_operator( filter, CONTACTS_FILTER_OPERATOR_AND);
835                 if(errorCode != CONTACTS_ERROR_NONE)
836                         ThrowMsg(PlatformException, "contacts_filter_add_int error : " << errorCode << " (" << __FUNCTION__ << ")");
837
838                 errorCode = contacts_filter_add_int(filter, _contacts_event.type, CONTACTS_MATCH_EQUAL, CONTACTS_EVENT_TYPE_ANNIVERSARY);
839                 if(errorCode != CONTACTS_ERROR_NONE)
840                         ThrowMsg(PlatformException, "contacts_filter_add_int error : " << errorCode << " (" << __FUNCTION__ << ")");
841         }
842
843         _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result);
844 }
845
846 void ContactSearchEngine::queryAttributeString(AttributeProperties& attributeProperties, ContactIdSetPtr& result,
847                 contacts_match_str_flag_e match, const char* match_value)
848 {
849         const char* view_uri = attributeProperties.viewUri;
850         unsigned int property_contact_id = attributeProperties.propertyContactId;
851         unsigned int property_id = attributeProperties.propertyId;
852
853         int errorCode = 0;
854         contacts_query_h query = NULL;
855         contacts_filter_h filter = NULL;
856         contacts_list_h list = NULL;
857
858         _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter);
859
860         errorCode = contacts_filter_add_str(filter, property_id, match, match_value);
861         if(errorCode != CONTACTS_ERROR_NONE)
862         {
863                 ThrowMsg(PlatformException, "contacts_filter_add_int error : " << errorCode << " (" << __FUNCTION__ << ")");
864         }
865
866         _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result);
867 }
868
869 void ContactSearchEngine::queryAttributeRangeBool(AttributeProperties& attributeProperties, ContactIdSetPtr& result,
870                 bool initial_value_is_set, bool initial_value, bool end_value_is_set, bool end_value)
871 {
872         const char* view_uri = attributeProperties.viewUri;
873         unsigned int property_contact_id = attributeProperties.propertyContactId;
874         unsigned int property_id = attributeProperties.propertyId;
875
876         int errorCode = 0;
877         contacts_query_h query = NULL;
878         contacts_filter_h filter = NULL;
879         contacts_list_h list = NULL;
880
881         _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter);
882
883         if(initial_value_is_set && end_value_is_set)
884         {
885                 if(initial_value == end_value)
886                 {
887                         if(initial_value == true)
888                                 errorCode = contacts_filter_add_bool(filter, property_id, true);
889                         else if(end_value == false)
890                                 errorCode = contacts_filter_add_bool(filter, property_id, false);
891                 }
892         }
893         else if(initial_value_is_set)
894         {
895                 if(initial_value == true)
896                         errorCode = contacts_filter_add_bool(filter, property_id, true);
897         }
898         else if(end_value_is_set)
899         {
900                 if(end_value == false)
901                         errorCode = contacts_filter_add_bool(filter, property_id, false);
902         }
903
904         _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result);
905 }
906
907 void ContactSearchEngine::queryAttributeRangeInt(AttributeProperties& attributeProperties, ContactIdSetPtr& result,
908                 bool initial_value_is_set, int initial_value, bool end_value_is_set, int end_value)
909 {
910         const char* view_uri = attributeProperties.viewUri;
911         unsigned int property_contact_id = attributeProperties.propertyContactId;
912         unsigned int property_id = attributeProperties.propertyId;
913
914         int errorCode = 0;
915         contacts_query_h query = NULL;
916         contacts_filter_h filter = NULL;
917         contacts_list_h list = NULL;
918
919         _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter);
920
921         if(initial_value_is_set && end_value_is_set)
922         {
923                 contacts_filter_h sub_filter = NULL;
924
925                 errorCode = contacts_filter_create(_contacts_person._uri, &sub_filter);
926
927                 errorCode = contacts_filter_add_int(sub_filter, property_id,
928                                 CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initial_value);
929
930                 contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
931
932                 errorCode = contacts_filter_add_int(sub_filter, property_id,
933                                 CONTACTS_MATCH_LESS_THAN_OR_EQUAL, end_value);
934
935                 errorCode = contacts_filter_add_filter(filter, sub_filter);
936         }
937         else if(initial_value_is_set)
938         {
939                 errorCode = contacts_filter_add_int(filter, property_id,
940                                 CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initial_value);
941         }
942         else if(end_value_is_set)
943         {
944                 errorCode = contacts_filter_add_int(filter, property_id,
945                                 CONTACTS_MATCH_LESS_THAN_OR_EQUAL, end_value);
946         }
947
948         _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result);
949 }
950
951 void ContactSearchEngine::queryAttributeRangeString(AttributeProperties& attributeProperties, ContactIdSetPtr& result,
952                 const char* initial_value, const char* end_value)
953
954 {
955         const char* view_uri = attributeProperties.viewUri;
956         unsigned int property_contact_id = attributeProperties.propertyContactId;
957         unsigned int property_id = attributeProperties.propertyId;
958         LoggerD("entered");
959
960         int errorCode = 0;
961         contacts_query_h query = NULL;
962         contacts_filter_h filter = NULL;
963         contacts_list_h list = NULL;
964
965         _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter);
966
967         if(initial_value != NULL && end_value != NULL)
968         {
969                 contacts_filter_h sub_filter = NULL;
970
971                 errorCode = contacts_filter_create(view_uri, &sub_filter);
972
973                 // TODO To be supported start
974                 errorCode = contacts_filter_add_str(sub_filter, property_id,
975                                 CONTACTS_MATCH_STARTSWITH, initial_value);
976
977                 contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
978
979                 errorCode = contacts_filter_add_str(sub_filter, property_id,
980                                 CONTACTS_MATCH_ENDSWITH, end_value);
981
982                 errorCode = contacts_filter_add_filter(filter, sub_filter);
983         }
984         else if(initial_value != NULL)
985         {
986                 errorCode = contacts_filter_add_str(filter, property_id,
987                                 CONTACTS_MATCH_STARTSWITH, initial_value);
988         }
989         else if(end_value != NULL)
990         {
991                 errorCode = contacts_filter_add_str(filter, property_id,
992                                 CONTACTS_MATCH_ENDSWITH, end_value);
993         }
994
995         _CONTACTS_SVC_QUERY_FUNC_SUFFIX(query, filter, list, property_contact_id, result);
996         LoggerD("end");
997 }
998
999 #if 0
1000 void ContactSearchEngine::sortContacts(AttributeProperties& attributeProperties, ContactIdArrayPtr& result,
1001                 bool is_ascending, ContactIdSetPtr& idSet)
1002 {
1003         const char* view_uri = attributeProperties.viewUri;
1004         unsigned int property_contact_id = attributeProperties.propertyContactId;
1005         unsigned int property_id = attributeProperties.propertyId;
1006
1007         LogDebug("entered");
1008
1009         int errorCode = 0;
1010         contacts_query_h query = NULL;
1011         contacts_list_h list = NULL;
1012
1013         errorCode = contacts_query_create(view_uri, &query);
1014         if(errorCode != CONTACTS_ERROR_NONE)
1015                 ThrowMsg(PlatformException, "contacts_query_create error : " << errorCode << " (" << __FUNCTION__ << ")");
1016
1017         errorCode = contacts_query_set_sort(query, property_id, is_ascending);
1018         if(errorCode != CONTACTS_ERROR_NONE)
1019                 ThrowMsg(PlatformException, "contacts_query_set_sort error : " << errorCode << " (" << __FUNCTION__ << ")");
1020
1021         errorCode = contacts_db_get_records_with_query(query, 0, 0, &list);
1022         if(errorCode != CONTACTS_ERROR_NONE)
1023                 ThrowMsg(PlatformException, "contacts_db_get_records_with_query error : " << errorCode << " (" << __FUNCTION__ << ")");
1024
1025         unsigned int record_count = 0;
1026         errorCode = contacts_list_get_count(list, &record_count);
1027         if(errorCode != CONTACTS_ERROR_NONE)
1028                 ThrowMsg(PlatformException, "contacts_list_get_count error : " << errorCode << " (" << __FUNCTION__ << ")");
1029
1030         std::set<int>::iterator it;
1031
1032         contacts_list_first(list);
1033         for(unsigned int i=0; i<record_count; i++)
1034         {
1035                 contacts_record_h record;
1036                 errorCode = contacts_list_get_current_record_p(list, &record);
1037                 if(errorCode != CONTACTS_ERROR_NONE)
1038                         ThrowMsg(PlatformException, "contacts_list_get_current_record_p error : " << errorCode << " (" << __FUNCTION__ << ")");
1039
1040                 int value = 0;
1041                 errorCode = contacts_record_get_int(record, property_contact_id, &value);
1042                 if(errorCode  != CONTACTS_ERROR_NONE)
1043                         ThrowMsg(PlatformException, "contacts_record_get_int error : " << errorCode << " (" << __FUNCTION__ << ")");
1044
1045                 it = idSet->find(value);
1046                 if(it != idSet->end())
1047                         result->push_back(value);
1048
1049                 contacts_list_next(list);
1050         }
1051
1052         if(list != NULL)
1053                 contacts_list_destroy(list, true);
1054
1055         if(query != NULL)
1056                 contacts_query_destroy(query);
1057
1058         LogDebug("end");
1059 }
1060 #endif
1061
1062 void ContactSearchEngine::sortContacts(AttributeProperties& attributeProperties, ContactIdArrayPtr& result,
1063                 bool is_ascending, ContactIdSetPtr& idSet)
1064 {
1065         const char* view_uri = attributeProperties.viewUri;
1066         unsigned int property_contact_id = attributeProperties.propertyContactId;
1067         unsigned int property_id = attributeProperties.propertyId;
1068
1069         LoggerD("entered");
1070
1071         int errorCode = 0;
1072         contacts_query_h query = NULL;
1073         contacts_filter_h filter = NULL;
1074         contacts_list_h list = NULL;
1075
1076         errorCode = contacts_query_create(view_uri, &query);
1077         if(errorCode != CONTACTS_ERROR_NONE)
1078                 ThrowMsg(PlatformException, "contacts_query_create error : " << errorCode << " (" << __FUNCTION__ << ")");
1079
1080         errorCode = contacts_filter_create(view_uri, &filter);
1081         if(errorCode != CONTACTS_ERROR_NONE)
1082                 ThrowMsg(PlatformException, "contacts_filter_create error : " << errorCode << " (" << __FUNCTION__ << ")");
1083
1084         ContactIdSet::iterator iter = idSet->begin();
1085         if(iter != idSet->end())
1086         {
1087                 errorCode = contacts_filter_add_int(filter, property_contact_id, CONTACTS_MATCH_EQUAL, *iter);
1088                 for(; iter!=idSet->end(); iter++)
1089                 {
1090                         errorCode = contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR);
1091                         if(errorCode != CONTACTS_ERROR_NONE)
1092                                 ThrowMsg(PlatformException, "contacts_filter_add_operator error : " << errorCode << " (" << __FUNCTION__ << ")");
1093
1094                         errorCode = contacts_filter_add_int(filter, property_contact_id, CONTACTS_MATCH_EQUAL, *iter);
1095                         if(errorCode != CONTACTS_ERROR_NONE)
1096                                 ThrowMsg(PlatformException, "contacts_query_create error : " << errorCode << " (" << __FUNCTION__ << ")");
1097                 }
1098         }
1099
1100         errorCode = contacts_query_set_sort(query, property_id, is_ascending);
1101         if(errorCode != CONTACTS_ERROR_NONE)
1102                 ThrowMsg(PlatformException, "contacts_query_set_sort error : " << errorCode << " (" << __FUNCTION__ << ")");
1103
1104         errorCode = contacts_query_set_filter(query, filter);
1105         if(errorCode != CONTACTS_ERROR_NONE)
1106                 ThrowMsg(PlatformException, "contacts_query_set_filter error : " << errorCode << " (" << __FUNCTION__ << ")");
1107
1108         errorCode = contacts_db_get_records_with_query(query, 0, 0, &list);
1109         if(errorCode != CONTACTS_ERROR_NONE)
1110                 ThrowMsg(PlatformException, "contacts_db_get_records_with_query error : " << errorCode << " (" << __FUNCTION__ << ")");
1111
1112         unsigned int record_count = 0;
1113         errorCode = contacts_list_get_count(list, &record_count);
1114         if(errorCode != CONTACTS_ERROR_NONE)
1115                 ThrowMsg(PlatformException, "contacts_list_get_count error : " << errorCode << " (" << __FUNCTION__ << ")");
1116
1117         ContactIdSet overlappingIds;
1118
1119         contacts_list_first(list);
1120         for(unsigned int i=0; i<record_count; i++)
1121         {
1122                 contacts_record_h record;
1123                 errorCode = contacts_list_get_current_record_p(list, &record);
1124                 if(errorCode != CONTACTS_ERROR_NONE)
1125                         ThrowMsg(PlatformException, "contacts_list_get_current_record_p error : " << errorCode << " (" << __FUNCTION__ << ")");
1126
1127                 int value = 0;
1128                 errorCode = contacts_record_get_int(record, property_contact_id, &value);
1129                 if(errorCode  != CONTACTS_ERROR_NONE)
1130                         ThrowMsg(PlatformException, "contacts_record_get_int error : " << errorCode << " (" << __FUNCTION__ << ")");
1131
1132                 if(overlappingIds.find(value) == overlappingIds.end())
1133                 {
1134                         result->push_back(value);
1135                         overlappingIds.insert(value);
1136                 }
1137
1138                 contacts_list_next(list);
1139         }
1140
1141         if(list != NULL)
1142                 contacts_list_destroy(list, true);
1143
1144         if(filter != NULL)
1145                 contacts_filter_destroy(filter);
1146
1147         if(query != NULL)
1148                 contacts_query_destroy(query);
1149
1150         LoggerD("end");
1151 }
1152
1153 void ContactSearchEngine::sortContacts(AttributeProperties& attributeProperties, ContactIdArrayPtr& result,
1154                 bool is_ascending)
1155 {
1156         const char* view_uri = attributeProperties.viewUri;
1157         unsigned int property_contact_id = attributeProperties.propertyContactId;
1158         unsigned int property_id = attributeProperties.propertyId;
1159
1160         int errorCode = 0;
1161         contacts_query_h query = NULL;
1162         contacts_list_h list = NULL;
1163
1164         errorCode = contacts_query_create(view_uri, &query);
1165         if(errorCode != CONTACTS_ERROR_NONE)
1166                 ThrowMsg(PlatformException, "contacts_query_create error : " << errorCode << " (" << __FUNCTION__ << ")");
1167
1168         errorCode = contacts_query_set_sort(query, property_id, is_ascending);
1169         if(errorCode != CONTACTS_ERROR_NONE)
1170                 ThrowMsg(PlatformException, "contacts_query_set_sort error : " << errorCode << " (" << __FUNCTION__ << ")");
1171
1172         errorCode = contacts_db_get_records_with_query(query, 0, 0, &list);
1173         if(errorCode != CONTACTS_ERROR_NONE)
1174                 ThrowMsg(PlatformException, "contacts_db_get_records_with_query error : " << errorCode << " (" << __FUNCTION__ << ")");
1175
1176         unsigned int record_count = 0;
1177         errorCode = contacts_list_get_count(list, &record_count);
1178         if(errorCode != CONTACTS_ERROR_NONE)
1179                 ThrowMsg(PlatformException, "contacts_list_get_count error : " << errorCode << " (" << __FUNCTION__ << ")");
1180
1181         ContactIdSet overlappingIds;
1182
1183         contacts_list_first(list);
1184         for(unsigned int i=0; i<record_count; i++)
1185         {
1186                 contacts_record_h record;
1187                 errorCode = contacts_list_get_current_record_p(list, &record);
1188                 if(errorCode != CONTACTS_ERROR_NONE)
1189                         ThrowMsg(PlatformException, "contacts_list_get_current_record_p error : " << errorCode << " (" << __FUNCTION__ << ")");
1190
1191                 int value = 0;
1192                 errorCode = contacts_record_get_int(record, property_contact_id, &value);
1193                 if(errorCode  != CONTACTS_ERROR_NONE)
1194                         ThrowMsg(PlatformException, "contacts_record_get_int error : " << errorCode << " (" << __FUNCTION__ << ")");
1195
1196                 if(overlappingIds.find(value) == overlappingIds.end())
1197                 {
1198                         result->push_back(value);
1199                         overlappingIds.insert(value);
1200                 }
1201
1202                 contacts_list_next(list);
1203         }
1204
1205         if(list != NULL)
1206                 contacts_list_destroy(list, true);
1207
1208         if(query != NULL)
1209                 contacts_query_destroy(query);
1210 }
1211
1212 void ContactSearchEngine::getIntersection(ContactIdSetArrayPtr& idSets, ContactIdSetPtr& result)
1213 {
1214         ContactIdSetArray::iterator i;
1215
1216         if(idSets->size() == 0)
1217         {
1218                 result = ContactIdSetPtr(NULL);
1219                 return;
1220         }
1221         else if(idSets->size() == 1)
1222         {
1223                 *result = **idSets->begin();
1224                 return;
1225         }
1226
1227         ContactIdSetArray::iterator minIter;
1228         ContactIdSetArray::size_type minSize =
1229                         numeric_limits<ContactIdSetArray::size_type>::max();
1230
1231         for(i=idSets->begin(); i!=idSets->end(); i++)
1232         {
1233                 ContactIdSetPtr idSet = *i;
1234                 ContactIdSetArray::size_type size = idSet->size();
1235                 if(minSize > size)
1236                 {
1237                         minSize = size;
1238                         minIter = i;
1239                 }
1240         }
1241
1242         ContactIdSetPtr p = *minIter;
1243         ContactIdSetArrayPtr sa = ContactIdSetArrayPtr(new ContactIdSetArray());
1244         for(i=idSets->begin(); i!=idSets->end(); i++)
1245         {
1246                 if(minIter != i)
1247                 {
1248                         sa->push_back(*i);
1249                 }
1250         }
1251
1252         ContactIdSet::iterator iter;
1253         for(iter=p->begin(); iter!=p->end(); iter++)
1254         {
1255                 bool excluded = false;
1256                 int value = *iter;
1257
1258                 for(i=sa->begin(); i!=sa->end(); i++)
1259                 {
1260                         ContactIdSetPtr idSet = *i;
1261                         if(idSet->find(value) == idSet->end())
1262                         {
1263                                 excluded = true;
1264                                 break;
1265                         }
1266                 }
1267
1268                 if(excluded == false)
1269                 {
1270                         result->insert(value);
1271                 }
1272         }
1273 }
1274
1275 void ContactSearchEngine::getUnion(ContactIdSetArrayPtr& idSets, ContactIdSetPtr& result)
1276 {
1277         ContactIdSetArray::iterator i;
1278
1279         if(idSets->size() == 0)
1280         {
1281                 result = ContactIdSetPtr(NULL);
1282                 return;
1283         }
1284         else if(idSets->size() == 1)
1285         {
1286                 *result = **idSets->begin();
1287                 return;
1288         }
1289
1290         for(i=idSets->begin(); i!=idSets->end(); i++)
1291         {
1292                 ContactIdSetPtr ids = *i;
1293                 ContactIdSet::iterator j;
1294                 for(j=ids->begin(); j!=ids->end(); j++)
1295                 {
1296                         result->insert(*j);
1297                 }
1298         }
1299 }
1300
1301 } // Contact
1302 } // DeviceAPI