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.
23 #include "ctsvc_internal.h"
24 #include "ctsvc_db_sqlite.h"
25 #include "ctsvc_db_schema.h"
26 #include "ctsvc_db_init.h"
27 #include "ctsvc_db_query.h"
28 #include "ctsvc_db_utils.h"
29 #include "ctsvc_record.h"
30 #include "ctsvc_normalize.h"
31 #include "ctsvc_number_utils.h"
32 #include "ctsvc_list.h"
33 #include "ctsvc_server_setting.h"
34 #include "ctsvc_localize_ch.h"
35 #include "ctsvc_server_group.h"
36 #include "ctsvc_notification.h"
37 #include "ctsvc_localize.h"
38 #include "ctsvc_localize_utils.h"
39 #include "ctsvc_server_person.h"
40 #include "ctsvc_notify.h"
42 #ifdef ENABLE_LOG_FEATURE
43 #include "ctsvc_server_phonelog.h"
44 #endif /* ENABLE_LOG_FEATURE */
45 #include "ctsvc_db_access_control.h"
47 #include "ctsvc_db_plugin_contact_helper.h"
48 #include "ctsvc_db_plugin_person_helper.h"
51 static int __ctsvc_db_get_contact_base_info(int id, ctsvc_contact_s *contact)
56 char query[CTS_SQL_MAX_LEN] = {0};
58 char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
60 snprintf(query, sizeof(query),
61 "SELECT contact_id, addressbook_id, person_id, changed_time, changed_ver, link_mode, %s, "
62 "display_name_source, image_thumbnail_path, "
63 "ringtone_path, vibration, message_alert, "
64 "uid, is_favorite, has_phonenumber, has_email, "
65 "sort_name, reverse_sort_name "
66 "FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d AND deleted = 0",
67 ctsvc_get_display_column(), id);
69 ret = ctsvc_query_prepare(query, &stmt);
70 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
72 ret = ctsvc_stmt_step(stmt);
73 if (1 /*CTS_TRUE*/ != ret) {
75 ERR("ctsvc_stmt_step() Fail(%d)", ret);
76 ctsvc_stmt_finalize(stmt);
77 if (CONTACTS_ERROR_NONE == ret)
78 return CONTACTS_ERROR_NO_DATA;
85 contact->id = ctsvc_stmt_get_int(stmt, i++);
86 contact->addressbook_id = ctsvc_stmt_get_int(stmt, i++);
87 contact->person_id = ctsvc_stmt_get_int(stmt, i++);
88 contact->changed_time = ctsvc_stmt_get_int(stmt, i++);
89 contact->changed_ver = ctsvc_stmt_get_int(stmt, i++);
90 contact->link_mode = ctsvc_stmt_get_int(stmt, i++);
91 temp = ctsvc_stmt_get_text(stmt, i++);
92 contact->display_name = SAFE_STRDUP(temp);
93 contact->display_source_type = ctsvc_stmt_get_int(stmt, i++);
95 temp = ctsvc_stmt_get_text(stmt, i++);
97 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
98 contact->image_thumbnail_path = strdup(full_path);
101 temp = ctsvc_stmt_get_text(stmt, i++);
102 contact->ringtone_path = SAFE_STRDUP(temp);
103 temp = ctsvc_stmt_get_text(stmt, i++);
104 contact->vibration = SAFE_STRDUP(temp);
105 temp = ctsvc_stmt_get_text(stmt, i++);
106 contact->message_alert = SAFE_STRDUP(temp);
107 temp = ctsvc_stmt_get_text(stmt, i++);
108 contact->uid = SAFE_STRDUP(temp);
109 contact->is_favorite = ctsvc_stmt_get_int(stmt, i++);
110 contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i++);
111 contact->has_email = ctsvc_stmt_get_int(stmt, i++);
112 temp = ctsvc_stmt_get_text(stmt, i++);
113 contact->sort_name = SAFE_STRDUP(temp);
114 temp = ctsvc_stmt_get_text(stmt, i++);
115 contact->reverse_sort_name = SAFE_STRDUP(temp);
116 ctsvc_stmt_finalize(stmt);
118 return CONTACTS_ERROR_NONE;
121 static int __ctsvc_db_get_data(int id, ctsvc_contact_s *contact)
125 cts_stmt stmt = NULL;
126 char query[CTS_SQL_MAX_LEN] = {0};
128 snprintf(query, sizeof(query),
129 "SELECT datatype, id, data.contact_id, is_default, data1, data2, "
130 "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
131 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
132 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
133 "WHERE data.contact_id = %d AND is_my_profile = 0 "
134 "ORDER BY is_default DESC", id);
136 ret = ctsvc_query_prepare(query, &stmt);
137 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
139 ret = ctsvc_stmt_step(stmt);
140 if (1 /*CTS_TRUE */!= ret) {
141 /* LCOV_EXCL_START */
142 ERR("ctsvc_stmt_step() Fail(%d)", ret);
143 ctsvc_stmt_finalize(stmt);
149 datatype = ctsvc_stmt_get_int(stmt, 0);
151 case CONTACTS_DATA_TYPE_NAME:
152 ctsvc_get_data_info_name(stmt, (contacts_list_h)contact->name);
154 case CONTACTS_DATA_TYPE_EVENT:
155 ctsvc_get_data_info_event(stmt, (contacts_list_h)contact->events);
157 case CONTACTS_DATA_TYPE_MESSENGER:
158 ctsvc_get_data_info_messenger(stmt, (contacts_list_h)contact->messengers);
160 case CONTACTS_DATA_TYPE_POSTAL:
161 ctsvc_get_data_info_address(stmt, (contacts_list_h)contact->postal_addrs);
163 case CONTACTS_DATA_TYPE_URL:
164 ctsvc_get_data_info_url(stmt, (contacts_list_h)contact->urls);
166 case CONTACTS_DATA_TYPE_NICKNAME:
167 ctsvc_get_data_info_nickname(stmt, (contacts_list_h)contact->nicknames);
169 case CONTACTS_DATA_TYPE_NUMBER:
170 ctsvc_get_data_info_number(stmt, (contacts_list_h)contact->numbers);
172 case CONTACTS_DATA_TYPE_EMAIL:
173 ctsvc_get_data_info_email(stmt, (contacts_list_h)contact->emails);
175 case CONTACTS_DATA_TYPE_PROFILE:
176 ctsvc_get_data_info_profile(stmt, (contacts_list_h)contact->profiles);
178 case CONTACTS_DATA_TYPE_RELATIONSHIP:
179 ctsvc_get_data_info_relationship(stmt, (contacts_list_h)contact->relationships);
181 case CONTACTS_DATA_TYPE_IMAGE:
182 ctsvc_get_data_info_image(stmt, (contacts_list_h)contact->images);
184 case CONTACTS_DATA_TYPE_COMPANY:
185 ctsvc_get_data_info_company(stmt, (contacts_list_h)contact->company);
187 case CONTACTS_DATA_TYPE_NOTE:
188 ctsvc_get_data_info_note(stmt, (contacts_list_h)contact->note);
190 case CONTACTS_DATA_TYPE_EXTENSION:
191 ctsvc_get_data_info_extension(stmt, (contacts_list_h)contact->extensions);
193 case CONTACTS_DATA_TYPE_SIP:
194 ctsvc_get_data_info_sip(stmt, (contacts_list_h)contact->sips);
197 /* LCOV_EXCL_START */
198 ERR("Intenal : Not supported data type (%d)", datatype);
203 } while (1 == ctsvc_stmt_step(stmt));
205 ctsvc_stmt_finalize(stmt);
207 return CONTACTS_ERROR_NONE;
211 static inline int __ctsvc_get_contact_grouprel(int contact_id, ctsvc_contact_s *contact)
215 ctsvc_group_relation_s *grouprel;
216 cts_stmt stmt = NULL;
217 char query[CTS_SQL_MAX_LEN] = {0};
220 snprintf(query, sizeof(query),
221 "SELECT group_id, contact_id, group_name "
222 " FROM "CTSVC_DB_VIEW_GROUP_RELATION" WHERE contact_id = %d", contact_id);
224 ret = ctsvc_query_prepare(query, &stmt);
225 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
227 while (1 /*CTS_TRUE */ == ctsvc_stmt_step(stmt)) {
228 contacts_record_create(_contacts_group_relation._uri, (contacts_record_h*)&grouprel);
231 grouprel->group_id = ctsvc_stmt_get_int(stmt, 0);
232 grouprel->id = grouprel->group_id;
233 grouprel->contact_id = ctsvc_stmt_get_int(stmt, 1);
234 temp = ctsvc_stmt_get_text(stmt, 2);
235 grouprel->group_name = SAFE_STRDUP(temp);
237 ctsvc_list_prepend((contacts_list_h)contact->grouprelations, (contacts_record_h)grouprel);
241 ctsvc_stmt_finalize(stmt);
242 ctsvc_list_reverse((contacts_list_h)contact->grouprelations);
243 return CONTACTS_ERROR_NONE;
246 static int __ctsvc_db_contact_get_record(int id, contacts_record_h *out_record)
249 contacts_record_h record;
250 ctsvc_contact_s *contact;
252 RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
255 contacts_record_create(_contacts_contact._uri, &record);
256 contact = (ctsvc_contact_s*)record;
257 ret = __ctsvc_db_get_contact_base_info(id, contact);
258 if (CONTACTS_ERROR_NONE != ret) {
259 /* LCOV_EXCL_START */
260 ERR("__ctsvc_db_get_contact_base_info(ALL) Fail(%d)", ret);
261 contacts_record_destroy(record, true);
266 ret = __ctsvc_db_get_data(id, contact);
267 if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
268 /* LCOV_EXCL_START */
269 ERR("ctsvc_get_data_info Fail(%d)", ret);
270 contacts_record_destroy(record, true);
275 ret = __ctsvc_get_contact_grouprel(id, contact);
276 if (CONTACTS_ERROR_NONE != ret) {
277 /* LCOV_EXCL_START */
278 ERR("ctsvc_get_group_relations Fail(%d)", ret);
279 contacts_record_destroy(record, true);
284 *out_record = record;
286 return CONTACTS_ERROR_NONE;
289 static int __ctsvc_db_contact_delete_record(int id)
291 return ctsvc_db_contact_delete(id);
294 static inline int __ctsvc_contact_update_data(ctsvc_contact_s *contact)
299 ret = ctsvc_contact_update_data_name((contacts_list_h)contact->name, contact->id, false);
300 if (CONTACTS_ERROR_NONE != ret) {
301 /* LCOV_EXCL_START */
302 ERR("ctsvc_contact_update_data_name() Fail(%d)", ret);
308 if (contact->company) {
309 ret = ctsvc_contact_update_data_company((contacts_list_h)contact->company, contact->id, false);
310 if (CONTACTS_ERROR_NONE != ret) {
311 /* LCOV_EXCL_START */
312 ERR("ctsvc_contact_update_data_company() Fail(%d)", ret);
319 ret = ctsvc_contact_update_data_note((contacts_list_h)contact->note, contact->id, false);
320 if (CONTACTS_ERROR_NONE != ret) {
321 /* LCOV_EXCL_START */
322 ERR("ctsvc_contact_update_data_note() Fail(%d)", ret);
328 if (contact->events) {
329 ret = ctsvc_contact_update_data_event((contacts_list_h)contact->events, contact->id, false);
330 if (CONTACTS_ERROR_NONE != ret) {
331 /* LCOV_EXCL_START */
332 ERR("ctsvc_contact_update_data_events() Fail(%d)", ret);
338 if (contact->messengers) {
339 ret = ctsvc_contact_update_data_messenger((contacts_list_h)contact->messengers, contact->id, false);
340 if (CONTACTS_ERROR_NONE != ret) {
341 /* LCOV_EXCL_START */
342 ERR("ctsvc_contact_update_data_messengers() Fail(%d)", ret);
348 if (contact->postal_addrs) {
349 ret = ctsvc_contact_update_data_address((contacts_list_h)contact->postal_addrs, contact->id, false);
350 if (CONTACTS_ERROR_NONE != ret) {
351 /* LCOV_EXCL_START */
352 ERR("ctsvc_contact_update_data_address() Fail(%d)", ret);
359 ret = ctsvc_contact_update_data_url((contacts_list_h)contact->urls, contact->id, false);
360 if (CONTACTS_ERROR_NONE != ret) {
361 /* LCOV_EXCL_START */
362 ERR("ctsvc_contact_update_data_url() Fail(%d)", ret);
368 if (contact->nicknames) {
369 ret = ctsvc_contact_update_data_nickname((contacts_list_h)contact->nicknames, contact->id, false);
370 if (CONTACTS_ERROR_NONE != ret) {
371 /* LCOV_EXCL_START */
372 ERR("ctsvc_contact_update_data_nickname() Fail(%d)", ret);
378 if (contact->numbers) {
379 bool had_phonenumber;
380 ret = ctsvc_contact_update_data_number((contacts_list_h)contact->numbers, contact->id, false, &had_phonenumber);
381 if (CONTACTS_ERROR_NONE != ret) {
382 /* LCOV_EXCL_START */
383 ERR("ctsvc_contact_update_data_number() Fail(%d)", ret);
387 contact->has_phonenumber = had_phonenumber;
390 if (contact->emails) {
392 ret = ctsvc_contact_update_data_email((contacts_list_h)contact->emails, contact->id, false, &had_email);
393 if (CONTACTS_ERROR_NONE != ret) {
394 /* LCOV_EXCL_START */
395 ERR("ctsvc_contact_update_data_email() Fail(%d)", ret);
399 contact->has_email = had_email;
402 if (contact->profiles) {
403 ret = ctsvc_contact_update_data_profile((contacts_list_h)contact->profiles, contact->id, false);
404 if (CONTACTS_ERROR_NONE != ret) {
405 /* LCOV_EXCL_START */
406 ERR("ctsvc_contact_update_data_profile() Fail(%d)", ret);
412 if (contact->relationships) {
413 ret = ctsvc_contact_update_data_relationship((contacts_list_h)contact->relationships, contact->id, false);
414 if (CONTACTS_ERROR_NONE != ret) {
415 /* LCOV_EXCL_START */
416 ERR("ctsvc_contact_update_data_relationship() Fail(%d)", ret);
422 if (contact->images) {
423 ret = ctsvc_contact_update_data_image((contacts_list_h)contact->images, contact->id, false);
424 if (CONTACTS_ERROR_NONE != ret) {
425 /* LCOV_EXCL_START */
426 ERR("ctsvc_contact_update_data_image() Fail(%d)", ret);
432 if (contact->extensions) {
433 ret = ctsvc_contact_update_data_extension((contacts_list_h)contact->extensions, contact->id, false);
434 if (CONTACTS_ERROR_NONE != ret) {
435 /* LCOV_EXCL_START */
436 ERR("ctsvc_contact_update_data_extension() Fail(%d)", ret);
443 ret = ctsvc_contact_update_data_sip((contacts_list_h)contact->sips, contact->id, false);
444 if (CONTACTS_ERROR_NONE != ret) {
445 /* LCOV_EXCL_START */
446 ERR("ctsvc_contact_update_data_sips() Fail(%d)", ret);
451 return CONTACTS_ERROR_NONE;
454 static void __ctsvc_contact_check_default_data(ctsvc_contact_s *contact)
456 if (contact->numbers)
457 contact->has_phonenumber = ctsvc_contact_check_default_number((contacts_list_h)contact->numbers);
459 contact->has_email = ctsvc_contact_check_default_email((contacts_list_h)contact->emails);
461 ctsvc_contact_check_default_image((contacts_list_h)contact->images);
462 if (contact->postal_addrs)
463 ctsvc_contact_check_default_address((contacts_list_h)contact->postal_addrs);
466 static inline int __ctsvc_contact_update_grouprel(int contact_id, contacts_list_h group_list)
469 ctsvc_group_relation_s *grouprel;
470 ctsvc_list_s *list = (ctsvc_list_s*)group_list;
476 RETV_IF(NULL == group_list, CONTACTS_ERROR_INVALID_PARAMETER);
478 for (cursor = list->deleted_records; cursor; cursor = cursor->next) {
479 grouprel = cursor->data;
480 ret = ctsvc_group_remove_contact_in_transaction(grouprel->group_id, contact_id);
485 ret = contacts_list_get_count(group_list, &count);
487 return CONTACTS_ERROR_NONE;
489 contacts_list_first(group_list);
491 contacts_list_get_current_record_p(group_list, (contacts_record_h*)&grouprel);
492 if (NULL == grouprel)
495 RETVM_IF(grouprel->group_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "group_id(%d) invalid", grouprel->group_id);
496 if (grouprel->group_id) {
497 ret = ctsvc_group_add_contact_in_transaction(grouprel->group_id, contact_id);
498 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_db_group_set_relation() Fail(%d)", ret);
502 } while (CONTACTS_ERROR_NONE == contacts_list_next(group_list));
507 return CONTACTS_ERROR_NONE;
510 static bool __ctsvc_contact_check_token(char *src, char *dest, int len)
515 for (i = 0; i < len; i++) {
516 if (src[i] == '@' || src[i] == '.') {
528 /* Make search data by number, email, nicknames, address, note, messenger, relationship, company */
529 static inline int __ctsvc_contact_make_search_data(ctsvc_contact_s *contact,
530 char **search_number, char **search_data)
536 char *temp_number = NULL;
537 char *temp_data = NULL;
540 RETV_IF(NULL == contact, CONTACTS_ERROR_NO_DATA);
542 if (contact->numbers) {
543 contacts_list_h number_list = (contacts_list_h)contact->numbers;
544 ctsvc_number_s *number_record;
545 contacts_list_first(number_list);
547 contacts_list_get_current_record_p(number_list, (contacts_record_h*)&number_record);
548 if (number_record && number_record->cleaned) {
549 buf_size = SAFE_STRLEN(number) + SAFE_STRLEN(number_record->cleaned) + SAFE_STRLEN(number_record->normalized) + 3;
550 temp_number = calloc(1, buf_size);
551 if (NULL == temp_number) {
552 /* LCOV_EXCL_START */
553 ERR("calloc() Fail");
555 return CONTACTS_ERROR_OUT_OF_MEMORY;
560 snprintf(temp_number, buf_size, "%s %s %s", SAFE_STR(number), number_record->cleaned, number_record->normalized);
562 snprintf(temp_number, buf_size, "%s %s", number_record->cleaned, number_record->normalized);
564 number = temp_number;
566 } while (CONTACTS_ERROR_NONE == contacts_list_next(number_list));
569 if (contact->emails) {
570 contacts_list_h email_list = (contacts_list_h)contact->emails;
571 ctsvc_email_s *email;
572 contacts_list_first(email_list);
574 contacts_list_get_current_record_p(email_list, (contacts_record_h*)&email);
575 if (email && email->email_addr) {
576 int len = strlen(email->email_addr);
578 bool had = __ctsvc_contact_check_token(email->email_addr, temp, len);
580 buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(email->email_addr)
582 temp_data = calloc(1, buf_size);
583 if (NULL == temp_data) {
584 /* LCOV_EXCL_START */
585 ERR("calloc() Fail");
588 return CONTACTS_ERROR_OUT_OF_MEMORY;
593 snprintf(temp_data, buf_size, "%s %s %s", data, email->email_addr,
596 snprintf(temp_data, buf_size, "%s %s", email->email_addr,
602 } while (CONTACTS_ERROR_NONE == contacts_list_next(email_list));
605 if (contact->nicknames) {
606 contacts_list_h nickname_list = (contacts_list_h)contact->nicknames;
607 ctsvc_nickname_s *nickname;
608 contacts_list_first(nickname_list);
610 contacts_list_get_current_record_p(nickname_list, (contacts_record_h*)&nickname);
611 if (nickname && nickname->nickname) {
612 int len = strlen(nickname->nickname);
614 bool had = __ctsvc_contact_check_token(nickname->nickname, temp, len);
616 buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(nickname->nickname) * (had ? 2 : 1) + 4;
617 temp_data = calloc(1, buf_size);
618 if (NULL == temp_data) {
619 /* LCOV_EXCL_START */
620 ERR("calloc() Fail");
623 return CONTACTS_ERROR_OUT_OF_MEMORY;
628 snprintf(temp_data, buf_size, "%s %s %s", data, nickname->nickname, (had ? temp : ""));
630 snprintf(temp_data, buf_size, "%s %s", nickname->nickname, (had ? temp : ""));
634 } while (CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
637 if (contact->postal_addrs) {
638 contacts_list_h address_list = (contacts_list_h)contact->postal_addrs;
639 ctsvc_address_s *address;
640 contacts_list_first(address_list);
642 contacts_list_get_current_record_p(address_list, (contacts_record_h*)&address);
645 int str_len = SAFE_STRLEN(address->country)
646 + SAFE_STRLEN(address->pobox)
647 + SAFE_STRLEN(address->postalcode)
648 + SAFE_STRLEN(address->region)
649 + SAFE_STRLEN(address->locality)
650 + SAFE_STRLEN(address->street)
651 + SAFE_STRLEN(address->extended);
653 buf_size = SAFE_STRLEN(data)
655 temp_data = calloc(1, buf_size);
656 if (NULL == temp_data) {
657 /* LCOV_EXCL_START */
658 ERR("calloc() Fail");
661 return CONTACTS_ERROR_OUT_OF_MEMORY;
665 char temp[str_len+1];
668 len += snprintf(temp_data + len, buf_size - len, "%s ", data);
670 if (address->country) {
671 had = __ctsvc_contact_check_token(address->country, temp, SAFE_STRLEN(address->country));
672 len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->country, had ? temp : "");
674 if (address->pobox) {
675 had = __ctsvc_contact_check_token(address->pobox, temp, SAFE_STRLEN(address->pobox));
676 len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->pobox, had ? temp : "");
678 if (address->postalcode) {
679 had = __ctsvc_contact_check_token(address->postalcode, temp, SAFE_STRLEN(address->postalcode));
680 len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->postalcode, had ? temp : "");
682 if (address->region) {
683 had = __ctsvc_contact_check_token(address->region, temp, SAFE_STRLEN(address->region));
684 len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->region, had ? temp : "");
686 if (address->locality) {
687 had = __ctsvc_contact_check_token(address->locality, temp, SAFE_STRLEN(address->locality));
688 len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->locality, had ? temp : "");
690 if (address->street) {
691 had = __ctsvc_contact_check_token(address->street, temp, SAFE_STRLEN(address->street));
692 len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->street, had ? temp : "");
694 if (address->extended) {
695 had = __ctsvc_contact_check_token(address->extended, temp, SAFE_STRLEN(address->extended));
696 len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->extended, had ? temp : "");
701 } while (CONTACTS_ERROR_NONE == contacts_list_next(address_list));
705 contacts_list_h note_list = (contacts_list_h)contact->note;
707 contacts_list_first(note_list);
709 contacts_list_get_current_record_p(note_list, (contacts_record_h*)¬e);
710 if (note && note->note) {
711 int len = strlen(note->note);
713 bool had = __ctsvc_contact_check_token(note->note, temp, len);
715 buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(note->note) * (had ? 2 : 1) + 4;
716 temp_data = calloc(1, buf_size);
717 if (NULL == temp_data) {
718 /* LCOV_EXCL_START */
719 ERR("calloc() Fail");
722 return CONTACTS_ERROR_OUT_OF_MEMORY;
727 snprintf(temp_data, buf_size, "%s %s %s", data, note->note,
730 snprintf(temp_data, buf_size, "%s %s", note->note,
736 } while (CONTACTS_ERROR_NONE == contacts_list_next(note_list));
739 if (contact->messengers) {
740 contacts_list_h messenger_list = (contacts_list_h)contact->messengers;
741 ctsvc_messenger_s *messenger;
742 contacts_list_first(messenger_list);
744 contacts_list_get_current_record_p(messenger_list, (contacts_record_h*)&messenger);
745 if (messenger && messenger->im_id) {
746 int len = strlen(messenger->im_id);
748 bool had = __ctsvc_contact_check_token(messenger->im_id, temp, len);
750 buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(messenger->im_id) * (had ? 2 : 1) + 4;
751 temp_data = calloc(1, buf_size);
752 if (NULL == temp_data) {
753 /* LCOV_EXCL_START */
754 ERR("calloc() Fail");
757 return CONTACTS_ERROR_OUT_OF_MEMORY;
762 snprintf(temp_data, buf_size, "%s %s %s", data, messenger->im_id,
765 snprintf(temp_data, buf_size, "%s %s", messenger->im_id,
771 } while (CONTACTS_ERROR_NONE == contacts_list_next(messenger_list));
774 if (contact->relationships) {
775 contacts_list_h relationship_list = (contacts_list_h)contact->relationships;
776 ctsvc_relationship_s *relationship;
777 contacts_list_first(relationship_list);
779 contacts_list_get_current_record_p(relationship_list, (contacts_record_h*)&relationship);
780 if (relationship && relationship->name) {
781 int len = strlen(relationship->name);
783 bool had = __ctsvc_contact_check_token(relationship->name, temp, len);
785 buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(relationship->name) * (had ? 2 : 1) + 4;
786 temp_data = calloc(1, buf_size);
787 if (NULL == temp_data) {
788 /* LCOV_EXCL_START */
789 ERR("calloc() Fail");
792 return CONTACTS_ERROR_OUT_OF_MEMORY;
797 snprintf(temp_data, buf_size, "%s %s %s", data, relationship->name,
800 snprintf(temp_data, buf_size, "%s %s", relationship->name,
806 } while (CONTACTS_ERROR_NONE == contacts_list_next(relationship_list));
809 if (contact->company) {
810 contacts_list_h company_list = (contacts_list_h)contact->company;
811 ctsvc_company_s *company;
812 contacts_list_first(company_list);
814 contacts_list_get_current_record_p(company_list, (contacts_record_h*)&company);
817 int str_len = SAFE_STRLEN(company->name)
818 + SAFE_STRLEN(company->department)
819 + SAFE_STRLEN(company->job_title)
820 + SAFE_STRLEN(company->role)
821 + SAFE_STRLEN(company->assistant_name)
822 + SAFE_STRLEN(company->location)
823 + SAFE_STRLEN(company->description)
824 + SAFE_STRLEN(company->phonetic_name);
826 buf_size = SAFE_STRLEN(data) + str_len * 2 + 18;
827 temp_data = calloc(1, buf_size);
828 if (NULL == temp_data) {
829 /* LCOV_EXCL_START */
830 ERR("calloc() Fail");
833 return CONTACTS_ERROR_OUT_OF_MEMORY;
837 char temp[str_len+1];
840 len += snprintf(temp_data + len, buf_size - len, "%s ", data);
842 had = __ctsvc_contact_check_token(company->name, temp, SAFE_STRLEN(company->name));
843 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->name, had ? temp : "");
845 if (company->department) {
846 had = __ctsvc_contact_check_token(company->department, temp, SAFE_STRLEN(company->department));
847 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->department, had ? temp : "");
849 if (company->job_title) {
850 had = __ctsvc_contact_check_token(company->job_title, temp, SAFE_STRLEN(company->job_title));
851 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->job_title, had ? temp : "");
854 had = __ctsvc_contact_check_token(company->role, temp, SAFE_STRLEN(company->role));
855 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->role, had ? temp : "");
857 if (company->assistant_name) {
858 had = __ctsvc_contact_check_token(company->assistant_name, temp, SAFE_STRLEN(company->assistant_name));
859 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->assistant_name, had ? temp : "");
861 if (company->location) {
862 had = __ctsvc_contact_check_token(company->location, temp, SAFE_STRLEN(company->location));
863 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->location, had ? temp : "");
865 if (company->description) {
866 had = __ctsvc_contact_check_token(company->description, temp, SAFE_STRLEN(company->description));
867 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->description, had ? temp : "");
869 if (company->phonetic_name) {
870 had = __ctsvc_contact_check_token(company->phonetic_name, temp, SAFE_STRLEN(company->phonetic_name));
871 len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->phonetic_name, had ? temp : "");
877 } while (CONTACTS_ERROR_NONE == contacts_list_next(company_list));
880 *search_number = number;
884 return CONTACTS_ERROR_NONE;
887 static inline int __ctsvc_contact_refresh_lookup_data(int contact_id, ctsvc_contact_s *contact)
890 int ret, len = 0, temp_len = 0;
891 char query[CTS_SQL_MAX_LEN] = {0};
893 snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d",
894 CTS_TABLE_NAME_LOOKUP, contact_id);
895 ret = ctsvc_query_exec(query);
896 if (CONTACTS_ERROR_NONE != ret) {
897 /* LCOV_EXCL_START */
898 ERR("ctsvc_query_exec() Fail(%d)", ret);
903 snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d",
904 CTS_TABLE_PHONE_LOOKUP, contact_id);
905 ret = ctsvc_query_exec(query);
906 if (CONTACTS_ERROR_NONE != ret) {
907 /* LCOV_EXCL_START */
908 ERR("ctsvc_query_exec() Fail(%d)", ret);
914 return CONTACTS_ERROR_NO_DATA;
917 contacts_list_h name_list = (contacts_list_h)contact->name;
918 ctsvc_name_s *name_record;
919 cts_stmt stmt = NULL;
920 char *temp_name = NULL;
921 contacts_list_first(name_list);
923 /* name record of contact should be one */
925 contacts_list_get_current_record_p(name_list, (contacts_record_h*)&name_record);
927 && (name_record->last
928 || name_record->first
929 || name_record->addition
930 || name_record->suffix)) {
931 char *normalized_name = NULL;
934 * Make reverse display name (Last name first)
935 * Default : Prefix Last, First Middle(addition), Suffix
936 * Korean, Chinese : Prefix LastMiddleFirstSuffix
937 * Japanese : Prefix Last Middle First Suffix
938 * reverse sort name does not include prefix
939 * But, if there is only prefix, reverse sort_name is prefix
941 /* make display name */
942 temp_len = SAFE_STRLEN(name_record->first)
943 + SAFE_STRLEN(name_record->addition)
944 + SAFE_STRLEN(name_record->last)
945 + SAFE_STRLEN(name_record->suffix)
947 int reverse_lang_type = ctsvc_contact_get_name_language(name_record);
948 temp_name = calloc(1, temp_len);
949 if (NULL == temp_name) {
950 /* LCOV_EXCL_START */
951 ERR("calloc() Fail");
952 return CONTACTS_ERROR_OUT_OF_MEMORY;
956 if (reverse_lang_type == CTSVC_LANG_KOREAN ||
957 reverse_lang_type == CTSVC_LANG_CHINESE ||
958 reverse_lang_type == CTSVC_LANG_JAPANESE) {
959 if (name_record->last)
960 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->last);
961 if (name_record->addition)
962 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->addition);
963 if (name_record->first)
964 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->first);
965 if (name_record->suffix)
966 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->suffix);
968 if (name_record->last)
969 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->last);
970 if (name_record->first)
971 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->first);
972 if (name_record->addition)
973 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->addition);
974 if (name_record->suffix)
975 len += snprintf(temp_name + len, temp_len - len, "%s", name_record->suffix);
978 ctsvc_normalize_str(temp_name, &normalized_name);
979 snprintf(query, sizeof(query), "INSERT INTO %s(data_id, contact_id, name, type) "
980 "VALUES(%d, %d, ?, %d)", CTS_TABLE_NAME_LOOKUP, name_record->id,
983 ret = ctsvc_query_prepare(query, &stmt);
985 /* LCOV_EXCL_START */
986 ERR("ctsvc_query_prepare() Fail(%d)", ret);
988 free(normalized_name);
994 ctsvc_stmt_bind_text(stmt, 1, normalized_name);
996 ret = ctsvc_stmt_step(stmt);
999 free(normalized_name);
1001 ctsvc_stmt_finalize(stmt);
1003 if (CONTACTS_ERROR_NONE != ret) {
1004 /* LCOV_EXCL_START */
1005 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1007 /* LCOV_EXCL_STOP */
1011 } while (CONTACTS_ERROR_NONE == contacts_list_next(name_list));
1014 if (contact->numbers) {
1015 contacts_list_h number_list = (contacts_list_h)contact->numbers;
1016 cts_stmt stmt = NULL;
1017 ctsvc_number_s *number_record;
1018 contacts_list_first(number_list);
1021 contacts_list_get_current_record_p(number_list, (contacts_record_h*)&number_record);
1022 if (number_record && number_record->number) {
1023 if (NULL == number_record->cleaned)
1026 /* actually phone_lookup minmatch is not used */
1027 snprintf(query, sizeof(query), "INSERT INTO %s(data_id, contact_id, number, min_match) "
1028 "VALUES(%d, %d, ?, ?)", CTS_TABLE_PHONE_LOOKUP, number_record->id,
1031 ret = ctsvc_query_prepare(query, &stmt);
1032 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
1034 if (*number_record->cleaned)
1035 ctsvc_stmt_bind_text(stmt, 1, number_record->cleaned);
1036 ret = ctsvc_stmt_step(stmt);
1037 if (CONTACTS_ERROR_NONE != ret) {
1038 /* LCOV_EXCL_START */
1039 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1040 ctsvc_stmt_finalize(stmt);
1042 /* LCOV_EXCL_STOP */
1044 if (number_record->normalized && STRING_EQUAL != strcmp(number_record->cleaned, number_record->normalized)) {
1045 ctsvc_stmt_reset(stmt);
1046 if (*number_record->normalized)
1047 ctsvc_stmt_bind_text(stmt, 1, number_record->normalized);
1048 ret = ctsvc_stmt_step(stmt);
1049 if (CONTACTS_ERROR_NONE != ret) {
1050 /* LCOV_EXCL_START */
1051 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1052 ctsvc_stmt_finalize(stmt);
1054 /* LCOV_EXCL_STOP */
1057 ctsvc_stmt_finalize(stmt);
1059 } while (CONTACTS_ERROR_NONE == contacts_list_next(number_list));
1062 if (contact->nicknames) {
1063 contacts_list_h nickname_list = (contacts_list_h)contact->nicknames;
1064 cts_stmt stmt = NULL;
1065 ctsvc_nickname_s *nickname;
1066 contacts_list_first(nickname_list);
1068 contacts_list_get_current_record_p(nickname_list, (contacts_record_h*)&nickname);
1069 if (nickname && nickname->nickname) {
1070 char *normalized_nickname = NULL;
1071 ctsvc_normalize_str(nickname->nickname, &normalized_nickname);
1072 snprintf(query, sizeof(query), "INSERT INTO %s(data_id, contact_id, name, type) "
1073 "VALUES(%d, %d, ?, %d)", CTS_TABLE_NAME_LOOKUP, nickname->id,
1074 contact_id, CONTACTS_DATA_TYPE_NICKNAME);
1076 ret = ctsvc_query_prepare(query, &stmt);
1078 /* LCOV_EXCL_START */
1079 ERR("ctsvc_query_prepare() Fail(%d)", ret);
1080 free(normalized_nickname);
1082 /* LCOV_EXCL_STOP */
1085 if (normalized_nickname && *normalized_nickname)
1086 ctsvc_stmt_bind_text(stmt, 1, normalized_nickname);
1088 ret = ctsvc_stmt_step(stmt);
1090 free(normalized_nickname);
1092 ctsvc_stmt_finalize(stmt);
1094 if (CONTACTS_ERROR_NONE != ret) {
1095 /* LCOV_EXCL_START */
1096 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1098 /* LCOV_EXCL_STOP */
1101 } while (CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
1104 return CONTACTS_ERROR_NONE;
1107 static inline int __ctsvc_contact_update_search_data(int contact_id, bool need_refresh_lookup_data)
1110 cts_stmt stmt = NULL;
1111 char query[CTS_SQL_MAX_LEN] = {0};
1112 char *search_name = NULL;
1113 char *search_number = NULL;
1114 char *search_data = NULL;
1115 ctsvc_contact_s *contact = NULL;
1117 ret = ctsvc_begin_trans();
1118 RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
1120 ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&contact);
1121 if (CONTACTS_ERROR_NO_DATA == ret) {
1123 snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d",
1124 CTS_TABLE_SEARCH_INDEX, contact_id);
1125 r = ctsvc_query_exec(query);
1126 if (CONTACTS_ERROR_NONE != r) {
1127 /* LCOV_EXCL_START */
1128 ERR("ctsvc_query_exec() Fail(%d)", r);
1129 ctsvc_end_trans(false);
1131 /* LCOV_EXCL_STOP */
1133 ctsvc_end_trans(false);
1135 } else if (CONTACTS_ERROR_NONE != ret) {
1136 /* LCOV_EXCL_START */
1137 ERR("ctsvc_db_contact_get() Fail(%d)", ret);
1138 ctsvc_end_trans(false);
1140 /* LCOV_EXCL_STOP */
1143 ret = ctsvc_contact_make_search_name(contact, &search_name);
1144 if (CONTACTS_ERROR_NONE != ret) {
1145 /* LCOV_EXCL_START */
1146 ERR("ctsvc_contact_make_search_name() Fail(%d)", ret);
1147 contacts_record_destroy((contacts_record_h)contact, true);
1148 ctsvc_end_trans(false);
1150 /* LCOV_EXCL_STOP */
1153 ret = __ctsvc_contact_make_search_data(contact, &search_number, &search_data);
1154 if (CONTACTS_ERROR_NONE != ret) {
1155 /* LCOV_EXCL_START */
1156 ERR("__ctsvc_contact_make_search_data() Fail(%d)", ret);
1157 contacts_record_destroy((contacts_record_h)contact, true);
1158 ctsvc_end_trans(false);
1161 /* LCOV_EXCL_STOP */
1164 snprintf(query, sizeof(query),
1165 "UPDATE %s SET name=?, number=?, data=? "
1166 "WHERE contact_id = %d",
1167 CTS_TABLE_SEARCH_INDEX, contact_id);
1169 ret = ctsvc_query_prepare(query, &stmt);
1171 /* LCOV_EXCL_START */
1172 ERR("ctsvc_query_prepare() Fail(%d)", ret);
1173 contacts_record_destroy((contacts_record_h)contact, true);
1174 ctsvc_end_trans(false);
1176 free(search_number);
1179 /* LCOV_EXCL_STOP */
1183 ctsvc_stmt_bind_text(stmt, 1, search_name);
1185 ctsvc_stmt_bind_text(stmt, 2, search_number);
1187 ctsvc_stmt_bind_text(stmt, 3, search_data);
1189 ret = ctsvc_stmt_step(stmt);
1192 free(search_number);
1195 if (CONTACTS_ERROR_NONE != ret) {
1196 /* LCOV_EXCL_START */
1197 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1198 contacts_record_destroy((contacts_record_h)contact, true);
1199 ctsvc_stmt_finalize(stmt);
1200 ctsvc_end_trans(false);
1202 /* LCOV_EXCL_STOP */
1204 ctsvc_stmt_finalize(stmt);
1206 if (need_refresh_lookup_data) {
1207 /* update phone_lookup, name_lookup */
1208 ret = __ctsvc_contact_refresh_lookup_data(contact_id, contact);
1209 if (CONTACTS_ERROR_NONE != ret) {
1210 /* LCOV_EXCL_START */
1211 ERR("__ctsvc_contact_refresh_lookup_data() Fail(%d)", ret);
1212 contacts_record_destroy((contacts_record_h)contact, true);
1213 ctsvc_end_trans(false);
1215 /* LCOV_EXCL_STOP */
1219 contacts_record_destroy((contacts_record_h)contact, true);
1221 ret = ctsvc_end_trans(true);
1222 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
1224 return CONTACTS_ERROR_NONE;
1227 static bool __ctsvc_list_check_dirty(ctsvc_list_s *list)
1230 if (list->deleted_records)
1234 for (c = list->records; c; c = c->next) {
1235 ctsvc_record_s *s_record = c->data;
1237 unsigned int property_info_count = 0;
1238 const property_info_s *property_info = ctsvc_view_get_all_property_infos(s_record->view_uri, &property_info_count);
1239 for (i = 0; i < property_info_count; i++) {
1240 bool ret = ctsvc_record_check_property_flag(s_record,
1241 property_info[i].property_id, CTSVC_PROPERTY_FLAG_DIRTY);
1250 static bool __ctsvc_get_need_refresh_lookup_data(ctsvc_contact_s *contact)
1252 if (__ctsvc_list_check_dirty(contact->name))
1254 if (__ctsvc_list_check_dirty(contact->numbers))
1256 if (__ctsvc_list_check_dirty(contact->nicknames))
1261 static int __ctsvc_db_contact_update_record(contacts_record_h record)
1264 int rel_changed = 0;
1267 char query[CTS_SQL_MAX_LEN] = {0};
1268 GSList *bind_text = NULL;
1269 GSList *cursor = NULL;
1270 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
1271 bool is_invalid = false;
1272 int current_version = 0;
1274 ret = ctsvc_begin_trans();
1275 RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
1277 snprintf(query, sizeof(query),
1278 "SELECT changed_ver FROM "CTS_TABLE_CONTACTS" "
1279 "WHERE contact_id = %d AND deleted = 0", contact->id);
1280 ret = ctsvc_query_get_first_int_result(query, ¤t_version);
1281 if (CONTACTS_ERROR_NONE != ret) {
1282 /* LCOV_EXCL_START */
1283 ERR("The index(%d) is Invalid. %d Record(s) is(are) found", contact->id, ret);
1284 ctsvc_end_trans(false);
1286 /* LCOV_EXCL_STOP */
1289 if (false == ctsvc_have_ab_write_permission(contact->addressbook_id, false)) {
1290 /* LCOV_EXCL_START */
1291 ERR("No permission in this addresbook_id(%d)", contact->addressbook_id);
1292 ctsvc_end_trans(false);
1293 return CONTACTS_ERROR_PERMISSION_DENIED;
1294 /* LCOV_EXCL_STOP */
1297 if (current_version != contact->changed_ver)
1299 __ctsvc_contact_check_default_data(contact);
1301 /* check lookup data is dirty */
1302 bool need_update_lookup = __ctsvc_get_need_refresh_lookup_data(contact);
1305 ret = __ctsvc_contact_update_data(contact);
1306 if (CONTACTS_ERROR_NONE != ret) {
1307 /* LCOV_EXCL_START */
1308 ERR("__ctsvc_contact_update_data() Fail(%d)", ret);
1309 ctsvc_end_trans(false);
1311 /* LCOV_EXCL_STOP */
1314 if (contact->grouprelations) {
1315 rel_changed = __ctsvc_contact_update_grouprel(contact->id, (contacts_list_h)contact->grouprelations);
1316 if (rel_changed < CONTACTS_ERROR_NONE) {
1317 /* LCOV_EXCL_START */
1318 ERR("cts_update_contact_grouprel() Fail(%d)", rel_changed);
1319 ctsvc_end_trans(false);
1321 /* LCOV_EXCL_STOP */
1326 if (contact->images) {
1327 int ret = CONTACTS_ERROR_NONE;
1329 ctsvc_image_s *image;
1330 char *contact_image_path = NULL;
1332 contacts_list_get_count((contacts_list_h)contact->images, &count);
1334 contacts_list_first((contacts_list_h)contact->images);
1336 ret = contacts_list_get_current_record_p((contacts_list_h)contact->images, (contacts_record_h*)&image);
1337 if (CONTACTS_ERROR_NONE != ret) {
1338 /* LCOV_EXCL_START */
1339 ERR("contacts_list_get_current_record_p() Fail(%d)", ret);
1340 ctsvc_end_trans(false);
1341 return CONTACTS_ERROR_DB;
1342 /* LCOV_EXCL_STOP */
1345 if (image->is_default)
1347 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
1349 contact_image_path = ctsvc_utils_get_image_path(contact->image_thumbnail_path);
1351 if ((NULL == contact_image_path && image->path) ||
1352 (contact_image_path && NULL == image->path) ||
1353 (contact_image_path && image->path && (STRING_EQUAL != strcmp(contact_image_path, image->path)))) {
1354 free(contact->image_thumbnail_path);
1355 contact->image_thumbnail_path = NULL;
1356 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
1359 contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
1361 free(contact_image_path);
1362 } else if (contact->image_thumbnail_path) {
1363 free(contact->image_thumbnail_path);
1364 contact->image_thumbnail_path = NULL;
1365 bool is_changed = ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
1366 if ((false == is_changed && false == is_invalid) || (is_changed && false == is_invalid)) {
1367 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
1369 if (((ctsvc_record_s*)record)->properties_flags) {
1370 int index = _contacts_contact.image_thumbnail_path & 0x000000FF;
1371 ((ctsvc_record_s*)record)->properties_flags[index] = 0;
1378 ctsvc_contact_s *temp_contact;
1379 contacts_record_create(_contacts_contact._uri, (contacts_record_h*)&temp_contact);
1380 ret = __ctsvc_db_get_data(contact->id, temp_contact);
1381 ctsvc_contact_make_display_name(temp_contact);
1383 FREEandSTRDUP(contact->display_name, temp_contact->display_name);
1384 FREEandSTRDUP(contact->reverse_display_name, temp_contact->reverse_display_name);
1385 FREEandSTRDUP(contact->sort_name, temp_contact->sort_name);
1386 FREEandSTRDUP(contact->reverse_sort_name, temp_contact->reverse_sort_name);
1387 FREEandSTRDUP(contact->sortkey, temp_contact->sortkey);
1388 FREEandSTRDUP(contact->reverse_sortkey, temp_contact->reverse_sortkey);
1390 contact->display_name_language = temp_contact->display_name_language;
1391 contact->reverse_display_name_language = temp_contact->reverse_display_name_language;
1392 contact->display_source_type = temp_contact->display_source_type;
1394 if (ctsvc_record_check_property_flag((ctsvc_record_s*)temp_contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY))
1395 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
1397 contacts_record_destroy((contacts_record_h)temp_contact, true);
1399 ctsvc_contact_make_display_name(contact);
1403 char query[CTS_SQL_MAX_LEN] = {0};
1404 char query_set[CTS_SQL_MIN_LEN] = {0, };
1405 cts_stmt stmt = NULL;
1407 version = ctsvc_get_next_ver();
1409 ret = ctsvc_db_create_set_query(record, &set, &bind_text);
1410 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_db_create_set_query() Fail(%d)", ret);
1413 len = snprintf(query_set, sizeof(query_set), "%s, ", set);
1414 len += snprintf(query_set+len, sizeof(query_set)-len, " changed_ver=%d, changed_time=%d, has_phonenumber=%d, has_email=%d",
1415 version, (int)time(NULL), contact->has_phonenumber, contact->has_email);
1416 if (ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY)) {
1417 len += snprintf(query_set+len, sizeof(query_set)-len,
1418 ", display_name=?, reverse_display_name=?, display_name_source=%d, "
1419 "display_name_language=%d, reverse_display_name_language=%d, "
1420 "sort_name=?, reverse_sort_name=?, sortkey=?, reverse_sortkey=?",
1421 contact->display_source_type, contact->display_name_language, contact->reverse_display_name_language);
1422 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->display_name)));
1423 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_display_name)));
1424 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->sort_name)));
1425 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_sort_name)));
1426 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->sortkey)));
1427 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_sortkey)));
1430 if (ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY))
1431 len += snprintf(query_set+len, sizeof(query_set)-len, ", image_changed_ver=%d", version);
1433 snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE contact_id = %d", CTS_TABLE_CONTACTS, query_set, contact->id);
1435 ret = ctsvc_query_prepare(query, &stmt);
1437 /* LCOV_EXCL_START */
1438 ERR("ctsvc_query_prepare() Fail(%d)", ret);
1440 /* LCOV_EXCL_STOP */
1445 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++) {
1446 const char *text = cursor->data;
1448 ctsvc_stmt_bind_text(stmt, i, text);
1451 ret = ctsvc_stmt_step(stmt);
1452 if (CONTACTS_ERROR_NONE != ret) {
1453 /* LCOV_EXCL_START */
1454 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1455 ctsvc_stmt_finalize(stmt);
1457 /* LCOV_EXCL_STOP */
1459 ctsvc_stmt_finalize(stmt);
1462 if (CONTACTS_ERROR_NONE != ret) {
1463 ctsvc_end_trans(false);
1464 CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s*)record);
1468 for (cursor = bind_text; cursor; cursor = cursor->next) {
1470 cursor->data = NULL;
1472 g_slist_free(bind_text);
1477 ctsvc_set_contact_noti();
1478 if (0 < rel_changed)
1479 ctsvc_set_group_rel_noti();
1481 __ctsvc_contact_update_search_data(contact->id, need_update_lookup);
1482 ctsvc_db_update_person((contacts_record_h)contact);
1484 CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s*)record);
1488 for (cursor = bind_text; cursor; cursor = cursor->next) {
1490 cursor->data = NULL;
1492 g_slist_free(bind_text);
1495 ret = ctsvc_end_trans(true);
1496 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
1498 return CONTACTS_ERROR_NONE;
1501 static int __ctsvc_db_contact_get_all_records(int offset, int limit, contacts_list_h *out_list)
1507 char query[CTS_SQL_MAX_LEN] = {0};
1508 contacts_list_h list;
1510 len = snprintf(query, sizeof(query),
1511 "SELECT contact_id FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0");
1514 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
1516 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
1519 ret = ctsvc_query_prepare(query, &stmt);
1520 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
1522 contacts_list_create(&list);
1523 while ((ret = ctsvc_stmt_step(stmt))) {
1524 contacts_record_h record;
1526 /* LCOV_EXCL_START */
1527 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1528 ctsvc_stmt_finalize(stmt);
1529 contacts_list_destroy(list, true);
1531 /* LCOV_EXCL_STOP */
1533 contact_id = ctsvc_stmt_get_int(stmt, 0);
1534 ret = ctsvc_db_contact_get(contact_id, &record);
1535 if (CONTACTS_ERROR_NONE != ret) {
1536 /* LCOV_EXCL_START */
1537 ERR("ctsvc_db_contact_get() Fail(%d)", ret);
1538 ctsvc_stmt_finalize(stmt);
1539 contacts_list_destroy(list, true);
1541 /* LCOV_EXCL_STOP */
1543 ctsvc_list_prepend(list, record);
1545 ctsvc_stmt_finalize(stmt);
1546 ctsvc_list_reverse(list);
1548 *out_list = (contacts_list_h)list;
1549 return CONTACTS_ERROR_NONE;
1552 static int __ctsvc_db_contact_get_changed_ver(int contact_id, ctsvc_contact_s *contact)
1556 char query[CTS_SQL_MAX_LEN] = {0};
1558 snprintf(query, sizeof(query),
1559 "SELECT changed_ver FROM "CTS_TABLE_CONTACTS
1560 " WHERE contact_id = %d AND deleted = 0", contact_id);
1561 ret = ctsvc_query_get_first_int_result(query, &version);
1562 if (CONTACTS_ERROR_NONE == ret)
1563 contact->changed_ver = version;
1567 static int __ctsvc_db_contact_get_records_with_query(contacts_query_h query, int offset, int limit, contacts_list_h *out_list)
1572 ctsvc_query_s *s_query;
1574 contacts_list_h list;
1575 ctsvc_contact_s *contact;
1576 char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
1577 bool had_contact_id = false;
1580 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
1581 s_query = (ctsvc_query_s*)query;
1583 if (s_query->projection) {
1584 for (i = 0; i < s_query->projection_count; i++) {
1585 if (s_query->projection[i] == CTSVC_PROPERTY_CONTACT_ID) {
1586 had_contact_id = true;
1591 s_query->projection_count = 0;
1592 had_contact_id = true;
1595 if (false == had_contact_id) {
1596 s_query->projection = realloc(s_query->projection, s_query->projection_count+1);
1597 if (NULL == s_query->projection) {
1598 /* LCOV_EXCL_START */
1599 ERR("realloc() Fail");
1600 return CONTACTS_ERROR_OUT_OF_MEMORY;
1601 /* LCOV_EXCL_STOP */
1604 s_query->projection[s_query->projection_count] = CTSVC_PROPERTY_CONTACT_ID;
1605 s_query->projection_count++;
1608 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
1609 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
1611 contacts_list_create(&list);
1612 while ((ret = ctsvc_stmt_step(stmt))) {
1613 contacts_record_h record;
1615 /* LCOV_EXCL_START */
1616 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1617 ctsvc_stmt_finalize(stmt);
1618 contacts_list_destroy(list, true);
1620 /* LCOV_EXCL_STOP */
1623 contacts_record_create(_contacts_contact._uri, &record);
1624 contact = (ctsvc_contact_s*)record;
1625 if (0 == s_query->projection_count) {
1626 field_count = s_query->property_count;
1628 field_count = s_query->projection_count;
1629 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
1630 s_query->projection_count, s_query->property_count);
1632 if (CONTACTS_ERROR_NONE != ret)
1633 ASSERT_NOT_REACHED("To set projection is failed.\n");
1636 for (i = 0; i < field_count; i++) {
1639 if (0 == s_query->projection_count)
1640 property_id = s_query->properties[i].property_id;
1642 property_id = s_query->projection[i];
1644 switch (property_id) {
1645 case CTSVC_PROPERTY_CONTACT_ID:
1646 contact_id = ctsvc_stmt_get_int(stmt, i);
1648 contact->id = contact_id;
1650 case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
1651 temp = ctsvc_stmt_get_text(stmt, i);
1652 free(contact->display_name);
1653 contact->display_name = SAFE_STRDUP(temp);
1655 case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
1656 contact->display_source_type = ctsvc_stmt_get_int(stmt, i);
1658 case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
1659 contact->addressbook_id = ctsvc_stmt_get_int(stmt, i);
1661 case CTSVC_PROPERTY_CONTACT_RINGTONE:
1662 temp = ctsvc_stmt_get_text(stmt, i);
1663 free(contact->ringtone_path);
1664 contact->ringtone_path = SAFE_STRDUP(temp);
1666 case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
1667 temp = ctsvc_stmt_get_text(stmt, i);
1668 if (temp && *temp) {
1669 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
1670 free(contact->image_thumbnail_path);
1671 contact->image_thumbnail_path = strdup(full_path);
1674 case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
1675 contact->is_favorite = ctsvc_stmt_get_int(stmt, i);
1677 case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
1678 contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
1680 case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
1681 contact->has_email = ctsvc_stmt_get_int(stmt, i);
1683 case CTSVC_PROPERTY_CONTACT_PERSON_ID:
1684 contact->person_id = ctsvc_stmt_get_int(stmt, i);
1686 case CTSVC_PROPERTY_CONTACT_UID:
1687 temp = ctsvc_stmt_get_text(stmt, i);
1689 contact->uid = SAFE_STRDUP(temp);
1691 case CTSVC_PROPERTY_CONTACT_VIBRATION:
1692 temp = ctsvc_stmt_get_text(stmt, i);
1693 free(contact->vibration);
1694 contact->vibration = SAFE_STRDUP(temp);
1696 case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
1697 temp = ctsvc_stmt_get_text(stmt, i);
1698 free(contact->message_alert);
1699 contact->message_alert = SAFE_STRDUP(temp);
1701 case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
1702 contact->changed_time = ctsvc_stmt_get_int(stmt, i);
1704 case CTSVC_PROPERTY_CONTACT_LINK_MODE:
1705 contact->link_mode = ctsvc_stmt_get_int(stmt, i);
1711 /* get changed_ver */
1712 ret = __ctsvc_db_contact_get_changed_ver(contact_id, contact);
1713 if (CONTACTS_ERROR_NONE != ret) {
1714 /* LCOV_EXCL_START */
1715 ERR("__ctsvc_db_contact_get_changed_ver Fail(%d)", ret);
1716 ctsvc_stmt_finalize(stmt);
1717 contacts_list_destroy(list, true);
1719 /* LCOV_EXCL_STOP */
1722 ret = __ctsvc_db_get_data(contact_id, contact);
1723 if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
1724 /* LCOV_EXCL_START */
1725 ERR("ctsvc_get_data_info Fail(%d)", ret);
1726 ctsvc_stmt_finalize(stmt);
1727 contacts_list_destroy(list, true);
1729 /* LCOV_EXCL_STOP */
1732 ret = __ctsvc_get_contact_grouprel(contact_id, contact);
1733 if (CONTACTS_ERROR_NONE != ret) {
1734 /* LCOV_EXCL_START */
1735 ERR("ctsvc_get_group_relations Fail(%d)", ret);
1736 ctsvc_stmt_finalize(stmt);
1737 contacts_list_destroy(list, true);
1739 /* LCOV_EXCL_STOP */
1742 ctsvc_list_prepend(list, record);
1744 ctsvc_stmt_finalize(stmt);
1745 ctsvc_list_reverse(list);
1747 *out_list = (contacts_list_h)list;
1749 return CONTACTS_ERROR_NONE;
1753 static int __ctsvc_contact_insert_data(ctsvc_contact_s *contact)
1757 /* Insert the name */
1758 if (contact->name) {
1759 ret = ctsvc_contact_insert_data_name((contacts_list_h)contact->name, contact->id, false);
1760 if (CONTACTS_ERROR_NONE != ret) {
1761 /* LCOV_EXCL_START */
1762 ERR("ctsvc_contact_insert_data_name() Fail(%d)", ret);
1764 /* LCOV_EXCL_STOP */
1768 /* Insert the company */
1769 if (contact->company) {
1770 ret = ctsvc_contact_insert_data_company((contacts_list_h)contact->company, contact->id, false);
1771 if (CONTACTS_ERROR_NONE != ret) {
1772 /* LCOV_EXCL_START */
1773 ERR("ctsvc_insert_contact_data_company() Fail(%d)", ret);
1775 /* LCOV_EXCL_STOP */
1779 /* Insert the events */
1780 if (contact->events) {
1781 ret = ctsvc_contact_insert_data_event((contacts_list_h)contact->events, contact->id, false);
1782 if (CONTACTS_ERROR_NONE != ret) {
1783 /* LCOV_EXCL_START */
1784 ERR("ctsvc_insert_contact_data_event() Fail(%d)", ret);
1786 /* LCOV_EXCL_STOP */
1790 /* Insert the messengers */
1791 if (contact->messengers) {
1792 ret = ctsvc_contact_insert_data_messenger((contacts_list_h)contact->messengers, contact->id, false);
1793 if (CONTACTS_ERROR_NONE != ret) {
1794 /* LCOV_EXCL_START */
1795 ERR("ctsvc_insert_contact_data_messenger() Fail(%d)", ret);
1797 /* LCOV_EXCL_STOP */
1801 /* Insert the postals */
1802 if (contact->postal_addrs) {
1803 ret = ctsvc_contact_insert_data_address((contacts_list_h)contact->postal_addrs, contact->id, false);
1804 if (CONTACTS_ERROR_NONE != ret) {
1805 /* LCOV_EXCL_START */
1806 ERR("ctsvc_insert_contact_data_postal() Fail(%d)", ret);
1808 /* LCOV_EXCL_STOP */
1812 /* Insert the Web addrs */
1813 if (contact->urls) {
1814 ret = ctsvc_contact_insert_data_url((contacts_list_h)contact->urls, contact->id, false);
1815 if (CONTACTS_ERROR_NONE != ret) {
1816 /* LCOV_EXCL_START */
1817 ERR("ctsvc_insert_contact_data_web() Fail(%d)", ret);
1819 /* LCOV_EXCL_STOP */
1823 /* Insert the Nick names */
1824 if (contact->nicknames) {
1825 ret = ctsvc_contact_insert_data_nickname((contacts_list_h)contact->nicknames, contact->id, false);
1826 if (CONTACTS_ERROR_NONE != ret) {
1827 /* LCOV_EXCL_START */
1828 ERR("ctsvc_insert_contact_data_nickname() Fail(%d)", ret);
1830 /* LCOV_EXCL_STOP */
1834 /* Insert the numbers */
1835 if (contact->numbers) {
1836 ret = ctsvc_contact_insert_data_number((contacts_list_h)contact->numbers, contact->id, false);
1837 if (ret < CONTACTS_ERROR_NONE) {
1838 /* LCOV_EXCL_START */
1839 ERR("ctsvc_contact_insert_data_number() Fail(%d)", ret);
1841 /* LCOV_EXCL_STOP */
1845 /* Insert the emails */
1846 if (contact->emails) {
1847 ret = ctsvc_contact_insert_data_email((contacts_list_h)contact->emails, contact->id, false);
1848 if (ret < CONTACTS_ERROR_NONE) {
1849 /* LCOV_EXCL_START */
1850 ERR("ctsvc_insert_contact_data_email() Fail(%d)", ret);
1852 /* LCOV_EXCL_STOP */
1856 /* Insert the profile values */
1857 if (contact->profiles) {
1858 ret = ctsvc_contact_insert_data_profile((contacts_list_h)contact->profiles, contact->id, false);
1859 if (CONTACTS_ERROR_NONE != ret) {
1860 /* LCOV_EXCL_START */
1861 ERR("ctsvc_insert_contact_data_profile() Fail(%d)", ret);
1863 /* LCOV_EXCL_STOP */
1867 /* Insert the relationship values */
1868 if (contact->relationships) {
1869 ret = ctsvc_contact_insert_data_relationship((contacts_list_h)contact->relationships, contact->id, false);
1870 if (CONTACTS_ERROR_NONE != ret) {
1871 /* LCOV_EXCL_START */
1872 ERR("ctsvc_contact_insert_data_relationship() Fail(%d)", ret);
1874 /* LCOV_EXCL_STOP */
1878 /* Insert the image values */
1879 if (contact->images) {
1880 ret = ctsvc_contact_insert_data_image((contacts_list_h)contact->images, contact->id, false);
1881 if (CONTACTS_ERROR_NONE != ret) {
1882 /* LCOV_EXCL_START */
1883 ERR("ctsvc_contact_insert_data_image() Fail(%d)", ret);
1885 /* LCOV_EXCL_STOP */
1889 /* Insert the note values */
1890 if (contact->note) {
1891 ret = ctsvc_contact_insert_data_note((contacts_list_h)contact->note, contact->id, false);
1892 if (CONTACTS_ERROR_NONE != ret) {
1893 /* LCOV_EXCL_START */
1894 ERR("ctsvc_contact_insert_data_note() Fail(%d)", ret);
1896 /* LCOV_EXCL_STOP */
1900 /* Insert the extensions values */
1901 if (contact->extensions) {
1902 ret = ctsvc_contact_insert_data_extension((contacts_list_h)contact->extensions, contact->id, false);
1903 if (CONTACTS_ERROR_NONE != ret) {
1904 /* LCOV_EXCL_START */
1905 ERR("ctsvc_contact_insert_data_extension() Fail(%d)", ret);
1907 /* LCOV_EXCL_STOP */
1911 /* Insert the sips */
1912 if (contact->sips) {
1913 ret = ctsvc_contact_insert_data_sip((contacts_list_h)contact->sips, contact->id, false);
1914 if (CONTACTS_ERROR_NONE != ret) {
1915 /* LCOV_EXCL_START */
1916 ERR("ctsvc_insert_contact_data_sip() Fail(%d)", ret);
1918 /* LCOV_EXCL_STOP */
1922 return CONTACTS_ERROR_NONE;
1925 static inline int __ctsvc_contact_insert_search_data(int contact_id, bool need_insert_lookup_data)
1928 cts_stmt stmt = NULL;
1929 char query[CTS_SQL_MAX_LEN] = {0};
1930 char *search_name = NULL;
1931 char *search_number = NULL;
1932 char *search_data = NULL;
1933 ctsvc_contact_s *contact = NULL;
1935 ret = ctsvc_begin_trans();
1936 RETVM_IF(ret, ret, "contacts_begin_trans() Fail(%d)", ret);
1938 ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&contact);
1939 if (CONTACTS_ERROR_NONE != ret) {
1940 /* LCOV_EXCL_START */
1941 ERR("ctsvc_db_contact_get() Fail(%d)", ret);
1942 ctsvc_end_trans(false);
1944 /* LCOV_EXCL_STOP */
1947 ret = ctsvc_contact_make_search_name(contact, &search_name);
1948 if (CONTACTS_ERROR_NONE != ret) {
1949 /* LCOV_EXCL_START */
1950 ERR("ctsvc_contact_make_search_name() Fail(%d)", ret);
1951 contacts_record_destroy((contacts_record_h)contact, true);
1952 ctsvc_end_trans(false);
1954 /* LCOV_EXCL_STOP */
1957 ret = __ctsvc_contact_make_search_data(contact, &search_number, &search_data);
1958 if (CONTACTS_ERROR_NONE != ret) {
1959 /* LCOV_EXCL_START */
1960 ERR("__ctsvc_contact_make_search_data() Fail(%d)", ret);
1961 contacts_record_destroy((contacts_record_h)contact, true);
1962 ctsvc_end_trans(false);
1965 /* LCOV_EXCL_STOP */
1968 snprintf(query, sizeof(query),
1969 "INSERT INTO %s(contact_id, name, number, data) "
1970 "VALUES(%d, ?, ?, ?)",
1971 CTS_TABLE_SEARCH_INDEX, contact_id);
1973 ret = ctsvc_query_prepare(query, &stmt);
1975 /* LCOV_EXCL_START */
1976 ERR("ctsvc_query_prepare() Fail(%d)", ret);
1977 contacts_record_destroy((contacts_record_h)contact, true);
1978 ctsvc_end_trans(false);
1980 free(search_number);
1983 /* LCOV_EXCL_STOP */
1987 ctsvc_stmt_bind_text(stmt, 1, search_name);
1989 ctsvc_stmt_bind_text(stmt, 2, search_number);
1991 ctsvc_stmt_bind_text(stmt, 3, search_data);
1993 ret = ctsvc_stmt_step(stmt);
1996 free(search_number);
1999 if (CONTACTS_ERROR_NONE != ret) {
2000 /* LCOV_EXCL_START */
2001 ERR("ctsvc_stmt_step() Fail(%d)", ret);
2002 contacts_record_destroy((contacts_record_h)contact, true);
2003 ctsvc_stmt_finalize(stmt);
2004 ctsvc_end_trans(false);
2006 /* LCOV_EXCL_STOP */
2008 ctsvc_stmt_finalize(stmt);
2010 /* update phone_lookup, name_lookup */
2011 if (need_insert_lookup_data) {
2012 ret = __ctsvc_contact_refresh_lookup_data(contact_id, contact);
2013 if (CONTACTS_ERROR_NONE != ret) {
2014 /* LCOV_EXCL_START */
2015 ERR("__ctsvc_contact_refresh_lookup_data() Fail(%d)", ret);
2016 contacts_record_destroy((contacts_record_h)contact, true);
2017 ctsvc_end_trans(false);
2019 /* LCOV_EXCL_STOP */
2023 contacts_record_destroy((contacts_record_h)contact, true);
2025 ret = ctsvc_end_trans(true);
2026 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
2028 return CONTACTS_ERROR_NONE;
2031 static inline int __ctsvc_contact_insert_grouprel(int contact_id, contacts_list_h group_list)
2034 ctsvc_group_relation_s *grouprel;
2035 int rel_changed = 0;
2039 RETV_IF(NULL == group_list, CONTACTS_ERROR_INVALID_PARAMETER);
2040 ret = contacts_list_get_count(group_list, &count);
2042 return CONTACTS_ERROR_NONE;
2044 contacts_list_first(group_list);
2046 contacts_list_get_current_record_p(group_list, (contacts_record_h*)&grouprel);
2047 if (NULL == grouprel)
2050 RETVM_IF(grouprel->group_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "group_id(%d) invalid", grouprel->group_id);
2051 if (grouprel->group_id) {
2052 ret = ctsvc_group_add_contact_in_transaction(grouprel->group_id, contact_id);
2053 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_db_group_set_relation() Fail(%d)", ret);
2057 } while (CONTACTS_ERROR_NONE == contacts_list_next(group_list));
2062 return CONTACTS_ERROR_NONE;
2065 static inline int __ctsvc_find_person_to_link_with_number(const char *number,
2066 int addressbook_id, int *person_id)
2069 cts_stmt stmt = NULL;
2070 char query[CTS_SQL_MIN_LEN] = {0};
2071 int number_len = SAFE_STRLEN(number);
2072 char clean_num[number_len+1];
2074 ret = ctsvc_clean_number(number, clean_num, sizeof(clean_num), true);
2076 char normal_num[sizeof(clean_num)+20];
2077 ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
2078 char minmatch[sizeof(normal_num)+1];
2080 ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
2082 snprintf(query, sizeof(query),
2083 "SELECT C.person_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
2084 "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 "
2085 "AND C.addressbook_id <> %d AND D.is_my_profile = 0 "
2086 "WHERE D.data4 = ?",
2087 /* Below condition takes long time, so omit the condition */
2088 /* AND _NUMBER_COMPARE_(D.data5, ?, NULL, NULL) */
2089 CONTACTS_DATA_TYPE_NUMBER, addressbook_id);
2091 ret = ctsvc_query_prepare(query, &stmt);
2092 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
2093 ctsvc_stmt_bind_text(stmt, 1, minmatch);
2094 /* ctsvc_stmt_bind_text(stmt, 2, normal_num); */
2095 ret = ctsvc_stmt_step(stmt);
2097 *person_id = ctsvc_stmt_get_int(stmt, 0);
2098 ret = CONTACTS_ERROR_NONE;
2099 } else if (CONTACTS_ERROR_NONE == ret) {
2100 ret = CONTACTS_ERROR_NO_DATA;
2102 ctsvc_stmt_finalize(stmt);
2103 DBG("result ret(%d) person_id(%d)", ret, *person_id);
2107 return CONTACTS_ERROR_INVALID_PARAMETER;
2110 static inline int __ctsvc_find_person_to_link_with_email(const char *email_addr, int addressbook_id, int *person_id)
2113 cts_stmt stmt = NULL;
2114 char query[CTS_SQL_MIN_LEN] = {0};
2116 snprintf(query, sizeof(query),
2117 "SELECT C.person_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
2118 "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 AND D.is_my_profile = 0 "
2119 "AND C.addressbook_id <> %d "
2120 "WHERE D.data3 = ?",
2121 CONTACTS_DATA_TYPE_EMAIL, addressbook_id);
2123 ret = ctsvc_query_prepare(query, &stmt);
2124 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
2126 ctsvc_stmt_bind_text(stmt, 1, email_addr);
2127 ret = ctsvc_stmt_step(stmt);
2129 *person_id = ctsvc_stmt_get_int(stmt, 0);
2130 ret = CONTACTS_ERROR_NONE;
2131 } else if (CONTACTS_ERROR_NONE == ret) {
2132 ret = CONTACTS_ERROR_NO_DATA;
2135 ctsvc_stmt_finalize(stmt);
2136 DBG("result ret(%d) person_id(%d)", ret, *person_id);
2141 static inline int __ctsvc_find_person_to_link(contacts_record_h record, int addressbook_id, int *person_id)
2144 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2145 ctsvc_number_s *number_data;
2146 ctsvc_email_s *email_data;
2149 for (cursor = contact->numbers->records; cursor; cursor = cursor->next) {
2150 number_data = cursor->data;
2151 if (number_data && number_data->number && number_data->number[0]) {
2152 ret = __ctsvc_find_person_to_link_with_number(number_data->number, addressbook_id, person_id);
2154 if (ret == CONTACTS_ERROR_NONE && 0 < *person_id)
2159 for (cursor = contact->emails->records; cursor; cursor = cursor->next) {
2160 email_data = cursor->data;
2161 if (email_data && email_data->email_addr && email_data->email_addr[0]) {
2162 ret = __ctsvc_find_person_to_link_with_email(email_data->email_addr, addressbook_id, person_id);
2164 if (ret == CONTACTS_ERROR_NONE && 0 < *person_id)
2169 return CONTACTS_ERROR_NO_DATA;
2172 static int __ctsvc_db_contact_insert_record(contacts_record_h record, int *id)
2175 int ret, person_id = 0;
2176 char query[CTS_SQL_MAX_LEN] = {0};
2177 bool auto_link_enabled = true;
2178 bool auto_linked = false;
2180 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2181 int rel_changed = 0;
2182 cts_stmt stmt = NULL;
2184 /* These check should be done in client side */
2185 RETV_IF(NULL == contact, CONTACTS_ERROR_INVALID_PARAMETER);
2186 RETVM_IF(contact->addressbook_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,
2187 "addressbook_id(%d) is mandatory field to insert contact record ", contact->addressbook_id);
2188 RETVM_IF(0 < contact->id, CONTACTS_ERROR_INVALID_PARAMETER,
2189 "id(%d), This record is already inserted", contact->id);
2191 if (contact->link_mode == CONTACTS_CONTACT_LINK_MODE_IGNORE_ONCE)
2192 auto_link_enabled = false;
2194 ret = ctsvc_begin_trans();
2195 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Fail(%d)", ret);
2197 if (false == ctsvc_have_ab_write_permission(contact->addressbook_id, false)) {
2198 /* LCOV_EXCL_START */
2199 ERR("No permission in this addresbook_id(%d)", contact->addressbook_id);
2200 ctsvc_end_trans(false);
2201 return CONTACTS_ERROR_PERMISSION_DENIED;
2202 /* LCOV_EXCL_STOP */
2205 ret = ctsvc_db_get_next_id(CTS_TABLE_CONTACTS);
2206 if (ret < CONTACTS_ERROR_NONE) {
2207 /* LCOV_EXCL_START */
2208 ERR("ctsvc_db_get_next_id() Fail(%d)", ret);
2209 ctsvc_end_trans(false);
2211 /* LCOV_EXCL_STOP */
2217 ctsvc_contact_make_display_name(contact);
2218 __ctsvc_contact_check_default_data(contact);
2220 /* check lookup data is dirty */
2221 bool need_insert_lookup = __ctsvc_get_need_refresh_lookup_data(contact);
2224 ret = __ctsvc_contact_insert_data(contact);
2225 if (CONTACTS_ERROR_NONE != ret) {
2226 /* LCOV_EXCL_START */
2227 ERR("cts_insert_contact_data() Fail(%d)", ret);
2228 ctsvc_end_trans(false);
2230 /* LCOV_EXCL_STOP */
2234 free(contact->image_thumbnail_path);
2235 contact->image_thumbnail_path = NULL;
2236 if (contact->images) {
2238 ctsvc_image_s *image;
2240 contacts_list_get_count((contacts_list_h)contact->images, &count);
2242 contacts_list_first((contacts_list_h)contact->images);
2244 ret = contacts_list_get_current_record_p((contacts_list_h)contact->images, (contacts_record_h*)&image);
2245 if (CONTACTS_ERROR_NONE != ret) {
2246 /* LCOV_EXCL_START */
2247 ERR("contacts_list_get_current_record_p() Fail(%d)", ret);
2248 ctsvc_end_trans(false);
2249 return CONTACTS_ERROR_DB;
2250 /* LCOV_EXCL_STOP */
2253 if (image->path && image->is_default) {
2254 contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
2257 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
2261 version = ctsvc_get_next_ver();
2263 if (contact->person_id) {
2266 snprintf(query, sizeof(query),
2267 "SELECT contact_id FROM "CTSVC_DB_VIEW_CONTACT" "
2268 "WHERE person_id = %d", contact->person_id);
2269 ret = ctsvc_query_get_first_int_result(query, &id);
2270 if (CONTACTS_ERROR_NONE != ret) {
2271 /* LCOV_EXCL_START */
2272 ERR("Invalid person_id(%d)", contact->person_id);
2273 ctsvc_end_trans(false);
2274 return CONTACTS_ERROR_INVALID_PARAMETER;
2275 /* LCOV_EXCL_STOP */
2279 } else if (auto_link_enabled) {
2280 ret = __ctsvc_find_person_to_link((contacts_record_h)contact, contact->addressbook_id, &person_id);
2281 DBG("__ctsvc_find_person_to_link return %d, person_id(%d)", ret, person_id);
2282 if (ret == CONTACTS_ERROR_NONE && 0 < person_id) {
2283 contact->person_id = person_id;
2286 ret = ctsvc_db_insert_person((contacts_record_h)contact);
2287 DBG("ctsvc_db_insert_person return %d, person_id(%d)", ret, ret);
2288 if (ret < CONTACTS_ERROR_NONE) {
2289 /* LCOV_EXCL_START */
2290 ERR("ctsvc_db_insert_person() Fail(%d)", ret);
2291 ctsvc_end_trans(false);
2293 /* LCOV_EXCL_STOP */
2295 contact->person_id = ret;
2298 ret = ctsvc_db_insert_person((contacts_record_h)contact);
2299 DBG("ctsvc_db_insert_person return %d, person_id(%d)", ret, ret);
2300 if (ret < CONTACTS_ERROR_NONE) {
2301 /* LCOV_EXCL_START */
2302 ERR("ctsvc_db_insert_person() Fail(%d)", ret);
2303 ctsvc_end_trans(false);
2305 /* LCOV_EXCL_STOP */
2307 contact->person_id = ret;
2310 snprintf(query, sizeof(query),
2311 "INSERT INTO "CTS_TABLE_CONTACTS"(contact_id, person_id, addressbook_id, is_favorite, "
2312 "created_ver, changed_ver, changed_time, link_mode, "
2313 "image_changed_ver, has_phonenumber, has_email, "
2314 "display_name, reverse_display_name, display_name_source, "
2315 "display_name_language, reverse_display_name_language, "
2316 "sort_name, reverse_sort_name, "
2317 "sortkey, reverse_sortkey, "
2318 "uid, ringtone_path, vibration, message_alert, image_thumbnail_path) "
2319 "VALUES(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, ?, ?, %d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
2320 contact->id, contact->person_id, contact->addressbook_id, contact->is_favorite,
2321 version, version, (int)time(NULL), contact->link_mode,
2322 (contact->image_thumbnail_path) ? version : 0, contact->has_phonenumber, contact->has_email,
2323 contact->display_source_type, contact->display_name_language, contact->reverse_display_name_language);
2325 ret = ctsvc_query_prepare(query, &stmt);
2327 /* LCOV_EXCL_START */
2328 ERR("ctsvc_query_prepare() Fail(%d)", ret);
2329 ctsvc_end_trans(false);
2331 /* LCOV_EXCL_STOP */
2334 if (contact->display_name)
2335 ctsvc_stmt_bind_text(stmt, 1, contact->display_name);
2336 if (contact->reverse_display_name)
2337 ctsvc_stmt_bind_text(stmt, 2, contact->reverse_display_name);
2338 if (contact->sort_name)
2339 ctsvc_stmt_bind_text(stmt, 3, contact->sort_name);
2340 if (contact->reverse_sort_name)
2341 ctsvc_stmt_bind_text(stmt, 4, contact->reverse_sort_name);
2342 if (contact->sortkey)
2343 ctsvc_stmt_bind_text(stmt, 5, contact->sortkey);
2344 if (contact->reverse_sortkey)
2345 ctsvc_stmt_bind_text(stmt, 6, contact->reverse_sortkey);
2347 ctsvc_stmt_bind_text(stmt, 7, contact->uid);
2348 if (contact->ringtone_path)
2349 ctsvc_stmt_bind_text(stmt, 8, contact->ringtone_path);
2350 if (contact->vibration)
2351 ctsvc_stmt_bind_text(stmt, 9, contact->vibration);
2352 if (contact->message_alert)
2353 ctsvc_stmt_bind_text(stmt, 10, contact->message_alert);
2354 if (contact->image_thumbnail_path)
2355 ctsvc_stmt_bind_text(stmt, 11, contact->image_thumbnail_path);
2357 ret = ctsvc_stmt_step(stmt);
2358 if (CONTACTS_ERROR_NONE != ret) {
2359 /* LCOV_EXCL_START */
2360 ERR("ctsvc_stmt_step() Fail(%d)", ret);
2361 ctsvc_stmt_finalize(stmt);
2362 ctsvc_end_trans(false);
2364 /* LCOV_EXCL_STOP */
2366 ctsvc_stmt_finalize(stmt);
2368 /* Insert group Info */
2369 if (contact->grouprelations) {
2370 rel_changed = __ctsvc_contact_insert_grouprel(contact->id, (contacts_list_h)contact->grouprelations);
2371 if (rel_changed < CONTACTS_ERROR_NONE) {
2372 /* LCOV_EXCL_START */
2373 ERR("__ctsvc_contact_insert_grouprel() Fail(%d)", rel_changed);
2374 ctsvc_end_trans(false);
2376 /* LCOV_EXCL_STOP */
2380 ret = __ctsvc_contact_insert_search_data(contact->id, need_insert_lookup);
2381 if (ret != CONTACTS_ERROR_NONE) {
2382 /* LCOV_EXCL_START */
2383 ERR("__ctsvc_contact_insert_search_data() Fail(%d)", ret);
2384 ctsvc_end_trans(false);
2386 /* LCOV_EXCL_STOP */
2389 /* person aggregation when auto_linked */
2391 ctsvc_person_aggregate(contact->person_id);
2393 #ifdef ENABLE_LOG_FEATURE
2394 /* update phonelog */
2395 if (contact->numbers) {
2397 ret = contacts_list_get_count((contacts_list_h)contact->numbers, &count);
2398 contacts_list_first((contacts_list_h)contact->numbers);
2400 ctsvc_number_s *number_record;
2402 contacts_list_get_current_record_p((contacts_list_h)contact->numbers, (contacts_record_h*)&number_record);
2403 if (number_record->number)
2404 ctsvc_db_phone_log_update_person_id(number_record->number, -1, contact->person_id, false, NULL);
2405 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->numbers));
2408 #endif /* ENABLE_LOG_FEATURE */
2410 ctsvc_set_group_rel_noti();
2411 ctsvc_set_contact_noti();
2413 ret = ctsvc_end_trans(true);
2414 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_svc_end_trans() Fail(%d)", ret);
2416 return CONTACTS_ERROR_NONE;
2419 static int __ctsvc_db_contact_replace_record(contacts_record_h record, int contact_id)
2423 int rel_changed = 0;
2426 char query[CTS_SQL_MAX_LEN] = {0};
2427 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2428 cts_stmt stmt = NULL;
2431 ret = ctsvc_begin_trans();
2432 RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
2434 snprintf(query, sizeof(query),
2435 "SELECT addressbook_id, person_id FROM "CTS_TABLE_CONTACTS" "
2436 "WHERE contact_id = %d AND deleted = 0", contact_id);
2437 ret = ctsvc_query_prepare(query, &stmt);
2439 /* LCOV_EXCL_START */
2440 ERR("ctsvc_query_prepare fail(%d)", ret);
2441 ctsvc_end_trans(false);
2443 /* LCOV_EXCL_STOP */
2445 ret = ctsvc_stmt_step(stmt);
2447 /* LCOV_EXCL_START */
2448 ERR("The contact_id(%d) is Invalid(%d)", contact_id, ret);
2449 ctsvc_stmt_finalize(stmt);
2450 ctsvc_end_trans(false);
2451 if (CONTACTS_ERROR_NONE == ret)
2452 return CONTACTS_ERROR_NO_DATA;
2455 /* LCOV_EXCL_STOP */
2458 addressbook_id = ctsvc_stmt_get_int(stmt, 0);
2459 person_id = ctsvc_stmt_get_int(stmt, 1);
2460 ctsvc_stmt_finalize(stmt);
2462 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
2463 /* LCOV_EXCL_START */
2464 ERR("No permission in this addresbook_id(%d)", addressbook_id);
2465 ctsvc_end_trans(false);
2466 return CONTACTS_ERROR_PERMISSION_DENIED;
2467 /* LCOV_EXCL_STOP */
2470 contact->id = contact_id;
2471 contact->person_id = person_id;
2472 ctsvc_contact_make_display_name(contact);
2473 __ctsvc_contact_check_default_data(contact);
2475 /* remove current child data */
2476 snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE contact_id = %d",
2478 ret = ctsvc_query_exec(query);
2479 if (CONTACTS_ERROR_NONE != ret) {
2480 /* LCOV_EXCL_START */
2481 ERR("ctsvc_query_exec() Fail(%d)", ret);
2482 ctsvc_end_trans(false);
2484 /* LCOV_EXCL_STOP */
2487 ret = __ctsvc_contact_insert_data(contact);
2488 if (CONTACTS_ERROR_NONE != ret) {
2489 /* LCOV_EXCL_START */
2490 ERR("__ctsvc_contact_insert_data() Fail(%d)", ret);
2491 ctsvc_end_trans(false);
2493 /* LCOV_EXCL_STOP */
2496 /* remove current child data */
2497 snprintf(query, sizeof(query),
2498 "DELETE FROM "CTS_TABLE_GROUP_RELATIONS" WHERE contact_id = %d", contact_id);
2499 ret = ctsvc_query_exec(query);
2500 if (CONTACTS_ERROR_NONE != ret) {
2501 /* LCOV_EXCL_START */
2502 ERR("ctsvc_query_exec() Fail(%d)", ret);
2503 ctsvc_end_trans(false);
2505 /* LCOV_EXCL_STOP */
2508 if (contact->grouprelations) {
2509 rel_changed = __ctsvc_contact_insert_grouprel(contact_id,
2510 (contacts_list_h)contact->grouprelations);
2511 if (rel_changed < CONTACTS_ERROR_NONE) {
2512 /* LCOV_EXCL_START */
2513 ERR("__ctsvc_contact_insert_grouprel() Fail(%d)", rel_changed);
2514 ctsvc_end_trans(false);
2516 /* LCOV_EXCL_STOP */
2521 if (contact->images) {
2522 int ret = CONTACTS_ERROR_NONE;
2524 ctsvc_image_s *image;
2525 char *contact_image_path = NULL;
2527 contacts_list_get_count((contacts_list_h)contact->images, &count);
2529 contacts_list_first((contacts_list_h)contact->images);
2531 ret = contacts_list_get_current_record_p((contacts_list_h)contact->images,
2532 (contacts_record_h*)&image);
2533 if (CONTACTS_ERROR_NONE != ret) {
2534 /* LCOV_EXCL_START */
2535 ERR("contacts_list_get_current_record_p() Fail(%d)", ret);
2536 ctsvc_end_trans(false);
2537 return CONTACTS_ERROR_DB;
2538 /* LCOV_EXCL_STOP */
2541 if (image->is_default)
2543 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
2545 contact_image_path = ctsvc_utils_get_image_path(contact->image_thumbnail_path);
2546 if ((NULL == contact_image_path && image->path) ||
2547 (contact_image_path && NULL == image->path) ||
2548 (contact_image_path && image->path && STRING_EQUAL != strcmp(contact_image_path, image->path))) {
2549 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
2552 contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
2554 free(contact_image_path);
2555 } else if (contact->image_thumbnail_path) {
2556 free(contact->image_thumbnail_path);
2557 contact->image_thumbnail_path = NULL;
2558 if (false == ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY)) {
2559 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
2561 if (((ctsvc_record_s*)record)->properties_flags) {
2562 int index = _contacts_contact.image_thumbnail_path & 0x000000FF;
2563 ((ctsvc_record_s*)record)->properties_flags[index] = 0;
2568 version = ctsvc_get_next_ver();
2570 len = snprintf(query, sizeof(query),
2571 "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver=%d, changed_time=%d, is_favorite=%d, "
2572 "has_phonenumber=%d, has_email=%d, display_name=?, "
2573 "reverse_display_name=?, display_name_source=%d, "
2574 "display_name_language=%d, reverse_display_name_language=%d, "
2575 "sort_name=?, reverse_sort_name=?, "
2576 "sortkey=?, reverse_sortkey=?, uid=?, ringtone_path=?, vibration=?, "
2577 "message_alert =?, image_thumbnail_path=?",
2578 version, (int)time(NULL), contact->is_favorite,
2579 contact->has_phonenumber, contact->has_email,
2580 contact->display_source_type,
2581 contact->display_name_language, contact->reverse_display_name_language);
2583 if (ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY))
2584 len += snprintf(query+len, sizeof(query)-len, ", image_changed_ver = %d", version);
2586 len += snprintf(query+len, sizeof(query)-len, " WHERE contact_id=%d", contact->id);
2588 ret = ctsvc_query_prepare(query, &stmt);
2590 /* LCOV_EXCL_START */
2591 ERR("ctsvc_query_prepare() Fail(%d)", ret);
2592 ctsvc_end_trans(false);
2594 /* LCOV_EXCL_STOP */
2597 if (contact->display_name)
2598 ctsvc_stmt_bind_text(stmt, 1, contact->display_name);
2599 if (contact->reverse_display_name)
2600 ctsvc_stmt_bind_text(stmt, 2, contact->reverse_display_name);
2601 if (contact->sort_name)
2602 ctsvc_stmt_bind_text(stmt, 3, contact->sort_name);
2603 if (contact->reverse_sort_name)
2604 ctsvc_stmt_bind_text(stmt, 4, contact->reverse_sort_name);
2605 if (contact->sortkey)
2606 ctsvc_stmt_bind_text(stmt, 5, contact->sortkey);
2607 if (contact->reverse_sortkey)
2608 ctsvc_stmt_bind_text(stmt, 6, contact->reverse_sortkey);
2610 ctsvc_stmt_bind_text(stmt, 7, contact->uid);
2611 if (contact->ringtone_path)
2612 ctsvc_stmt_bind_text(stmt, 8, contact->ringtone_path);
2613 if (contact->vibration)
2614 ctsvc_stmt_bind_text(stmt, 9, contact->vibration);
2615 if (contact->message_alert)
2616 ctsvc_stmt_bind_text(stmt, 10, contact->message_alert);
2617 if (contact->image_thumbnail_path)
2618 ctsvc_stmt_bind_text(stmt, 11, contact->image_thumbnail_path);
2620 ret = ctsvc_stmt_step(stmt);
2621 if (CONTACTS_ERROR_NONE != ret) {
2622 /* LCOV_EXCL_START */
2623 ERR("ctsvc_stmt_step() Fail(%d)", ret);
2624 ctsvc_stmt_finalize(stmt);
2625 ctsvc_end_trans(false);
2627 /* LCOV_EXCL_STOP */
2629 ctsvc_stmt_finalize(stmt);
2631 ctsvc_set_contact_noti();
2632 if (0 < rel_changed)
2633 ctsvc_set_group_rel_noti();
2635 __ctsvc_contact_update_search_data(contact->id, true);
2636 ctsvc_db_update_person((contacts_record_h)contact);
2638 ret = ctsvc_end_trans(true);
2640 if (ret < CONTACTS_ERROR_NONE)
2643 return CONTACTS_ERROR_NONE;
2646 ctsvc_db_plugin_info_s ctsvc_db_plugin_contact = {
2647 .is_query_only = false,
2648 .insert_record = __ctsvc_db_contact_insert_record,
2649 .get_record = __ctsvc_db_contact_get_record,
2650 .update_record = __ctsvc_db_contact_update_record,
2651 .delete_record = __ctsvc_db_contact_delete_record,
2652 .get_all_records = __ctsvc_db_contact_get_all_records,
2653 .get_records_with_query = __ctsvc_db_contact_get_records_with_query,
2654 .insert_records = NULL,
2655 .update_records = NULL,
2656 .delete_records = NULL,
2658 .get_count_with_query = NULL,
2659 .replace_record = __ctsvc_db_contact_replace_record,
2660 .replace_records = NULL,