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_String } },
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;
201 filter = m_filterStack.top();
205 errorCode = contacts_filter_create(_contacts_person._uri, &filter);
206 m_filterStack.push(filter);
210 FilterPropertyStruct property = attrEnumMap[attrName];
212 if(property.type == PrimitiveType_Long)
217 string valueStr = matchValue->getString();
218 value = ContactUtility::strToInt(valueStr);
221 value = matchValue->getLong();
223 contacts_match_int_flag_e flag;
224 if(matchFlag == MATCH_EXISTS)
225 flag = CONTACTS_MATCH_NONE;
227 flag = CONTACTS_MATCH_EQUAL;
229 errorCode = contacts_filter_add_int(filter, property.propertyId, flag, value);
231 else if(property.type == PrimitiveType_String)
233 string value = matchValue->getString();
235 contacts_match_str_flag_e flag = CONTACTS_MATCH_EXISTS;
236 if(matchFlag == MATCH_EXACTLY)
237 flag = CONTACTS_MATCH_EXACTLY;
238 else if(matchFlag == MATCH_FULLSTRING)
239 flag = CONTACTS_MATCH_FULLSTRING;
240 else if(matchFlag == MATCH_CONTAINS)
241 flag = CONTACTS_MATCH_CONTAINS;
242 else if(matchFlag == MATCH_STARTSWITH)
243 flag = CONTACTS_MATCH_STARTSWITH;
244 else if(matchFlag == MATCH_ENDSWITH)
245 flag = CONTACTS_MATCH_ENDSWITH;
246 else if(matchFlag == MATCH_EXISTS)
247 flag = CONTACTS_MATCH_EXISTS;
249 contacts_filter_add_str(filter, property.propertyId, flag, value.c_str());
251 else if(property.type == PrimitiveType_Boolean)
254 value = matchValue->getBool();
257 // if(matchFlag == MATCH_EXISTS)
260 errorCode = contacts_filter_add_bool(filter, property.propertyId, value);
264 void PersonSearchEngine::visitAttributeRange(string& attrName, AnyPtr& initialValue, AnyPtr& endValue, int depth)
267 contacts_filter_h filter = NULL;
271 filter = m_filterStack.top();
275 errorCode = contacts_filter_create(_contacts_person._uri, &filter);
276 m_filterStack.push(filter);
280 FilterPropertyStruct property = attrEnumMap[attrName];
282 if(property.type == PrimitiveType_Long)
284 int initialValueInt = 0;
287 bool initialValueExists = false;
288 bool endValueExists = false;
290 if(!initialValue->isNullOrUndefined())
294 string valueStr = initialValue->getString();
295 initialValueInt = ContactUtility::strToInt(valueStr);
298 initialValueInt = initialValue->getLong();
300 initialValueExists = true;
303 if(!endValue->isNullOrUndefined())
307 string valueStr = endValue->getString();
308 endValueInt = ContactUtility::strToInt(valueStr);
311 endValueInt = endValue->getLong();
313 endValueExists = true;
317 if(initialValueExists && endValueExists)
319 contacts_filter_h sub_filter = NULL;
322 errorCode = contacts_filter_create(_contacts_person._uri, &sub_filter);
329 errorCode = contacts_filter_add_int(sub_filter, property.propertyId,
330 CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initialValueInt);
332 contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
334 errorCode = contacts_filter_add_int(sub_filter, property.propertyId,
335 CONTACTS_MATCH_LESS_THAN_OR_EQUAL, endValueInt);
339 errorCode = contacts_filter_add_filter(filter, sub_filter);
342 else if(initialValueExists)
344 errorCode = contacts_filter_add_int(filter, property.propertyId,
345 CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, initialValueInt);
347 else if(endValueExists)
349 errorCode = contacts_filter_add_int(filter, property.propertyId,
350 CONTACTS_MATCH_LESS_THAN_OR_EQUAL, endValueInt);
353 else if(property.type == PrimitiveType_String)
355 string initialValueStr = 0;
356 string endValueStr = 0;
358 bool initialValueExists = false;
359 bool endValueExists = false;
361 if(!initialValue->isNullOrUndefined())
363 initialValueStr = initialValue->getLong();
364 initialValueExists = true;
367 if(!endValue->isNullOrUndefined())
369 endValueStr = endValue->getLong();
370 endValueExists = true;
374 if(initialValueExists && endValueExists)
376 contacts_filter_h sub_filter = NULL;
379 errorCode = contacts_filter_create(_contacts_person._uri, &sub_filter);
386 errorCode = contacts_filter_add_str(sub_filter, property.propertyId,
387 CONTACTS_MATCH_STARTSWITH, initialValueStr.c_str());
389 contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
391 errorCode = contacts_filter_add_str(sub_filter, property.propertyId,
392 CONTACTS_MATCH_ENDSWITH, endValueStr.c_str());
396 errorCode = contacts_filter_add_filter(filter, sub_filter);
399 else if(initialValueExists)
401 errorCode = contacts_filter_add_str(filter, property.propertyId,
402 CONTACTS_MATCH_STARTSWITH, initialValueStr.c_str());
404 else if(endValueExists)
406 errorCode = contacts_filter_add_str(filter, property.propertyId,
407 CONTACTS_MATCH_ENDSWITH, endValueStr.c_str());
410 else if(property.type == PrimitiveType_Boolean)
412 bool initialValueBool = 0;
413 bool endValueBool = 0;
415 bool initialValueExists = false;
416 bool endValueExists = false;
418 if(!initialValue->isNullOrUndefined())
420 initialValueBool = initialValue->getBool();
421 initialValueExists = true;
424 if(!endValue->isNullOrUndefined())
426 endValueBool = endValue->getBool();
427 endValueExists = true;
431 if(initialValueExists && endValueExists)
433 if(initialValueBool == endValueBool)
435 if(initialValueBool == true)
436 errorCode = contacts_filter_add_bool(filter, property.propertyId, true);
437 else if(endValueBool == false)
438 errorCode = contacts_filter_add_bool(filter, property.propertyId, false);
441 else if(initialValueExists)
443 if(initialValueBool == true)
444 errorCode = contacts_filter_add_bool(filter, property.propertyId, true);
446 else if(endValueExists)
448 if(endValueBool == false)
449 errorCode = contacts_filter_add_bool(filter, property.propertyId, false);