4 * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include "ctsvc_internal.h"
22 #include "ctsvc_db_schema.h"
23 #include "ctsvc_db_sqlite.h"
24 #include "ctsvc_db_access_control.h"
25 #include "ctsvc_db_plugin_person_helper.h"
26 #include "ctsvc_localize.h"
27 #include "ctsvc_localize_utils.h"
28 #include "ctsvc_normalize.h"
29 #include "ctsvc_db_init.h"
30 #include "ctsvc_db_utils.h"
31 #include "ctsvc_db_query.h"
32 #include "ctsvc_record.h"
33 #include "ctsvc_notification.h"
34 #include "ctsvc_notify.h"
35 #include "ctsvc_utils_string.h"
37 #ifdef _CONTACTS_IPC_SERVER
38 #include "ctsvc_server_change_subject.h"
41 int ctsvc_db_person_create_record_from_stmt_with_projection(cts_stmt stmt,
42 unsigned int *projection,
46 const char *start_match,
47 const char *end_match,
49 contacts_record_h *record)
51 ctsvc_person_s *person;
52 char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
54 contacts_record_create(_contacts_person._uri, record);
55 person = (ctsvc_person_s*)*record;
58 for (i = 0; i < projection_count; i++) {
60 int property_id = projection[i];
62 switch (property_id) {
63 case CTSVC_PROPERTY_PERSON_ID:
64 person->person_id = ctsvc_stmt_get_int(stmt, i);
66 case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
67 temp = ctsvc_stmt_get_text(stmt, i);
68 free(person->display_name);
69 person->display_name = SAFE_STRDUP(temp);
71 case CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX:
72 temp = ctsvc_stmt_get_text(stmt, i);
73 free(person->display_name_index);
74 person->display_name_index = SAFE_STRDUP(temp);
76 case CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID:
77 person->name_contact_id = ctsvc_stmt_get_int(stmt, i);
79 case CTSVC_PROPERTY_PERSON_RINGTONE:
80 temp = ctsvc_stmt_get_text(stmt, i);
81 free(person->ringtone_path);
82 person->ringtone_path = SAFE_STRDUP(temp);
84 case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
85 temp = ctsvc_stmt_get_text(stmt, i);
87 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
88 free(person->image_thumbnail_path);
89 person->image_thumbnail_path = strdup(full_path);
92 case CTSVC_PROPERTY_PERSON_VIBRATION:
93 temp = ctsvc_stmt_get_text(stmt, i);
94 free(person->vibration);
95 person->vibration = SAFE_STRDUP(temp);
97 case CTSVC_PROPERTY_PERSON_MESSAGE_ALERT:
98 temp = ctsvc_stmt_get_text(stmt, i);
99 free(person->message_alert);
100 person->message_alert = SAFE_STRDUP(temp);
102 case CTSVC_PROPERTY_PERSON_STATUS:
103 temp = ctsvc_stmt_get_text(stmt, i);
104 free(person->status);
105 person->status = SAFE_STRDUP(temp);
107 case CTSVC_PROPERTY_PERSON_IS_FAVORITE:
108 person->is_favorite = ctsvc_stmt_get_int(stmt, i);
110 case CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER:
111 person->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
113 case CTSVC_PROPERTY_PERSON_HAS_EMAIL:
114 person->has_email = ctsvc_stmt_get_int(stmt, i);
116 case CTSVC_PROPERTY_PERSON_LINK_COUNT:
117 person->link_count = ctsvc_stmt_get_int(stmt, i);
119 case CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS:
120 temp = ctsvc_stmt_get_text(stmt, i);
121 free(person->addressbook_ids);
122 person->addressbook_ids = SAFE_STRDUP(temp);
124 case CTSVC_PROPERTY_PERSON_FAVORITE_PRIORITY:
125 person->favorite_prio = ctsvc_stmt_get_dbl(stmt, i);
127 case CTSVC_PROPERTY_PERSON_SNIPPET_TYPE:
128 person->snippet_type = ctsvc_stmt_get_int(stmt, i);
130 case CTSVC_PROPERTY_PERSON_SNIPPET_STRING:
131 temp = ctsvc_stmt_get_text(stmt, i);
132 free(person->snippet_string);
133 person->snippet_string = ctsvc_utils_get_modified_str(temp, is_snippet,
134 keyword, start_match, end_match, token_number);
135 if (NULL == person->snippet_string)
136 person->snippet_string = SAFE_STRDUP(temp);
139 ASSERT_NOT_REACHED("property_id(0x%0x) is not supported in value(person)", property_id);
140 return CONTACTS_ERROR_INVALID_PARAMETER;
143 return CONTACTS_ERROR_NONE;
147 int ctsvc_db_person_create_record_from_stmt_with_query(cts_stmt stmt, contacts_query_h query, contacts_record_h *record)
149 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
150 ctsvc_query_s *s_query = (ctsvc_query_s*)query;
152 if (0 == s_query->projection_count) {
154 unsigned int *projection = malloc(sizeof(unsigned int)*s_query->property_count);
155 if (NULL == projection) {
156 /* LCOV_EXCL_START */
157 ERR("malloc() Fail");
158 return CONTACTS_ERROR_OUT_OF_MEMORY;
162 for (i = 0; i < s_query->property_count; i++)
163 projection[i] = s_query->properties[i].property_id;
165 int ret = ctsvc_db_person_create_record_from_stmt_with_projection(stmt,
166 projection, s_query->property_count, false, NULL, NULL, NULL, -1, record);
172 return ctsvc_db_person_create_record_from_stmt_with_projection(stmt,
173 s_query->projection, s_query->projection_count, false, NULL, NULL, NULL,
179 int ctsvc_db_person_create_record_from_stmt(cts_stmt stmt, contacts_record_h *record)
184 ctsvc_person_s *person;
187 ret = contacts_record_create(_contacts_person._uri, record);
188 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create Fail(%d)", ret);
189 person = (ctsvc_person_s*)*record;
190 person->person_id = ctsvc_stmt_get_int(stmt, i++);
192 temp = ctsvc_stmt_get_text(stmt, i++);
193 person->display_name = SAFE_STRDUP(temp);
194 temp = ctsvc_stmt_get_text(stmt, i++);
195 person->display_name_index = SAFE_STRDUP(temp);
196 person->name_contact_id = ctsvc_stmt_get_int(stmt, i++);
198 temp = ctsvc_stmt_get_text(stmt, i++);
200 char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
201 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
202 person->image_thumbnail_path = strdup(full_path);
205 temp = ctsvc_stmt_get_text(stmt, i++);
206 person->ringtone_path = SAFE_STRDUP(temp);
207 temp = ctsvc_stmt_get_text(stmt, i++);
208 person->vibration = SAFE_STRDUP(temp);
209 temp = ctsvc_stmt_get_text(stmt, i++);
210 person->message_alert = SAFE_STRDUP(temp);
211 temp = ctsvc_stmt_get_text(stmt, i++);
212 person->status = SAFE_STRDUP(temp);
214 person->link_count = ctsvc_stmt_get_int(stmt, i++);
215 temp = ctsvc_stmt_get_text(stmt, i++);
216 person->addressbook_ids = SAFE_STRDUP(temp);
218 person->has_phonenumber = ctsvc_stmt_get_int(stmt, i++);
219 person->has_email = ctsvc_stmt_get_int(stmt, i++);
220 person->is_favorite = ctsvc_stmt_get_int(stmt, i++);
221 person->favorite_prio = ctsvc_stmt_get_dbl(stmt, i++);
222 return CONTACTS_ERROR_NONE;
225 static inline const char* __ctsvc_get_image_filename(const char *src)
227 const char *dir = CTSVC_CONTACT_IMG_FULL_LOCATION;
233 while (dir[pos] == src[pos])
237 return src + pos + 1;
242 int ctsvc_db_person_set_favorite(int person_id, bool set, bool propagate)
246 cts_stmt stmt = NULL;
247 char query[CTS_SQL_MIN_LEN] = {0};
250 snprintf(query, sizeof(query),
251 "SELECT MAX(favorite_prio) FROM "CTS_TABLE_FAVORITES);
253 ret = ctsvc_query_prepare(query, &stmt);
254 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
256 ret = ctsvc_stmt_step(stmt);
257 if (1 /*CTS_TRUE*/ == ret) {
258 prio = ctsvc_stmt_get_dbl(stmt, 0);
259 } else if (CONTACTS_ERROR_NONE != ret) {
260 /* LCOV_EXCL_START */
261 ERR("ctsvc_stmt_step() Fail(%d)", ret);
262 ctsvc_stmt_finalize(stmt);
266 ctsvc_stmt_finalize(stmt);
269 snprintf(query, sizeof(query),
270 "INSERT OR REPLACE INTO "CTS_TABLE_FAVORITES" values(%d, %f)", person_id, prio);
272 snprintf(query, sizeof(query),
273 "DELETE FROM "CTS_TABLE_FAVORITES" WHERE person_id = %d", person_id);
276 ret = ctsvc_query_exec(query);
277 if (CONTACTS_ERROR_NONE != ret) {
278 /* LCOV_EXCL_START */
279 ERR("ctsvc_query_exec() Fail(%d)", ret);
285 snprintf(query, sizeof(query),
286 "UPDATE "CTS_TABLE_CONTACTS" SET is_favorite=%d, "
287 "changed_time=%d, changed_ver=%d WHERE "
288 "person_id=%d AND deleted = 0",
289 set ? 1 : 0, (int)time(NULL), ctsvc_get_next_ver(),
291 ret = ctsvc_query_exec(query);
292 if (CONTACTS_ERROR_NONE != ret) {
293 /* LCOV_EXCL_START */
294 ERR("ctsvc_query_exec() Fail(%d)", ret);
300 return CONTACTS_ERROR_NONE;
303 int ctsvc_db_insert_person(contacts_record_h record)
306 cts_stmt stmt = NULL;
307 char query[CTS_SQL_MIN_LEN] = {0};
309 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
312 snprintf(query, sizeof(query),
313 "SELECT status FROM %s "
314 "WHERE contact_id=%d "
315 "ORDER BY timestamp DESC LIMIT 1",
316 CTS_TABLE_ACTIVITIES, contact->id);
317 ret = ctsvc_query_prepare(query, &stmt);
318 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
320 if (1 == ctsvc_stmt_step(stmt))
321 status = SAFE_STRDUP(ctsvc_stmt_get_text(stmt, 0));
322 ctsvc_stmt_finalize(stmt);
324 version = ctsvc_get_next_ver();
325 snprintf(query, sizeof(query),
326 "INSERT INTO "CTS_TABLE_PERSONS"(name_contact_id, created_ver, changed_ver, "
327 "has_phonenumber, has_email, ringtone_path, vibration, message_alert, status, "
328 "image_thumbnail_path, link_count, addressbook_ids) "
329 "VALUES(%d, %d, %d, %d, %d, ?, ?, ?, ?, ?, 1, '%d') ",
330 contact->id, version, version,
331 contact->has_phonenumber, contact->has_email, contact->addressbook_id);
333 ret = ctsvc_query_prepare(query, &stmt);
335 /* LCOV_EXCL_START */
336 ERR("ctsvc_query_prepare() Fail(%d)", ret);
341 if (contact->ringtone_path)
342 ctsvc_stmt_bind_text(stmt, 1, contact->ringtone_path);
343 if (contact->vibration)
344 ctsvc_stmt_bind_text(stmt, 2, contact->vibration);
345 if (contact->message_alert)
346 ctsvc_stmt_bind_text(stmt, 3, contact->message_alert);
348 ctsvc_stmt_bind_text(stmt, 4, status);
349 if (contact->image_thumbnail_path) {
350 ctsvc_stmt_bind_text(stmt, 5,
351 __ctsvc_get_image_filename(contact->image_thumbnail_path));
354 ret = ctsvc_stmt_step(stmt);
355 if (CONTACTS_ERROR_NONE != ret) {
356 /* LCOV_EXCL_START */
357 ERR("ctsvc_stmt_step() Fail(%d)", ret);
358 ctsvc_stmt_finalize(stmt);
363 index = ctsvc_db_get_last_insert_id();
365 ctsvc_stmt_finalize(stmt);
367 snprintf(query, sizeof(query),
368 "UPDATE "CTS_TABLE_DATA" SET is_primary_default = 1 "
369 "WHERE is_default = 1 AND contact_id = %d AND is_my_profile = 0", contact->id);
371 ret = ctsvc_query_exec(query);
372 if (CONTACTS_ERROR_NONE != ret) {
373 /* LCOV_EXCL_START */
374 ERR("ctsvc_query_exec() Fail(%d)", ret);
381 if (contact->is_favorite) {
382 ret = ctsvc_db_person_set_favorite(index, contact->is_favorite, false);
383 if (CONTACTS_ERROR_NONE != ret) {
384 /* LCOV_EXCL_START */
385 ERR("ctsvc_db_person_set_favorite() Fail(%d)", ret);
392 ctsvc_set_person_noti();
393 #ifdef _CONTACTS_IPC_SERVER
394 ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_INSERTED, index);
400 static inline int __ctsvc_db_update_person_default(int person_id, int datatype)
403 cts_stmt stmt = NULL;
404 char query[CTS_SQL_MIN_LEN] = {0};
406 char *image_path = NULL;
408 snprintf(query, sizeof(query),
409 "SELECT D.id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
410 "ON C.contact_id = D.contact_id AND C.deleted = 0 "
411 "WHERE C.person_id=%d AND D.datatype=%d AND is_primary_default=1 AND D.is_my_profile = 0",
412 person_id, datatype);
414 ret = ctsvc_query_get_first_int_result(query, &data_id);
415 if (CONTACTS_ERROR_NO_DATA == ret) {
416 snprintf(query, sizeof(query),
417 "SELECT D.id, D.data3 FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
418 "ON C.contact_id = D.contact_id AND C.deleted = 0 "
419 "WHERE C.person_id=%d AND D.datatype=%d AND D.is_default=1 AND D.is_my_profile = 0 ORDER BY D.id",
420 person_id, datatype);
422 ret = ctsvc_query_prepare(query, &stmt);
423 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
425 ret = ctsvc_stmt_step(stmt);
427 data_id = ctsvc_stmt_get_int(stmt, 0);
429 snprintf(query, sizeof(query),
430 "UPDATE "CTS_TABLE_DATA" SET is_primary_default=1 WHERE id=%d",
433 ret = ctsvc_query_exec(query);
434 if (CONTACTS_ERROR_NONE != ret) {
435 /* LCOV_EXCL_START */
436 ERR("ctsvc_query_exec() Fail(%d)", ret);
437 ctsvc_stmt_finalize(stmt);
442 if (CONTACTS_DATA_TYPE_IMAGE == datatype) {
443 temp = ctsvc_stmt_get_text(stmt, 1);
444 image_path = SAFE_STRDUP(temp);
447 ctsvc_stmt_finalize(stmt);
449 if (CONTACTS_DATA_TYPE_IMAGE == datatype) {
451 char *thumbnail_path = NULL;
453 snprintf(query, sizeof(query),
454 "UPDATE "CTS_TABLE_PERSONS" SET image_thumbnail_path=? WHERE person_id=%d", person_id);
455 ret = ctsvc_query_prepare(query, &stmt);
456 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
457 thumbnail_path = ctsvc_utils_get_thumbnail_path(image_path, TRUE);
458 ctsvc_stmt_bind_text(stmt, 1, thumbnail_path);
459 ret = ctsvc_stmt_step(stmt);
460 ctsvc_stmt_finalize(stmt);
462 free(thumbnail_path);
463 if (CONTACTS_ERROR_NONE != ret) {
464 /* LCOV_EXCL_START */
465 ERR("ctsvc_stmt_step() Fail(%d)", ret);
473 return CONTACTS_ERROR_NONE;
476 static bool __ctsvc_get_has_column(int person_id, const char *culumn)
479 int contact_count = 0;
480 char query[CTS_SQL_MIN_LEN] = {0};
482 snprintf(query, sizeof(query),
483 "SELECT count(contact_id) FROM "CTS_TABLE_CONTACTS" "
484 "WHERE person_id=%d AND %s=1 AND deleted = 0",
487 ret = ctsvc_query_get_first_int_result(query, &contact_count);
488 RETV_IF(CONTACTS_ERROR_NONE != ret, false);
495 static int __ctsvc_get_thumbnail_contact_id(int person_id)
499 char query[CTS_SQL_MIN_LEN] = {0};
501 snprintf(query, sizeof(query),
502 "SELECT D.contact_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
503 "ON C.contact_id = D.contact_id AND C.deleted = 0 "
504 "WHERE C.person_id=%d AND D.datatype=%d AND is_primary_default=1 AND D.is_my_profile = 0",
505 person_id, CONTACTS_DATA_TYPE_IMAGE);
506 ret = ctsvc_query_get_first_int_result(query, &contact_id);
507 RETV_IF(CONTACTS_ERROR_NONE != ret, -1);
511 int ctsvc_db_update_person(contacts_record_h record)
513 int ret, i = 1, len = 0;
514 cts_stmt stmt = NULL;
515 char query[CTS_SQL_MIN_LEN] = {0};
516 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
517 bool has_phonenumber = false, has_email = false;
518 int thumbnail_contact_id = 0;
522 ret = ctsvc_begin_trans();
523 RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
525 __ctsvc_db_update_person_default(contact->person_id, CONTACTS_DATA_TYPE_NUMBER);
526 __ctsvc_db_update_person_default(contact->person_id, CONTACTS_DATA_TYPE_EMAIL);
527 __ctsvc_db_update_person_default(contact->person_id, CONTACTS_DATA_TYPE_IMAGE);
529 has_phonenumber = __ctsvc_get_has_column(contact->person_id, "has_phonenumber");
530 has_email = __ctsvc_get_has_column(contact->person_id, "has_email");
531 thumbnail_contact_id = __ctsvc_get_thumbnail_contact_id(contact->person_id);
533 len = snprintf(query, sizeof(query),
534 "UPDATE "CTS_TABLE_PERSONS" SET changed_ver=%d, has_phonenumber=%d, has_email=%d ",
535 ctsvc_get_next_ver(), has_phonenumber, has_email);
537 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.ringtone_path, CTSVC_PROPERTY_FLAG_DIRTY))
538 len += snprintf(query+len, sizeof(query)-len, ", ringtone_path=?");
539 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.vibration, CTSVC_PROPERTY_FLAG_DIRTY))
540 len += snprintf(query+len, sizeof(query)-len, ", vibration=?");
541 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.message_alert, CTSVC_PROPERTY_FLAG_DIRTY))
542 len += snprintf(query+len, sizeof(query)-len, ", message_alert=?");
543 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY) &&
544 (contact->id == thumbnail_contact_id || thumbnail_contact_id == -1))
545 len += snprintf(query+len, sizeof(query)-len, ", image_thumbnail_path=?");
547 snprintf(query+len, sizeof(query)-len,
548 " WHERE person_id=%d", contact->person_id);
550 ret = ctsvc_query_prepare(query, &stmt);
552 /* LCOV_EXCL_START */
553 ERR("ctsvc_query_prepare() Fail(%d)", ret);
554 ctsvc_end_trans(false);
559 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.ringtone_path, CTSVC_PROPERTY_FLAG_DIRTY)) {
560 if (contact->ringtone_path)
561 ctsvc_stmt_bind_text(stmt, i, contact->ringtone_path);
564 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.vibration, CTSVC_PROPERTY_FLAG_DIRTY)) {
565 if (contact->vibration)
566 ctsvc_stmt_bind_text(stmt, i, contact->vibration);
569 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.message_alert, CTSVC_PROPERTY_FLAG_DIRTY)) {
570 if (contact->message_alert)
571 ctsvc_stmt_bind_text(stmt, i, contact->message_alert);
574 if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY) &&
575 (contact->id == thumbnail_contact_id || thumbnail_contact_id == -1)) {
576 if (contact->image_thumbnail_path)
577 ctsvc_stmt_bind_text(stmt, i, contact->image_thumbnail_path);
581 ret = ctsvc_stmt_step(stmt);
582 if (CONTACTS_ERROR_NONE != ret) {
583 /* LCOV_EXCL_START */
584 ERR("ctsvc_stmt_step() Fail(%d)", ret);
585 ctsvc_stmt_finalize(stmt);
586 ctsvc_end_trans(false);
590 ctsvc_stmt_finalize(stmt);
592 /* update favorite */
593 snprintf(query, sizeof(query),
594 "SELECT is_favorite FROM "CTS_TABLE_CONTACTS" WHERE contact_id =%d ", contact->id);
595 ret = ctsvc_query_get_first_int_result(query, &is_favorite);
596 if (ret < CONTACTS_ERROR_NONE) {
597 /* LCOV_EXCL_START */
598 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
599 ctsvc_end_trans(false);
604 snprintf(query, sizeof(query),
605 "SELECT person_id FROM "CTS_TABLE_FAVORITES" WHERE person_id =%d ", contact->person_id);
606 ret = ctsvc_query_get_first_int_result(query, &person_id);
607 if (CONTACTS_ERROR_NO_DATA == ret && is_favorite) {
608 ret = ctsvc_db_person_set_favorite(contact->person_id, true, false);
609 if (CONTACTS_ERROR_NONE != ret) {
610 /* LCOV_EXCL_START */
611 ERR("ctsvc_db_person_set_favorite() Fail(%d)", ret);
612 ctsvc_end_trans(false);
616 } else if (CONTACTS_ERROR_NONE == ret && false == is_favorite) {
617 snprintf(query, sizeof(query),
618 "SELECT person_id FROM "CTS_TABLE_CONTACTS" WHERE person_id =%d AND is_favorite = 1", contact->person_id);
619 ret = ctsvc_query_get_first_int_result(query, &person_id);
620 if (CONTACTS_ERROR_NO_DATA == ret) {
621 ret = ctsvc_db_person_set_favorite(contact->person_id, false, false);
622 if (CONTACTS_ERROR_NONE != ret) {
623 /* LCOV_EXCL_START */
624 ERR("ctsvc_db_person_set_favorite() Fail(%d)", ret);
625 ctsvc_end_trans(false);
629 } else if (CONTACTS_ERROR_NONE != ret) {
630 /* LCOV_EXCL_START */
631 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
632 ctsvc_end_trans(false);
636 } else if (ret < CONTACTS_ERROR_NONE && CONTACTS_ERROR_NO_DATA != ret) {
637 /* LCOV_EXCL_START */
638 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
639 ctsvc_end_trans(false);
644 ctsvc_set_person_noti();
646 #ifdef _CONTACTS_IPC_SERVER
647 ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_UPDATED, contact->person_id);
650 ret = ctsvc_end_trans(true);
651 if (ret < CONTACTS_ERROR_NONE) {
652 /* LCOV_EXCL_START */
653 ERR("ctsvc_end_trans() Fail(%d)", ret);
657 return CONTACTS_ERROR_NONE;
661 /* This function will return group letter of the person */
662 void ctsvc_db_normalize_str_callback(sqlite3_context *context,
663 int argc, sqlite3_value **argv)
665 const char *display_name;
666 int display_name_language = CTSVC_LANG_OTHERS;
669 sqlite3_result_null(context);
673 display_name_language = sqlite3_value_int(argv[1]);
674 if (display_name_language == CTSVC_SORT_OTHERS || display_name_language == CTSVC_SORT_NUMBER) {
675 sqlite3_result_text(context, "#", 1, SQLITE_TRANSIENT);
678 display_name = (const char *)sqlite3_value_text(argv[0]);
682 ret = ctsvc_normalize_index(display_name, &dest);
683 if (ret < CONTACTS_ERROR_NONE) {
684 /* LCOV_EXCL_START */
685 ERR("ctsvc_normalize_index() Fail(%d)", ret);
686 sqlite3_result_null(context);
690 sqlite3_result_text(context, dest, strlen(dest), SQLITE_TRANSIENT);
696 sqlite3_result_null(context);