2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file PersonSearchEngine.cpp
20 * @author Kisub Song (kisubs.song@samsung.com)
25 #include "PersonSearchEngine.h"
29 #include <Commons/Exception.h>
31 #include "ContactUtility.h"
32 #include "ContactsSvcObjectConverter.h"
38 using namespace WrtDeviceApis::Commons;
39 using namespace DeviceAPI::Tizen;
42 map<string, PersonSearchEngine::FilterPropertyStruct> PersonSearchEngine::attrEnumMap = {
43 {"id", { _contacts_person.id, PrimitiveType_Long } },
44 {"displayName", { _contacts_person.display_name, PrimitiveType_String } },
45 {"contactCount", { _contacts_person.link_count, PrimitiveType_Long } },
46 {"hasPhoneNumber", { _contacts_person.has_phonenumber, PrimitiveType_Boolean } },
47 {"hasEmail", { _contacts_person.has_email, PrimitiveType_Boolean } },
48 {"isFavorite", { _contacts_person.is_favorite, PrimitiveType_Boolean } },
49 {"photoURI", { _contacts_person.image_thumbnail_path,PrimitiveType_String } },
50 {"ringtoneURI", { _contacts_person.ringtone_path, PrimitiveType_String } },
51 {"displayContactId", { _contacts_person.display_contact_id, PrimitiveType_Long } },
54 PersonSearchEngine::PersonSearchEngine() :
58 contacts_query_create(_contacts_person._uri, &m_query);
61 PersonSearchEngine::~PersonSearchEngine()
64 contacts_filter_destroy(m_filter);
67 contacts_query_destroy(m_query);
70 void PersonSearchEngine::setCondition(FilterPtr filter)
75 IFilterVisitorPtr filterQuery = DPL::StaticPointerCast<IFilterVisitor>(SharedFromThis());
76 filter->travel(filterQuery);
78 contacts_query_set_filter(m_query, m_filter);
81 void PersonSearchEngine::setSortMode(SortModePtr attr)
86 string attrName = attr->getAttributeName();
88 map<string, PersonSearchEngine::FilterPropertyStruct>::iterator iter = attrEnumMap.find(attrName);
89 if(iter == attrEnumMap.end())
91 ThrowMsg(InvalidArgumentException, "SortMode don't support " << attrName);
94 FilterPropertyStruct property = iter->second;
97 if(attr->getOrder() == ASCENDING_SORT_ORDER)
100 is_ascending = false;
102 contacts_query_set_sort(m_query, property.propertyId, is_ascending);
105 PersonArrayPtr PersonSearchEngine::getResult()
108 contacts_list_h person_list = NULL;
110 PersonArrayPtr persons = PersonArrayPtr(new PersonArray());
112 errorCode = contacts_db_get_records_with_query(m_query, 0, 0, &person_list);
113 if(errorCode != CONTACTS_ERROR_NONE)
114 ThrowMsg(PlatformException, "Fail to get contacts_db_get_records_with_query (ret:" << errorCode << ")");
116 unsigned int record_count = 0;
117 errorCode = contacts_list_get_count(person_list, &record_count);
118 if(errorCode != CONTACTS_ERROR_NONE)
119 ThrowMsg(PlatformException, "Fail to get contacts_list_get_count (ret:" << errorCode << ")");
121 contacts_list_first(person_list);
122 for(unsigned int i=0; i<record_count; i++)
124 contacts_record_h contacts_record;
125 errorCode = contacts_list_get_current_record_p(person_list, &contacts_record);
126 if(errorCode != CONTACTS_ERROR_NONE || contacts_record == NULL)
128 LoggerW("Fail to get group record (ret:" << errorCode << ")");
132 PersonPtr person = PersonPtr(new Person());
134 ContactsSvcObjectConverter::convertToAbstract(contacts_record, person);
136 persons->push_back(person);
138 contacts_list_next(person_list);
141 if(person_list != NULL)
142 contacts_list_destroy(person_list, true);
147 void PersonSearchEngine::visitPreComposite(FilterType& type, int depth)
150 contacts_filter_h filter = NULL;
152 errorCode = contacts_filter_create(_contacts_person._uri, &filter);
154 m_filterStack.push(filter);
161 void PersonSearchEngine::visitInComposite(FilterType& type, int depth)
165 contacts_filter_h filter = NULL;
166 contacts_filter_operator_e operator_type = CONTACTS_FILTER_OPERATOR_OR;
168 filter = m_filterStack.top();
170 if(type == UNION_FILTER)
171 operator_type = CONTACTS_FILTER_OPERATOR_OR;
172 else if(type == INTERSECTION_FILTER)
173 operator_type = CONTACTS_FILTER_OPERATOR_AND;
175 errorCode = contacts_filter_add_operator(filter, operator_type);
178 void PersonSearchEngine::visitPostComposite(FilterType& type, int depth)
181 contacts_filter_h filter = NULL;
183 filter = m_filterStack.top();
188 contacts_filter_h parent_filter = NULL;
189 parent_filter = m_filterStack.top();
190 errorCode = contacts_filter_add_filter(parent_filter, filter);
194 void PersonSearchEngine::visitAttribute(string& attrName, MatchFlag& matchFlag, AnyPtr& matchValue, int depth)
197 contacts_filter_h filter = NULL;
199 if(matchValue == NULL || matchValue->isNullOrUndefined())
200 matchFlag = MATCH_EXISTS;
204 filter = m_filterStack.top();
208 errorCode = contacts_filter_create(_contacts_person._uri, &filter);
209 m_filterStack.push(filter);
213 FilterPropertyStruct property = attrEnumMap[attrName];
215 if(property.type == PrimitiveType_Long)
218 if(attrName == "id" || attrName == "displayContactId")
220 if(matchFlag != MATCH_EXISTS){
221 string valueStr = matchValue->getString();
222 value = ContactUtility::strToInt(valueStr);
226 if(matchFlag != MATCH_EXISTS)
227 value = matchValue->getLong();
230 contacts_match_int_flag_e flag;
231 if(matchFlag == MATCH_EXISTS)
233 flag = CONTACTS_MATCH_GREATER_THAN_OR_EQUAL;
235 }else if(matchFlag == MATCH_STARTSWITH || matchFlag == MATCH_CONTAINS){
236 flag = CONTACTS_MATCH_GREATER_THAN_OR_EQUAL;
237 }else if(matchFlag == MATCH_ENDSWITH){
238 flag = CONTACTS_MATCH_LESS_THAN_OR_EQUAL;
240 flag = CONTACTS_MATCH_EQUAL;
243 errorCode = contacts_filter_add_int(filter, property.propertyId, flag, value);
245 else if(property.type == PrimitiveType_String)
248 if(matchFlag != MATCH_EXISTS){
249 if(attrName == "photoURI" || attrName == "ringtoneURI")
250 value = ContactUtility::convertUriToPath(matchValue->getString());
252 value = matchValue->getString();
256 contacts_match_str_flag_e flag = CONTACTS_MATCH_EXISTS;
257 if(matchFlag == MATCH_EXACTLY)
258 flag = CONTACTS_MATCH_EXACTLY;
259 else if(matchFlag == MATCH_FULLSTRING)
260 flag = CONTACTS_MATCH_FULLSTRING;
261 else if(matchFlag == MATCH_CONTAINS)
262 flag = CONTACTS_MATCH_CONTAINS;
263 else if(matchFlag == MATCH_STARTSWITH)
264 flag = CONTACTS_MATCH_STARTSWITH;
265 else if(matchFlag == MATCH_ENDSWITH)
266 flag = CONTACTS_MATCH_ENDSWITH;
267 else if(matchFlag == MATCH_EXISTS)
268 flag = CONTACTS_MATCH_EXISTS;
270 contacts_filter_add_str(filter, property.propertyId, flag, value.c_str());
272 else if(property.type == PrimitiveType_Boolean)
275 if(matchFlag != MATCH_EXISTS)
276 value = matchValue->getBool();
278 errorCode = contacts_filter_add_bool(filter, property.propertyId, value);
282 void PersonSearchEngine::visitAttributeRange(string& attrName, AnyPtr& initialValue, AnyPtr& endValue, int depth)
285 contacts_filter_h filter = NULL;
289 filter = m_filterStack.top();
293 errorCode = contacts_filter_create(_contacts_person._uri, &filter);
294 m_filterStack.push(filter);
298 FilterPropertyStruct property = attrEnumMap[attrName];
300 if(property.type == PrimitiveType_Long)
302 int initialValueInt = 0;
305 bool initialValueExists = false;
306 bool endValueExists = false;
308 if(!initialValue->isNullOrUndefined())
312 string valueStr = initialValue->getString();
313 initialValueInt = ContactUtility::strToInt(valueStr);
316 initialValueInt = initialValue->getLong();
318 initialValueExists = true;
321 if(!endValue->isNullOrUndefined())
325 string valueStr = endValue->getString();
326 endValueInt = ContactUtility::strToInt(valueStr);
329 endValueInt = endValue->getLong();
331 endValueExists = true;
335 if(initialValueExists && endValueExists)
337 contacts_filter_h sub_filter = NULL;
340 errorCode = contacts_filter_create(_contacts_person._uri, &sub_filter);
347 errorCode = contacts_filter_add_int(sub_filter, property.propertyId,
348 CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initialValueInt);
350 contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
352 errorCode = contacts_filter_add_int(sub_filter, property.propertyId,
353 CONTACTS_MATCH_LESS_THAN_OR_EQUAL, endValueInt);
357 errorCode = contacts_filter_add_filter(filter, sub_filter);
360 else if(initialValueExists)
362 errorCode = contacts_filter_add_int(filter, property.propertyId,
363 CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initialValueInt);
365 else if(endValueExists)
367 errorCode = contacts_filter_add_int(filter, property.propertyId,
368 CONTACTS_MATCH_LESS_THAN_OR_EQUAL, endValueInt);
371 else if(property.type == PrimitiveType_String)
373 string initialValueStr = 0;
374 string endValueStr = 0;
376 bool initialValueExists = false;
377 bool endValueExists = false;
379 if(!initialValue->isNullOrUndefined())
381 initialValueStr = initialValue->getLong();
382 initialValueExists = true;
385 if(!endValue->isNullOrUndefined())
387 endValueStr = endValue->getLong();
388 endValueExists = true;
392 if(initialValueExists && endValueExists)
394 contacts_filter_h sub_filter = NULL;
397 errorCode = contacts_filter_create(_contacts_person._uri, &sub_filter);
404 errorCode = contacts_filter_add_str(sub_filter, property.propertyId,
405 CONTACTS_MATCH_STARTSWITH, initialValueStr.c_str());
407 contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
409 errorCode = contacts_filter_add_str(sub_filter, property.propertyId,
410 CONTACTS_MATCH_ENDSWITH, endValueStr.c_str());
414 errorCode = contacts_filter_add_filter(filter, sub_filter);
417 else if(initialValueExists)
419 errorCode = contacts_filter_add_str(filter, property.propertyId,
420 CONTACTS_MATCH_STARTSWITH, initialValueStr.c_str());
422 else if(endValueExists)
424 errorCode = contacts_filter_add_str(filter, property.propertyId,
425 CONTACTS_MATCH_ENDSWITH, endValueStr.c_str());
428 else if(property.type == PrimitiveType_Boolean)
430 bool initialValueBool = 0;
431 bool endValueBool = 0;
433 bool initialValueExists = false;
434 bool endValueExists = false;
436 if(!initialValue->isNullOrUndefined())
438 initialValueBool = initialValue->getBool();
439 initialValueExists = true;
442 if(!endValue->isNullOrUndefined())
444 endValueBool = endValue->getBool();
445 endValueExists = true;
449 if(initialValueExists && endValueExists)
451 if(initialValueBool == endValueBool)
453 if(initialValueBool == true)
454 errorCode = contacts_filter_add_bool(filter, property.propertyId, true);
455 else if(endValueBool == false)
456 errorCode = contacts_filter_add_bool(filter, property.propertyId, false);
459 else if(initialValueExists)
461 if(initialValueBool == true)
462 errorCode = contacts_filter_add_bool(filter, property.propertyId, true);
464 else if(endValueExists)
466 if(endValueBool == false)
467 errorCode = contacts_filter_add_bool(filter, property.propertyId, false);