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);
1381 ret = __ctsvc_db_get_data(contact->id, temp_contact);
1382 WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_db_get_data() Fail(%d)", ret);
1384 ctsvc_contact_make_display_name(temp_contact);
1386 FREEandSTRDUP(contact->display_name, temp_contact->display_name);
1387 FREEandSTRDUP(contact->reverse_display_name, temp_contact->reverse_display_name);
1388 FREEandSTRDUP(contact->sort_name, temp_contact->sort_name);
1389 FREEandSTRDUP(contact->reverse_sort_name, temp_contact->reverse_sort_name);
1390 FREEandSTRDUP(contact->sortkey, temp_contact->sortkey);
1391 FREEandSTRDUP(contact->reverse_sortkey, temp_contact->reverse_sortkey);
1393 contact->display_name_language = temp_contact->display_name_language;
1394 contact->reverse_display_name_language = temp_contact->reverse_display_name_language;
1395 contact->display_source_type = temp_contact->display_source_type;
1397 if (ctsvc_record_check_property_flag((ctsvc_record_s*)temp_contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY))
1398 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
1400 contacts_record_destroy((contacts_record_h)temp_contact, true);
1402 ctsvc_contact_make_display_name(contact);
1406 char query[CTS_SQL_MAX_LEN] = {0};
1407 char query_set[CTS_SQL_MIN_LEN] = {0, };
1408 cts_stmt stmt = NULL;
1410 version = ctsvc_get_next_ver();
1412 ret = ctsvc_db_create_set_query(record, &set, &bind_text);
1413 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_db_create_set_query() Fail(%d)", ret);
1416 len = snprintf(query_set, sizeof(query_set), "%s, ", set);
1417 len += snprintf(query_set+len, sizeof(query_set)-len, " changed_ver=%d, changed_time=%d, has_phonenumber=%d, has_email=%d",
1418 version, (int)time(NULL), contact->has_phonenumber, contact->has_email);
1419 if (ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY)) {
1420 len += snprintf(query_set+len, sizeof(query_set)-len,
1421 ", display_name=?, reverse_display_name=?, display_name_source=%d, "
1422 "display_name_language=%d, reverse_display_name_language=%d, "
1423 "sort_name=?, reverse_sort_name=?, sortkey=?, reverse_sortkey=?",
1424 contact->display_source_type, contact->display_name_language, contact->reverse_display_name_language);
1425 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->display_name)));
1426 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_display_name)));
1427 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->sort_name)));
1428 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_sort_name)));
1429 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->sortkey)));
1430 bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_sortkey)));
1433 if (ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY))
1434 len += snprintf(query_set+len, sizeof(query_set)-len, ", image_changed_ver=%d", version);
1436 snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE contact_id = %d", CTS_TABLE_CONTACTS, query_set, contact->id);
1438 ret = ctsvc_query_prepare(query, &stmt);
1440 /* LCOV_EXCL_START */
1441 ERR("ctsvc_query_prepare() Fail(%d)", ret);
1443 /* LCOV_EXCL_STOP */
1448 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++) {
1449 const char *text = cursor->data;
1451 ctsvc_stmt_bind_text(stmt, i, text);
1454 ret = ctsvc_stmt_step(stmt);
1455 if (CONTACTS_ERROR_NONE != ret) {
1456 /* LCOV_EXCL_START */
1457 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1458 ctsvc_stmt_finalize(stmt);
1460 /* LCOV_EXCL_STOP */
1462 ctsvc_stmt_finalize(stmt);
1465 if (CONTACTS_ERROR_NONE != ret) {
1466 ctsvc_end_trans(false);
1467 CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s*)record);
1471 for (cursor = bind_text; cursor; cursor = cursor->next) {
1473 cursor->data = NULL;
1475 g_slist_free(bind_text);
1480 ctsvc_set_contact_noti();
1481 if (0 < rel_changed)
1482 ctsvc_set_group_rel_noti();
1484 __ctsvc_contact_update_search_data(contact->id, need_update_lookup);
1485 ctsvc_db_update_person((contacts_record_h)contact);
1487 CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s*)record);
1491 for (cursor = bind_text; cursor; cursor = cursor->next) {
1493 cursor->data = NULL;
1495 g_slist_free(bind_text);
1498 ret = ctsvc_end_trans(true);
1499 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
1501 return CONTACTS_ERROR_NONE;
1504 static int __ctsvc_db_contact_get_all_records(int offset, int limit, contacts_list_h *out_list)
1510 char query[CTS_SQL_MAX_LEN] = {0};
1511 contacts_list_h list;
1513 len = snprintf(query, sizeof(query),
1514 "SELECT contact_id FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0");
1517 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
1519 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
1522 ret = ctsvc_query_prepare(query, &stmt);
1523 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
1525 contacts_list_create(&list);
1526 while ((ret = ctsvc_stmt_step(stmt))) {
1527 contacts_record_h record;
1529 /* LCOV_EXCL_START */
1530 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1531 ctsvc_stmt_finalize(stmt);
1532 contacts_list_destroy(list, true);
1534 /* LCOV_EXCL_STOP */
1536 contact_id = ctsvc_stmt_get_int(stmt, 0);
1537 ret = ctsvc_db_contact_get(contact_id, &record);
1538 if (CONTACTS_ERROR_NONE != ret) {
1539 /* LCOV_EXCL_START */
1540 ERR("ctsvc_db_contact_get() Fail(%d)", ret);
1541 ctsvc_stmt_finalize(stmt);
1542 contacts_list_destroy(list, true);
1544 /* LCOV_EXCL_STOP */
1546 ctsvc_list_prepend(list, record);
1548 ctsvc_stmt_finalize(stmt);
1549 ctsvc_list_reverse(list);
1551 *out_list = (contacts_list_h)list;
1552 return CONTACTS_ERROR_NONE;
1555 static int __ctsvc_db_contact_get_changed_ver(int contact_id, ctsvc_contact_s *contact)
1559 char query[CTS_SQL_MAX_LEN] = {0};
1561 snprintf(query, sizeof(query),
1562 "SELECT changed_ver FROM "CTS_TABLE_CONTACTS
1563 " WHERE contact_id = %d AND deleted = 0", contact_id);
1564 ret = ctsvc_query_get_first_int_result(query, &version);
1565 if (CONTACTS_ERROR_NONE == ret)
1566 contact->changed_ver = version;
1570 static int __ctsvc_db_contact_get_records_with_query(contacts_query_h query, int offset, int limit, contacts_list_h *out_list)
1575 ctsvc_query_s *s_query;
1577 contacts_list_h list;
1578 ctsvc_contact_s *contact;
1579 char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
1580 bool had_contact_id = false;
1583 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
1584 s_query = (ctsvc_query_s*)query;
1586 if (s_query->projection) {
1587 for (i = 0; i < s_query->projection_count; i++) {
1588 if (s_query->projection[i] == CTSVC_PROPERTY_CONTACT_ID) {
1589 had_contact_id = true;
1594 s_query->projection_count = 0;
1595 had_contact_id = true;
1598 if (false == had_contact_id) {
1599 int *tmp = (int *)realloc(s_query->projection, sizeof(unsigned int)*(s_query->projection_count+1));
1601 /* LCOV_EXCL_START */
1602 ERR("realloc() Fail");
1603 return CONTACTS_ERROR_OUT_OF_MEMORY;
1604 /* LCOV_EXCL_STOP */
1606 s_query->projection = tmp;
1609 s_query->projection[s_query->projection_count] = CTSVC_PROPERTY_CONTACT_ID;
1610 s_query->projection_count++;
1613 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
1614 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
1616 contacts_list_create(&list);
1617 while ((ret = ctsvc_stmt_step(stmt))) {
1618 contacts_record_h record;
1620 /* LCOV_EXCL_START */
1621 ERR("ctsvc_stmt_step() Fail(%d)", ret);
1622 ctsvc_stmt_finalize(stmt);
1623 contacts_list_destroy(list, true);
1625 /* LCOV_EXCL_STOP */
1628 contacts_record_create(_contacts_contact._uri, &record);
1629 contact = (ctsvc_contact_s*)record;
1630 if (0 == s_query->projection_count) {
1631 field_count = s_query->property_count;
1633 field_count = s_query->projection_count;
1634 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
1635 s_query->projection_count, s_query->property_count);
1637 if (CONTACTS_ERROR_NONE != ret)
1638 ASSERT_NOT_REACHED("To set projection is failed.\n");
1641 for (i = 0; i < field_count; i++) {
1644 if (0 == s_query->projection_count)
1645 property_id = s_query->properties[i].property_id;
1647 property_id = s_query->projection[i];
1649 switch (property_id) {
1650 case CTSVC_PROPERTY_CONTACT_ID:
1651 contact_id = ctsvc_stmt_get_int(stmt, i);
1653 contact->id = contact_id;
1655 case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
1656 temp = ctsvc_stmt_get_text(stmt, i);
1657 free(contact->display_name);
1658 contact->display_name = SAFE_STRDUP(temp);
1660 case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
1661 contact->display_source_type = ctsvc_stmt_get_int(stmt, i);
1663 case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
1664 contact->addressbook_id = ctsvc_stmt_get_int(stmt, i);
1666 case CTSVC_PROPERTY_CONTACT_RINGTONE:
1667 temp = ctsvc_stmt_get_text(stmt, i);
1668 free(contact->ringtone_path);
1669 contact->ringtone_path = SAFE_STRDUP(temp);
1671 case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
1672 temp = ctsvc_stmt_get_text(stmt, i);
1673 if (temp && *temp) {
1674 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
1675 free(contact->image_thumbnail_path);
1676 contact->image_thumbnail_path = strdup(full_path);
1679 case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
1680 contact->is_favorite = ctsvc_stmt_get_int(stmt, i);
1682 case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
1683 contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
1685 case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
1686 contact->has_email = ctsvc_stmt_get_int(stmt, i);
1688 case CTSVC_PROPERTY_CONTACT_PERSON_ID:
1689 contact->person_id = ctsvc_stmt_get_int(stmt, i);
1691 case CTSVC_PROPERTY_CONTACT_UID:
1692 temp = ctsvc_stmt_get_text(stmt, i);
1694 contact->uid = SAFE_STRDUP(temp);
1696 case CTSVC_PROPERTY_CONTACT_VIBRATION:
1697 temp = ctsvc_stmt_get_text(stmt, i);
1698 free(contact->vibration);
1699 contact->vibration = SAFE_STRDUP(temp);
1701 case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
1702 temp = ctsvc_stmt_get_text(stmt, i);
1703 free(contact->message_alert);
1704 contact->message_alert = SAFE_STRDUP(temp);
1706 case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
1707 contact->changed_time = ctsvc_stmt_get_int(stmt, i);
1709 case CTSVC_PROPERTY_CONTACT_LINK_MODE:
1710 contact->link_mode = ctsvc_stmt_get_int(stmt, i);
1716 /* get changed_ver */
1717 ret = __ctsvc_db_contact_get_changed_ver(contact_id, contact);
1718 if (CONTACTS_ERROR_NONE != ret) {
1719 /* LCOV_EXCL_START */
1720 ERR("__ctsvc_db_contact_get_changed_ver Fail(%d)", ret);
1721 ctsvc_stmt_finalize(stmt);
1722 contacts_list_destroy(list, true);
1724 /* LCOV_EXCL_STOP */
1727 ret = __ctsvc_db_get_data(contact_id, contact);
1728 if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
1729 /* LCOV_EXCL_START */
1730 ERR("ctsvc_get_data_info Fail(%d)", ret);
1731 ctsvc_stmt_finalize(stmt);
1732 contacts_list_destroy(list, true);
1734 /* LCOV_EXCL_STOP */
1737 ret = __ctsvc_get_contact_grouprel(contact_id, contact);
1738 if (CONTACTS_ERROR_NONE != ret) {
1739 /* LCOV_EXCL_START */
1740 ERR("ctsvc_get_group_relations Fail(%d)", ret);
1741 ctsvc_stmt_finalize(stmt);
1742 contacts_list_destroy(list, true);
1744 /* LCOV_EXCL_STOP */
1747 ctsvc_list_prepend(list, record);
1749 ctsvc_stmt_finalize(stmt);
1750 ctsvc_list_reverse(list);
1752 *out_list = (contacts_list_h)list;
1754 return CONTACTS_ERROR_NONE;
1758 static int __ctsvc_contact_insert_data(ctsvc_contact_s *contact)
1762 /* Insert the name */
1763 if (contact->name) {
1764 ret = ctsvc_contact_insert_data_name((contacts_list_h)contact->name, contact->id, false);
1765 if (CONTACTS_ERROR_NONE != ret) {
1766 /* LCOV_EXCL_START */
1767 ERR("ctsvc_contact_insert_data_name() Fail(%d)", ret);
1769 /* LCOV_EXCL_STOP */
1773 /* Insert the company */
1774 if (contact->company) {
1775 ret = ctsvc_contact_insert_data_company((contacts_list_h)contact->company, contact->id, false);
1776 if (CONTACTS_ERROR_NONE != ret) {
1777 /* LCOV_EXCL_START */
1778 ERR("ctsvc_insert_contact_data_company() Fail(%d)", ret);
1780 /* LCOV_EXCL_STOP */
1784 /* Insert the events */
1785 if (contact->events) {
1786 ret = ctsvc_contact_insert_data_event((contacts_list_h)contact->events, contact->id, false);
1787 if (CONTACTS_ERROR_NONE != ret) {
1788 /* LCOV_EXCL_START */
1789 ERR("ctsvc_insert_contact_data_event() Fail(%d)", ret);
1791 /* LCOV_EXCL_STOP */
1795 /* Insert the messengers */
1796 if (contact->messengers) {
1797 ret = ctsvc_contact_insert_data_messenger((contacts_list_h)contact->messengers, contact->id, false);
1798 if (CONTACTS_ERROR_NONE != ret) {
1799 /* LCOV_EXCL_START */
1800 ERR("ctsvc_insert_contact_data_messenger() Fail(%d)", ret);
1802 /* LCOV_EXCL_STOP */
1806 /* Insert the postals */
1807 if (contact->postal_addrs) {
1808 ret = ctsvc_contact_insert_data_address((contacts_list_h)contact->postal_addrs, contact->id, false);
1809 if (CONTACTS_ERROR_NONE != ret) {
1810 /* LCOV_EXCL_START */
1811 ERR("ctsvc_insert_contact_data_postal() Fail(%d)", ret);
1813 /* LCOV_EXCL_STOP */
1817 /* Insert the Web addrs */
1818 if (contact->urls) {
1819 ret = ctsvc_contact_insert_data_url((contacts_list_h)contact->urls, contact->id, false);
1820 if (CONTACTS_ERROR_NONE != ret) {
1821 /* LCOV_EXCL_START */
1822 ERR("ctsvc_insert_contact_data_web() Fail(%d)", ret);
1824 /* LCOV_EXCL_STOP */
1828 /* Insert the Nick names */
1829 if (contact->nicknames) {
1830 ret = ctsvc_contact_insert_data_nickname((contacts_list_h)contact->nicknames, contact->id, false);
1831 if (CONTACTS_ERROR_NONE != ret) {
1832 /* LCOV_EXCL_START */
1833 ERR("ctsvc_insert_contact_data_nickname() Fail(%d)", ret);
1835 /* LCOV_EXCL_STOP */
1839 /* Insert the numbers */
1840 if (contact->numbers) {
1841 ret = ctsvc_contact_insert_data_number((contacts_list_h)contact->numbers, contact->id, false);
1842 if (ret < CONTACTS_ERROR_NONE) {
1843 /* LCOV_EXCL_START */
1844 ERR("ctsvc_contact_insert_data_number() Fail(%d)", ret);
1846 /* LCOV_EXCL_STOP */
1850 /* Insert the emails */
1851 if (contact->emails) {
1852 ret = ctsvc_contact_insert_data_email((contacts_list_h)contact->emails, contact->id, false);
1853 if (ret < CONTACTS_ERROR_NONE) {
1854 /* LCOV_EXCL_START */
1855 ERR("ctsvc_insert_contact_data_email() Fail(%d)", ret);
1857 /* LCOV_EXCL_STOP */
1861 /* Insert the profile values */
1862 if (contact->profiles) {
1863 ret = ctsvc_contact_insert_data_profile((contacts_list_h)contact->profiles, contact->id, false);
1864 if (CONTACTS_ERROR_NONE != ret) {
1865 /* LCOV_EXCL_START */
1866 ERR("ctsvc_insert_contact_data_profile() Fail(%d)", ret);
1868 /* LCOV_EXCL_STOP */
1872 /* Insert the relationship values */
1873 if (contact->relationships) {
1874 ret = ctsvc_contact_insert_data_relationship((contacts_list_h)contact->relationships, contact->id, false);
1875 if (CONTACTS_ERROR_NONE != ret) {
1876 /* LCOV_EXCL_START */
1877 ERR("ctsvc_contact_insert_data_relationship() Fail(%d)", ret);
1879 /* LCOV_EXCL_STOP */
1883 /* Insert the image values */
1884 if (contact->images) {
1885 ret = ctsvc_contact_insert_data_image((contacts_list_h)contact->images, contact->id, false);
1886 if (CONTACTS_ERROR_NONE != ret) {
1887 /* LCOV_EXCL_START */
1888 ERR("ctsvc_contact_insert_data_image() Fail(%d)", ret);
1890 /* LCOV_EXCL_STOP */
1894 /* Insert the note values */
1895 if (contact->note) {
1896 ret = ctsvc_contact_insert_data_note((contacts_list_h)contact->note, contact->id, false);
1897 if (CONTACTS_ERROR_NONE != ret) {
1898 /* LCOV_EXCL_START */
1899 ERR("ctsvc_contact_insert_data_note() Fail(%d)", ret);
1901 /* LCOV_EXCL_STOP */
1905 /* Insert the extensions values */
1906 if (contact->extensions) {
1907 ret = ctsvc_contact_insert_data_extension((contacts_list_h)contact->extensions, contact->id, false);
1908 if (CONTACTS_ERROR_NONE != ret) {
1909 /* LCOV_EXCL_START */
1910 ERR("ctsvc_contact_insert_data_extension() Fail(%d)", ret);
1912 /* LCOV_EXCL_STOP */
1916 /* Insert the sips */
1917 if (contact->sips) {
1918 ret = ctsvc_contact_insert_data_sip((contacts_list_h)contact->sips, contact->id, false);
1919 if (CONTACTS_ERROR_NONE != ret) {
1920 /* LCOV_EXCL_START */
1921 ERR("ctsvc_insert_contact_data_sip() Fail(%d)", ret);
1923 /* LCOV_EXCL_STOP */
1927 return CONTACTS_ERROR_NONE;
1930 static inline int __ctsvc_contact_insert_search_data(int contact_id, bool need_insert_lookup_data)
1933 cts_stmt stmt = NULL;
1934 char query[CTS_SQL_MAX_LEN] = {0};
1935 char *search_name = NULL;
1936 char *search_number = NULL;
1937 char *search_data = NULL;
1938 ctsvc_contact_s *contact = NULL;
1940 ret = ctsvc_begin_trans();
1941 RETVM_IF(ret, ret, "contacts_begin_trans() Fail(%d)", ret);
1943 ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&contact);
1944 if (CONTACTS_ERROR_NONE != ret) {
1945 /* LCOV_EXCL_START */
1946 ERR("ctsvc_db_contact_get() Fail(%d)", ret);
1947 ctsvc_end_trans(false);
1949 /* LCOV_EXCL_STOP */
1952 ret = ctsvc_contact_make_search_name(contact, &search_name);
1953 if (CONTACTS_ERROR_NONE != ret) {
1954 /* LCOV_EXCL_START */
1955 ERR("ctsvc_contact_make_search_name() Fail(%d)", ret);
1956 contacts_record_destroy((contacts_record_h)contact, true);
1957 ctsvc_end_trans(false);
1959 /* LCOV_EXCL_STOP */
1962 ret = __ctsvc_contact_make_search_data(contact, &search_number, &search_data);
1963 if (CONTACTS_ERROR_NONE != ret) {
1964 /* LCOV_EXCL_START */
1965 ERR("__ctsvc_contact_make_search_data() Fail(%d)", ret);
1966 contacts_record_destroy((contacts_record_h)contact, true);
1967 ctsvc_end_trans(false);
1970 /* LCOV_EXCL_STOP */
1973 snprintf(query, sizeof(query),
1974 "INSERT INTO %s(contact_id, name, number, data) "
1975 "VALUES(%d, ?, ?, ?)",
1976 CTS_TABLE_SEARCH_INDEX, contact_id);
1978 ret = ctsvc_query_prepare(query, &stmt);
1980 /* LCOV_EXCL_START */
1981 ERR("ctsvc_query_prepare() Fail(%d)", ret);
1982 contacts_record_destroy((contacts_record_h)contact, true);
1983 ctsvc_end_trans(false);
1985 free(search_number);
1988 /* LCOV_EXCL_STOP */
1992 ctsvc_stmt_bind_text(stmt, 1, search_name);
1994 ctsvc_stmt_bind_text(stmt, 2, search_number);
1996 ctsvc_stmt_bind_text(stmt, 3, search_data);
1998 ret = ctsvc_stmt_step(stmt);
2001 free(search_number);
2004 if (CONTACTS_ERROR_NONE != ret) {
2005 /* LCOV_EXCL_START */
2006 ERR("ctsvc_stmt_step() Fail(%d)", ret);
2007 contacts_record_destroy((contacts_record_h)contact, true);
2008 ctsvc_stmt_finalize(stmt);
2009 ctsvc_end_trans(false);
2011 /* LCOV_EXCL_STOP */
2013 ctsvc_stmt_finalize(stmt);
2015 /* update phone_lookup, name_lookup */
2016 if (need_insert_lookup_data) {
2017 ret = __ctsvc_contact_refresh_lookup_data(contact_id, contact);
2018 if (CONTACTS_ERROR_NONE != ret) {
2019 /* LCOV_EXCL_START */
2020 ERR("__ctsvc_contact_refresh_lookup_data() Fail(%d)", ret);
2021 contacts_record_destroy((contacts_record_h)contact, true);
2022 ctsvc_end_trans(false);
2024 /* LCOV_EXCL_STOP */
2028 contacts_record_destroy((contacts_record_h)contact, true);
2030 ret = ctsvc_end_trans(true);
2031 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
2033 return CONTACTS_ERROR_NONE;
2036 static inline int __ctsvc_contact_insert_grouprel(int contact_id, contacts_list_h group_list)
2039 ctsvc_group_relation_s *grouprel;
2040 int rel_changed = 0;
2044 RETV_IF(NULL == group_list, CONTACTS_ERROR_INVALID_PARAMETER);
2045 ret = contacts_list_get_count(group_list, &count);
2047 return CONTACTS_ERROR_NONE;
2049 contacts_list_first(group_list);
2051 contacts_list_get_current_record_p(group_list, (contacts_record_h*)&grouprel);
2052 if (NULL == grouprel)
2055 RETVM_IF(grouprel->group_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "group_id(%d) invalid", grouprel->group_id);
2056 if (grouprel->group_id) {
2057 ret = ctsvc_group_add_contact_in_transaction(grouprel->group_id, contact_id);
2058 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_db_group_set_relation() Fail(%d)", ret);
2062 } while (CONTACTS_ERROR_NONE == contacts_list_next(group_list));
2067 return CONTACTS_ERROR_NONE;
2070 static inline int __ctsvc_find_person_to_link_with_number(const char *number,
2071 int addressbook_id, int *person_id)
2074 cts_stmt stmt = NULL;
2075 char query[CTS_SQL_MIN_LEN] = {0};
2076 int number_len = SAFE_STRLEN(number);
2077 char clean_num[number_len+1];
2079 ret = ctsvc_clean_number(number, clean_num, sizeof(clean_num), true);
2081 char normal_num[sizeof(clean_num)+20];
2082 ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
2083 char minmatch[sizeof(normal_num)+1];
2085 ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
2086 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_get_minmatch_number() Fail(%d)", ret);
2089 snprintf(query, sizeof(query),
2090 "SELECT C.person_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
2091 "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 "
2092 "AND C.addressbook_id <> %d AND D.is_my_profile = 0 "
2093 "WHERE D.data4 = ?",
2094 /* Below condition takes long time, so omit the condition */
2095 /* AND _NUMBER_COMPARE_(D.data5, ?, NULL, NULL) */
2096 CONTACTS_DATA_TYPE_NUMBER, addressbook_id);
2098 ret = ctsvc_query_prepare(query, &stmt);
2099 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
2100 ctsvc_stmt_bind_text(stmt, 1, minmatch);
2101 /* ctsvc_stmt_bind_text(stmt, 2, normal_num); */
2102 ret = ctsvc_stmt_step(stmt);
2104 *person_id = ctsvc_stmt_get_int(stmt, 0);
2105 ret = CONTACTS_ERROR_NONE;
2106 } else if (CONTACTS_ERROR_NONE == ret) {
2107 ret = CONTACTS_ERROR_NO_DATA;
2109 ctsvc_stmt_finalize(stmt);
2110 DBG("result ret(%d) person_id(%d)", ret, *person_id);
2114 return CONTACTS_ERROR_INVALID_PARAMETER;
2117 static inline int __ctsvc_find_person_to_link_with_email(const char *email_addr, int addressbook_id, int *person_id)
2120 cts_stmt stmt = NULL;
2121 char query[CTS_SQL_MIN_LEN] = {0};
2123 snprintf(query, sizeof(query),
2124 "SELECT C.person_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
2125 "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 AND D.is_my_profile = 0 "
2126 "AND C.addressbook_id <> %d "
2127 "WHERE D.data3 = ?",
2128 CONTACTS_DATA_TYPE_EMAIL, addressbook_id);
2130 ret = ctsvc_query_prepare(query, &stmt);
2131 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
2133 ctsvc_stmt_bind_text(stmt, 1, email_addr);
2134 ret = ctsvc_stmt_step(stmt);
2136 *person_id = ctsvc_stmt_get_int(stmt, 0);
2137 ret = CONTACTS_ERROR_NONE;
2138 } else if (CONTACTS_ERROR_NONE == ret) {
2139 ret = CONTACTS_ERROR_NO_DATA;
2142 ctsvc_stmt_finalize(stmt);
2143 DBG("result ret(%d) person_id(%d)", ret, *person_id);
2148 static inline int __ctsvc_find_person_to_link(contacts_record_h record, int addressbook_id, int *person_id)
2151 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2152 ctsvc_number_s *number_data;
2153 ctsvc_email_s *email_data;
2156 for (cursor = contact->numbers->records; cursor; cursor = cursor->next) {
2157 number_data = cursor->data;
2158 if (number_data && number_data->number && number_data->number[0]) {
2159 ret = __ctsvc_find_person_to_link_with_number(number_data->number, addressbook_id, person_id);
2161 if (ret == CONTACTS_ERROR_NONE && 0 < *person_id)
2166 for (cursor = contact->emails->records; cursor; cursor = cursor->next) {
2167 email_data = cursor->data;
2168 if (email_data && email_data->email_addr && email_data->email_addr[0]) {
2169 ret = __ctsvc_find_person_to_link_with_email(email_data->email_addr, addressbook_id, person_id);
2171 if (ret == CONTACTS_ERROR_NONE && 0 < *person_id)
2176 return CONTACTS_ERROR_NO_DATA;
2179 static int __ctsvc_db_contact_insert_record(contacts_record_h record, int *id)
2182 int ret, person_id = 0;
2183 char query[CTS_SQL_MAX_LEN] = {0};
2184 bool auto_link_enabled = true;
2185 bool auto_linked = false;
2187 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2188 int rel_changed = 0;
2189 cts_stmt stmt = NULL;
2191 /* These check should be done in client side */
2192 RETV_IF(NULL == contact, CONTACTS_ERROR_INVALID_PARAMETER);
2193 RETVM_IF(contact->addressbook_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,
2194 "addressbook_id(%d) is mandatory field to insert contact record ", contact->addressbook_id);
2195 RETVM_IF(0 < contact->id, CONTACTS_ERROR_INVALID_PARAMETER,
2196 "id(%d), This record is already inserted", contact->id);
2198 if (contact->link_mode == CONTACTS_CONTACT_LINK_MODE_IGNORE_ONCE)
2199 auto_link_enabled = false;
2201 ret = ctsvc_begin_trans();
2202 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Fail(%d)", ret);
2204 if (false == ctsvc_have_ab_write_permission(contact->addressbook_id, false)) {
2205 /* LCOV_EXCL_START */
2206 ERR("No permission in this addresbook_id(%d)", contact->addressbook_id);
2207 ctsvc_end_trans(false);
2208 return CONTACTS_ERROR_PERMISSION_DENIED;
2209 /* LCOV_EXCL_STOP */
2212 ret = ctsvc_db_get_next_id(CTS_TABLE_CONTACTS);
2213 if (ret < CONTACTS_ERROR_NONE) {
2214 /* LCOV_EXCL_START */
2215 ERR("ctsvc_db_get_next_id() Fail(%d)", ret);
2216 ctsvc_end_trans(false);
2218 /* LCOV_EXCL_STOP */
2224 ctsvc_contact_make_display_name(contact);
2225 __ctsvc_contact_check_default_data(contact);
2227 /* check lookup data is dirty */
2228 bool need_insert_lookup = __ctsvc_get_need_refresh_lookup_data(contact);
2231 ret = __ctsvc_contact_insert_data(contact);
2232 if (CONTACTS_ERROR_NONE != ret) {
2233 /* LCOV_EXCL_START */
2234 ERR("cts_insert_contact_data() Fail(%d)", ret);
2235 ctsvc_end_trans(false);
2237 /* LCOV_EXCL_STOP */
2241 free(contact->image_thumbnail_path);
2242 contact->image_thumbnail_path = NULL;
2243 if (contact->images) {
2245 ctsvc_image_s *image;
2247 contacts_list_get_count((contacts_list_h)contact->images, &count);
2249 contacts_list_first((contacts_list_h)contact->images);
2251 ret = contacts_list_get_current_record_p((contacts_list_h)contact->images, (contacts_record_h*)&image);
2252 if (CONTACTS_ERROR_NONE != ret) {
2253 /* LCOV_EXCL_START */
2254 ERR("contacts_list_get_current_record_p() Fail(%d)", ret);
2255 ctsvc_end_trans(false);
2256 return CONTACTS_ERROR_DB;
2257 /* LCOV_EXCL_STOP */
2260 if (image->path && image->is_default) {
2261 contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
2264 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
2268 version = ctsvc_get_next_ver();
2270 if (contact->person_id) {
2273 snprintf(query, sizeof(query),
2274 "SELECT contact_id FROM "CTSVC_DB_VIEW_CONTACT" "
2275 "WHERE person_id = %d", contact->person_id);
2276 ret = ctsvc_query_get_first_int_result(query, &id);
2277 if (CONTACTS_ERROR_NONE != ret) {
2278 /* LCOV_EXCL_START */
2279 ERR("Invalid person_id(%d)", contact->person_id);
2280 ctsvc_end_trans(false);
2281 return CONTACTS_ERROR_INVALID_PARAMETER;
2282 /* LCOV_EXCL_STOP */
2286 } else if (auto_link_enabled) {
2287 ret = __ctsvc_find_person_to_link((contacts_record_h)contact, contact->addressbook_id, &person_id);
2288 DBG("__ctsvc_find_person_to_link return %d, person_id(%d)", ret, person_id);
2289 if (ret == CONTACTS_ERROR_NONE && 0 < person_id) {
2290 contact->person_id = person_id;
2293 ret = ctsvc_db_insert_person((contacts_record_h)contact);
2294 DBG("ctsvc_db_insert_person return %d, person_id(%d)", ret, ret);
2295 if (ret < CONTACTS_ERROR_NONE) {
2296 /* LCOV_EXCL_START */
2297 ERR("ctsvc_db_insert_person() Fail(%d)", ret);
2298 ctsvc_end_trans(false);
2300 /* LCOV_EXCL_STOP */
2302 contact->person_id = ret;
2305 ret = ctsvc_db_insert_person((contacts_record_h)contact);
2306 DBG("ctsvc_db_insert_person return %d, person_id(%d)", ret, ret);
2307 if (ret < CONTACTS_ERROR_NONE) {
2308 /* LCOV_EXCL_START */
2309 ERR("ctsvc_db_insert_person() Fail(%d)", ret);
2310 ctsvc_end_trans(false);
2312 /* LCOV_EXCL_STOP */
2314 contact->person_id = ret;
2317 snprintf(query, sizeof(query),
2318 "INSERT INTO "CTS_TABLE_CONTACTS"(contact_id, person_id, addressbook_id, is_favorite, "
2319 "created_ver, changed_ver, changed_time, link_mode, "
2320 "image_changed_ver, has_phonenumber, has_email, "
2321 "display_name, reverse_display_name, display_name_source, "
2322 "display_name_language, reverse_display_name_language, "
2323 "sort_name, reverse_sort_name, "
2324 "sortkey, reverse_sortkey, "
2325 "uid, ringtone_path, vibration, message_alert, image_thumbnail_path) "
2326 "VALUES(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, ?, ?, %d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
2327 contact->id, contact->person_id, contact->addressbook_id, contact->is_favorite,
2328 version, version, (int)time(NULL), contact->link_mode,
2329 (contact->image_thumbnail_path) ? version : 0, contact->has_phonenumber, contact->has_email,
2330 contact->display_source_type, contact->display_name_language, contact->reverse_display_name_language);
2332 ret = ctsvc_query_prepare(query, &stmt);
2334 /* LCOV_EXCL_START */
2335 ERR("ctsvc_query_prepare() Fail(%d)", ret);
2336 ctsvc_end_trans(false);
2338 /* LCOV_EXCL_STOP */
2341 if (contact->display_name)
2342 ctsvc_stmt_bind_text(stmt, 1, contact->display_name);
2343 if (contact->reverse_display_name)
2344 ctsvc_stmt_bind_text(stmt, 2, contact->reverse_display_name);
2345 if (contact->sort_name)
2346 ctsvc_stmt_bind_text(stmt, 3, contact->sort_name);
2347 if (contact->reverse_sort_name)
2348 ctsvc_stmt_bind_text(stmt, 4, contact->reverse_sort_name);
2349 if (contact->sortkey)
2350 ctsvc_stmt_bind_text(stmt, 5, contact->sortkey);
2351 if (contact->reverse_sortkey)
2352 ctsvc_stmt_bind_text(stmt, 6, contact->reverse_sortkey);
2354 ctsvc_stmt_bind_text(stmt, 7, contact->uid);
2355 if (contact->ringtone_path)
2356 ctsvc_stmt_bind_text(stmt, 8, contact->ringtone_path);
2357 if (contact->vibration)
2358 ctsvc_stmt_bind_text(stmt, 9, contact->vibration);
2359 if (contact->message_alert)
2360 ctsvc_stmt_bind_text(stmt, 10, contact->message_alert);
2361 if (contact->image_thumbnail_path)
2362 ctsvc_stmt_bind_text(stmt, 11, contact->image_thumbnail_path);
2364 ret = ctsvc_stmt_step(stmt);
2365 if (CONTACTS_ERROR_NONE != ret) {
2366 /* LCOV_EXCL_START */
2367 ERR("ctsvc_stmt_step() Fail(%d)", ret);
2368 ctsvc_stmt_finalize(stmt);
2369 ctsvc_end_trans(false);
2371 /* LCOV_EXCL_STOP */
2373 ctsvc_stmt_finalize(stmt);
2375 /* Insert group Info */
2376 if (contact->grouprelations) {
2377 rel_changed = __ctsvc_contact_insert_grouprel(contact->id, (contacts_list_h)contact->grouprelations);
2378 if (rel_changed < CONTACTS_ERROR_NONE) {
2379 /* LCOV_EXCL_START */
2380 ERR("__ctsvc_contact_insert_grouprel() Fail(%d)", rel_changed);
2381 ctsvc_end_trans(false);
2383 /* LCOV_EXCL_STOP */
2387 ret = __ctsvc_contact_insert_search_data(contact->id, need_insert_lookup);
2388 if (ret != CONTACTS_ERROR_NONE) {
2389 /* LCOV_EXCL_START */
2390 ERR("__ctsvc_contact_insert_search_data() Fail(%d)", ret);
2391 ctsvc_end_trans(false);
2393 /* LCOV_EXCL_STOP */
2396 /* person aggregation when auto_linked */
2398 ctsvc_person_aggregate(contact->person_id);
2400 #ifdef ENABLE_LOG_FEATURE
2401 /* update phonelog */
2402 if (contact->numbers) {
2404 ret = contacts_list_get_count((contacts_list_h)contact->numbers, &count);
2405 if (ret != CONTACTS_ERROR_NONE) {
2406 ERR("__contacts_list_get_count() Fail(%d)", ret);
2407 ctsvc_end_trans(false);
2410 contacts_list_first((contacts_list_h)contact->numbers);
2412 ctsvc_number_s *number_record;
2414 contacts_list_get_current_record_p((contacts_list_h)contact->numbers, (contacts_record_h*)&number_record);
2415 if (number_record->number)
2416 ctsvc_db_phone_log_update_person_id(number_record->number, -1, contact->person_id, false, NULL);
2417 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->numbers));
2420 #endif /* ENABLE_LOG_FEATURE */
2422 ctsvc_set_group_rel_noti();
2423 ctsvc_set_contact_noti();
2425 ret = ctsvc_end_trans(true);
2426 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_svc_end_trans() Fail(%d)", ret);
2428 return CONTACTS_ERROR_NONE;
2431 static int __ctsvc_db_contact_replace_record(contacts_record_h record, int contact_id)
2435 int rel_changed = 0;
2438 char query[CTS_SQL_MAX_LEN] = {0};
2439 ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2440 cts_stmt stmt = NULL;
2443 ret = ctsvc_begin_trans();
2444 RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
2446 snprintf(query, sizeof(query),
2447 "SELECT addressbook_id, person_id FROM "CTS_TABLE_CONTACTS" "
2448 "WHERE contact_id = %d AND deleted = 0", contact_id);
2449 ret = ctsvc_query_prepare(query, &stmt);
2451 /* LCOV_EXCL_START */
2452 ERR("ctsvc_query_prepare fail(%d)", ret);
2453 ctsvc_end_trans(false);
2455 /* LCOV_EXCL_STOP */
2457 ret = ctsvc_stmt_step(stmt);
2459 /* LCOV_EXCL_START */
2460 ERR("The contact_id(%d) is Invalid(%d)", contact_id, ret);
2461 ctsvc_stmt_finalize(stmt);
2462 ctsvc_end_trans(false);
2463 if (CONTACTS_ERROR_NONE == ret)
2464 return CONTACTS_ERROR_NO_DATA;
2467 /* LCOV_EXCL_STOP */
2470 addressbook_id = ctsvc_stmt_get_int(stmt, 0);
2471 person_id = ctsvc_stmt_get_int(stmt, 1);
2472 ctsvc_stmt_finalize(stmt);
2474 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
2475 /* LCOV_EXCL_START */
2476 ERR("No permission in this addresbook_id(%d)", addressbook_id);
2477 ctsvc_end_trans(false);
2478 return CONTACTS_ERROR_PERMISSION_DENIED;
2479 /* LCOV_EXCL_STOP */
2482 contact->id = contact_id;
2483 contact->person_id = person_id;
2484 ctsvc_contact_make_display_name(contact);
2485 __ctsvc_contact_check_default_data(contact);
2487 /* remove current child data */
2488 snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE contact_id = %d",
2490 ret = ctsvc_query_exec(query);
2491 if (CONTACTS_ERROR_NONE != ret) {
2492 /* LCOV_EXCL_START */
2493 ERR("ctsvc_query_exec() Fail(%d)", ret);
2494 ctsvc_end_trans(false);
2496 /* LCOV_EXCL_STOP */
2499 ret = __ctsvc_contact_insert_data(contact);
2500 if (CONTACTS_ERROR_NONE != ret) {
2501 /* LCOV_EXCL_START */
2502 ERR("__ctsvc_contact_insert_data() Fail(%d)", ret);
2503 ctsvc_end_trans(false);
2505 /* LCOV_EXCL_STOP */
2508 /* remove current child data */
2509 snprintf(query, sizeof(query),
2510 "DELETE FROM "CTS_TABLE_GROUP_RELATIONS" WHERE contact_id = %d", contact_id);
2511 ret = ctsvc_query_exec(query);
2512 if (CONTACTS_ERROR_NONE != ret) {
2513 /* LCOV_EXCL_START */
2514 ERR("ctsvc_query_exec() Fail(%d)", ret);
2515 ctsvc_end_trans(false);
2517 /* LCOV_EXCL_STOP */
2520 if (contact->grouprelations) {
2521 rel_changed = __ctsvc_contact_insert_grouprel(contact_id,
2522 (contacts_list_h)contact->grouprelations);
2523 if (rel_changed < CONTACTS_ERROR_NONE) {
2524 /* LCOV_EXCL_START */
2525 ERR("__ctsvc_contact_insert_grouprel() Fail(%d)", rel_changed);
2526 ctsvc_end_trans(false);
2528 /* LCOV_EXCL_STOP */
2533 if (contact->images) {
2534 int ret = CONTACTS_ERROR_NONE;
2536 ctsvc_image_s *image;
2537 char *contact_image_path = NULL;
2539 contacts_list_get_count((contacts_list_h)contact->images, &count);
2541 contacts_list_first((contacts_list_h)contact->images);
2543 ret = contacts_list_get_current_record_p((contacts_list_h)contact->images,
2544 (contacts_record_h*)&image);
2545 if (CONTACTS_ERROR_NONE != ret) {
2546 /* LCOV_EXCL_START */
2547 ERR("contacts_list_get_current_record_p() Fail(%d)", ret);
2548 ctsvc_end_trans(false);
2549 return CONTACTS_ERROR_DB;
2550 /* LCOV_EXCL_STOP */
2553 if (image->is_default)
2555 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
2557 contact_image_path = ctsvc_utils_get_image_path(contact->image_thumbnail_path);
2558 if ((NULL == contact_image_path && image->path) ||
2559 (contact_image_path && NULL == image->path) ||
2560 (contact_image_path && image->path && STRING_EQUAL != strcmp(contact_image_path, image->path))) {
2561 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
2564 contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
2566 free(contact_image_path);
2567 } else if (contact->image_thumbnail_path) {
2568 free(contact->image_thumbnail_path);
2569 contact->image_thumbnail_path = NULL;
2570 if (false == ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY)) {
2571 ctsvc_record_set_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
2573 if (((ctsvc_record_s*)record)->properties_flags) {
2574 int index = _contacts_contact.image_thumbnail_path & 0x000000FF;
2575 ((ctsvc_record_s*)record)->properties_flags[index] = 0;
2580 version = ctsvc_get_next_ver();
2582 len = snprintf(query, sizeof(query),
2583 "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver=%d, changed_time=%d, is_favorite=%d, "
2584 "has_phonenumber=%d, has_email=%d, display_name=?, "
2585 "reverse_display_name=?, display_name_source=%d, "
2586 "display_name_language=%d, reverse_display_name_language=%d, "
2587 "sort_name=?, reverse_sort_name=?, "
2588 "sortkey=?, reverse_sortkey=?, uid=?, ringtone_path=?, vibration=?, "
2589 "message_alert =?, image_thumbnail_path=?",
2590 version, (int)time(NULL), contact->is_favorite,
2591 contact->has_phonenumber, contact->has_email,
2592 contact->display_source_type,
2593 contact->display_name_language, contact->reverse_display_name_language);
2595 if (ctsvc_record_check_property_flag((ctsvc_record_s*)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY))
2596 len += snprintf(query+len, sizeof(query)-len, ", image_changed_ver = %d", version);
2598 len += snprintf(query+len, sizeof(query)-len, " WHERE contact_id=%d", contact->id);
2600 ret = ctsvc_query_prepare(query, &stmt);
2602 /* LCOV_EXCL_START */
2603 ERR("ctsvc_query_prepare() Fail(%d)", ret);
2604 ctsvc_end_trans(false);
2606 /* LCOV_EXCL_STOP */
2609 if (contact->display_name)
2610 ctsvc_stmt_bind_text(stmt, 1, contact->display_name);
2611 if (contact->reverse_display_name)
2612 ctsvc_stmt_bind_text(stmt, 2, contact->reverse_display_name);
2613 if (contact->sort_name)
2614 ctsvc_stmt_bind_text(stmt, 3, contact->sort_name);
2615 if (contact->reverse_sort_name)
2616 ctsvc_stmt_bind_text(stmt, 4, contact->reverse_sort_name);
2617 if (contact->sortkey)
2618 ctsvc_stmt_bind_text(stmt, 5, contact->sortkey);
2619 if (contact->reverse_sortkey)
2620 ctsvc_stmt_bind_text(stmt, 6, contact->reverse_sortkey);
2622 ctsvc_stmt_bind_text(stmt, 7, contact->uid);
2623 if (contact->ringtone_path)
2624 ctsvc_stmt_bind_text(stmt, 8, contact->ringtone_path);
2625 if (contact->vibration)
2626 ctsvc_stmt_bind_text(stmt, 9, contact->vibration);
2627 if (contact->message_alert)
2628 ctsvc_stmt_bind_text(stmt, 10, contact->message_alert);
2629 if (contact->image_thumbnail_path)
2630 ctsvc_stmt_bind_text(stmt, 11, contact->image_thumbnail_path);
2632 ret = ctsvc_stmt_step(stmt);
2633 if (CONTACTS_ERROR_NONE != ret) {
2634 /* LCOV_EXCL_START */
2635 ERR("ctsvc_stmt_step() Fail(%d)", ret);
2636 ctsvc_stmt_finalize(stmt);
2637 ctsvc_end_trans(false);
2639 /* LCOV_EXCL_STOP */
2641 ctsvc_stmt_finalize(stmt);
2643 ctsvc_set_contact_noti();
2644 if (0 < rel_changed)
2645 ctsvc_set_group_rel_noti();
2647 __ctsvc_contact_update_search_data(contact->id, true);
2648 ctsvc_db_update_person((contacts_record_h)contact);
2650 ret = ctsvc_end_trans(true);
2652 if (ret < CONTACTS_ERROR_NONE)
2655 return CONTACTS_ERROR_NONE;
2658 ctsvc_db_plugin_info_s ctsvc_db_plugin_contact = {
2659 .is_query_only = false,
2660 .insert_record = __ctsvc_db_contact_insert_record,
2661 .get_record = __ctsvc_db_contact_get_record,
2662 .update_record = __ctsvc_db_contact_update_record,
2663 .delete_record = __ctsvc_db_contact_delete_record,
2664 .get_all_records = __ctsvc_db_contact_get_all_records,
2665 .get_records_with_query = __ctsvc_db_contact_get_records_with_query,
2666 .insert_records = NULL,
2667 .update_records = NULL,
2668 .delete_records = NULL,
2670 .get_count_with_query = NULL,
2671 .replace_record = __ctsvc_db_contact_replace_record,
2672 .replace_records = NULL,