[Contacts-service][Nno-ACR] Asan issue fixes TFDF-3462,3463
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_plugin_contact.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19 #include <fcntl.h>
20 #include <unistd.h>
21
22 #include "contacts.h"
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"
41
42 #ifdef ENABLE_LOG_FEATURE
43 #include "ctsvc_server_phonelog.h"
44 #endif /* ENABLE_LOG_FEATURE */
45 #include "ctsvc_db_access_control.h"
46
47 #include "ctsvc_db_plugin_contact_helper.h"
48 #include "ctsvc_db_plugin_person_helper.h"
49
50
51 static int __ctsvc_db_get_contact_base_info(int id, ctsvc_contact_s *contact)
52 {
53         int ret;
54         int i;
55         cts_stmt stmt = NULL;
56         char query[CTS_SQL_MAX_LEN] = {0};
57         char *temp;
58         char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
59
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);
68
69         ret = ctsvc_query_prepare(query, &stmt);
70         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
71
72         ret = ctsvc_stmt_step(stmt);
73         if (1 /*CTS_TRUE*/ != ret) {
74                 /* LCOV_EXCL_START */
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;
79                 else
80                         return ret;
81                 /* LCOV_EXCL_STOP */
82         }
83
84         i = 0;
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++);
94
95         temp = ctsvc_stmt_get_text(stmt, i++);
96         if (temp) {
97                 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
98                 contact->image_thumbnail_path = strdup(full_path);
99         }
100
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);
117
118         return CONTACTS_ERROR_NONE;
119 }
120
121 static int __ctsvc_db_get_data(int id, ctsvc_contact_s *contact)
122 {
123         int ret;
124         int datatype;
125         cts_stmt stmt = NULL;
126         char query[CTS_SQL_MAX_LEN] = {0};
127
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);
135
136         ret = ctsvc_query_prepare(query, &stmt);
137         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
138
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);
144                 return ret;
145                 /* LCOV_EXCL_STOP */
146         }
147
148         do {
149                 datatype = ctsvc_stmt_get_int(stmt, 0);
150                 switch (datatype) {
151                 case CONTACTS_DATA_TYPE_NAME:
152                         ctsvc_get_data_info_name(stmt, (contacts_list_h)contact->name);
153                         break;
154                 case CONTACTS_DATA_TYPE_EVENT:
155                         ctsvc_get_data_info_event(stmt, (contacts_list_h)contact->events);
156                         break;
157                 case CONTACTS_DATA_TYPE_MESSENGER:
158                         ctsvc_get_data_info_messenger(stmt, (contacts_list_h)contact->messengers);
159                         break;
160                 case CONTACTS_DATA_TYPE_POSTAL:
161                         ctsvc_get_data_info_address(stmt, (contacts_list_h)contact->postal_addrs);
162                         break;
163                 case CONTACTS_DATA_TYPE_URL:
164                         ctsvc_get_data_info_url(stmt, (contacts_list_h)contact->urls);
165                         break;
166                 case CONTACTS_DATA_TYPE_NICKNAME:
167                         ctsvc_get_data_info_nickname(stmt, (contacts_list_h)contact->nicknames);
168                         break;
169                 case CONTACTS_DATA_TYPE_NUMBER:
170                         ctsvc_get_data_info_number(stmt, (contacts_list_h)contact->numbers);
171                         break;
172                 case CONTACTS_DATA_TYPE_EMAIL:
173                         ctsvc_get_data_info_email(stmt, (contacts_list_h)contact->emails);
174                         break;
175                 case CONTACTS_DATA_TYPE_PROFILE:
176                         ctsvc_get_data_info_profile(stmt, (contacts_list_h)contact->profiles);
177                         break;
178                 case CONTACTS_DATA_TYPE_RELATIONSHIP:
179                         ctsvc_get_data_info_relationship(stmt, (contacts_list_h)contact->relationships);
180                         break;
181                 case CONTACTS_DATA_TYPE_IMAGE:
182                         ctsvc_get_data_info_image(stmt, (contacts_list_h)contact->images);
183                         break;
184                 case CONTACTS_DATA_TYPE_COMPANY:
185                         ctsvc_get_data_info_company(stmt, (contacts_list_h)contact->company);
186                         break;
187                 case CONTACTS_DATA_TYPE_NOTE:
188                         ctsvc_get_data_info_note(stmt, (contacts_list_h)contact->note);
189                         break;
190                 case CONTACTS_DATA_TYPE_EXTENSION:
191                         ctsvc_get_data_info_extension(stmt, (contacts_list_h)contact->extensions);
192                         break;
193                 case CONTACTS_DATA_TYPE_SIP:
194                         ctsvc_get_data_info_sip(stmt, (contacts_list_h)contact->sips);
195                         break;
196                 default:
197                         /* LCOV_EXCL_START */
198                         ERR("Intenal : Not supported data type (%d)", datatype);
199                         break;
200                         /* LCOV_EXCL_STOP */
201                 }
202
203         } while (1 == ctsvc_stmt_step(stmt));
204
205         ctsvc_stmt_finalize(stmt);
206
207         return CONTACTS_ERROR_NONE;
208
209 }
210
211 static inline int __ctsvc_get_contact_grouprel(int contact_id, ctsvc_contact_s *contact)
212 {
213         CTS_FN_CALL;
214         int ret;
215         ctsvc_group_relation_s *grouprel;
216         cts_stmt stmt = NULL;
217         char query[CTS_SQL_MAX_LEN] = {0};
218         char *temp;
219
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);
223
224         ret = ctsvc_query_prepare(query, &stmt);
225         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
226
227         while (1 /*CTS_TRUE */ == ctsvc_stmt_step(stmt)) {
228                 contacts_record_create(_contacts_group_relation._uri, (contacts_record_h*)&grouprel);
229
230                 if (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);
236
237                         ctsvc_list_prepend((contacts_list_h)contact->grouprelations, (contacts_record_h)grouprel);
238                 }
239         }
240
241         ctsvc_stmt_finalize(stmt);
242         ctsvc_list_reverse((contacts_list_h)contact->grouprelations);
243         return CONTACTS_ERROR_NONE;
244 }
245
246 static int __ctsvc_db_contact_get_record(int id, contacts_record_h *out_record)
247 {
248         int ret;
249         contacts_record_h record;
250         ctsvc_contact_s *contact;
251
252         RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
253         *out_record = NULL;
254
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);
262                 return ret;
263                 /* LCOV_EXCL_STOP */
264         }
265
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);
271                 return ret;
272                 /* LCOV_EXCL_STOP */
273         }
274
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);
280                 return ret;
281                 /* LCOV_EXCL_STOP */
282         }
283
284         *out_record = record;
285
286         return CONTACTS_ERROR_NONE;
287 }
288
289 static int __ctsvc_db_contact_delete_record(int id)
290 {
291         return ctsvc_db_contact_delete(id);
292 }
293
294 static inline int __ctsvc_contact_update_data(ctsvc_contact_s *contact)
295 {
296         int ret;
297
298         if (contact->name) {
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);
303                         return ret;
304                         /* LCOV_EXCL_STOP */
305                 }
306         }
307
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);
313                         return ret;
314                         /* LCOV_EXCL_STOP */
315                 }
316         }
317
318         if (contact->note) {
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);
323                         return ret;
324                         /* LCOV_EXCL_STOP */
325                 }
326         }
327
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);
333                         return ret;
334                         /* LCOV_EXCL_STOP */
335                 }
336         }
337
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);
343                         return ret;
344                         /* LCOV_EXCL_STOP */
345                 }
346         }
347
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);
353                         return ret;
354                         /* LCOV_EXCL_STOP */
355                 }
356         }
357
358         if (contact->urls) {
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);
363                         return ret;
364                         /* LCOV_EXCL_STOP */
365                 }
366         }
367
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);
373                         return ret;
374                         /* LCOV_EXCL_STOP */
375                 }
376         }
377
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);
384                         return ret;
385                         /* LCOV_EXCL_STOP */
386                 }
387                 contact->has_phonenumber = had_phonenumber;
388         }
389
390         if (contact->emails) {
391                 bool had_email;
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);
396                         return ret;
397                         /* LCOV_EXCL_STOP */
398                 }
399                 contact->has_email = had_email;
400         }
401
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);
407                         return ret;
408                         /* LCOV_EXCL_STOP */
409                 }
410         }
411
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);
417                         return ret;
418                         /* LCOV_EXCL_STOP */
419                 }
420         }
421
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);
427                         return ret;
428                         /* LCOV_EXCL_STOP */
429                 }
430         }
431
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);
437                         return ret;
438                         /* LCOV_EXCL_STOP */
439                 }
440         }
441
442         if (contact->sips) {
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);
447                         return ret;
448                         /* LCOV_EXCL_STOP */
449                 }
450         }
451         return CONTACTS_ERROR_NONE;
452 }
453
454 static void __ctsvc_contact_check_default_data(ctsvc_contact_s *contact)
455 {
456         if (contact->numbers)
457                 contact->has_phonenumber = ctsvc_contact_check_default_number((contacts_list_h)contact->numbers);
458         if (contact->emails)
459                 contact->has_email = ctsvc_contact_check_default_email((contacts_list_h)contact->emails);
460         if (contact->images)
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);
464 }
465
466 static inline int __ctsvc_contact_update_grouprel(int contact_id, contacts_list_h group_list)
467 {
468         CTS_FN_CALL;
469         ctsvc_group_relation_s *grouprel;
470         ctsvc_list_s *list = (ctsvc_list_s*)group_list;
471         int rel_changed = 0;
472         int count;
473         int ret;
474         GList *cursor;
475
476         RETV_IF(NULL == group_list, CONTACTS_ERROR_INVALID_PARAMETER);
477
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);
481                 if (0 < ret)
482                         rel_changed += ret;
483         }
484
485         ret = contacts_list_get_count(group_list, &count);
486         if (0 == count)
487                 return CONTACTS_ERROR_NONE;
488
489         contacts_list_first(group_list);
490         do {
491                 contacts_list_get_current_record_p(group_list, (contacts_record_h*)&grouprel);
492                 if (NULL == grouprel)
493                         continue;
494
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);
499                         if (0 < ret)
500                                 rel_changed += ret;
501                 }
502         } while (CONTACTS_ERROR_NONE == contacts_list_next(group_list));
503
504         if (rel_changed)
505                 return rel_changed;
506         else
507                 return CONTACTS_ERROR_NONE;
508 }
509
510 static bool __ctsvc_contact_check_token(char *src, char *dest, int len)
511 {
512         bool had = false;
513         int i = 0;
514
515         for (i = 0; i < len; i++) {
516                 if (src[i] == '@' || src[i] == '.') {
517                         dest[i] = ' ';
518                         had = true;
519                 } else {
520                         dest[i] = src[i];
521                 }
522         }
523         dest[i] = '\0';
524
525         return had;
526 }
527
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)
531 {
532         int len = 0;
533
534         char *number = NULL;
535         char *data = NULL;
536         char *temp_number = NULL;
537         char *temp_data = NULL;
538         int buf_size = 0;
539
540         RETV_IF(NULL == contact, CONTACTS_ERROR_NO_DATA);
541
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);
546                 do {
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");
554                                         free(number);
555                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
556                                         /* LCOV_EXCL_STOP */
557                                 }
558
559                                 if (number)
560                                         snprintf(temp_number, buf_size, "%s %s %s", SAFE_STR(number), number_record->cleaned, number_record->normalized);
561                                 else
562                                         snprintf(temp_number, buf_size, "%s %s", number_record->cleaned, number_record->normalized);
563                                 free(number);
564                                 number = temp_number;
565                         }
566                 } while (CONTACTS_ERROR_NONE == contacts_list_next(number_list));
567         }
568
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);
573                 do {
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);
577                                 char temp[len+1];
578                                 bool had = __ctsvc_contact_check_token(email->email_addr, temp, len);
579
580                                 buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(email->email_addr)
581                                         * (had ? 2 : 1) + 4;
582                                 temp_data = calloc(1, buf_size);
583                                 if (NULL == temp_data) {
584                                         /* LCOV_EXCL_START */
585                                         ERR("calloc() Fail");
586                                         free(data);
587                                         free(number);
588                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
589                                         /* LCOV_EXCL_STOP */
590                                 }
591
592                                 if (data) {
593                                         snprintf(temp_data, buf_size, "%s %s %s", data, email->email_addr,
594                                                         (had ? temp : ""));
595                                 } else {
596                                         snprintf(temp_data, buf_size, "%s %s", email->email_addr,
597                                                         (had ? temp : ""));
598                                 }
599                                 free(data);
600                                 data = temp_data;
601                         }
602                 } while (CONTACTS_ERROR_NONE == contacts_list_next(email_list));
603         }
604
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);
609                 do {
610                         contacts_list_get_current_record_p(nickname_list, (contacts_record_h*)&nickname);
611                         if (nickname && nickname->nickname) {
612                                 int len = strlen(nickname->nickname);
613                                 char temp[len+1];
614                                 bool had = __ctsvc_contact_check_token(nickname->nickname, temp, len);
615
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");
621                                         free(data);
622                                         free(number);
623                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
624                                         /* LCOV_EXCL_STOP */
625                                 }
626
627                                 if (data)
628                                         snprintf(temp_data, buf_size, "%s %s %s", data, nickname->nickname, (had ? temp : ""));
629                                 else
630                                         snprintf(temp_data, buf_size, "%s %s", nickname->nickname, (had ? temp : ""));
631                                 free(data);
632                                 data = temp_data;
633                         }
634                 } while (CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
635         }
636
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);
641                 do {
642                         contacts_list_get_current_record_p(address_list, (contacts_record_h*)&address);
643                         if (address) {
644                                 bool had;
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);
652                                 len = 0;
653                                 buf_size = SAFE_STRLEN(data)
654                                         + str_len * 2 + 16;
655                                 temp_data = calloc(1, buf_size);
656                                 if (NULL == temp_data) {
657                                         /* LCOV_EXCL_START */
658                                         ERR("calloc() Fail");
659                                         free(data);
660                                         free(number);
661                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
662                                         /* LCOV_EXCL_STOP */
663                                 }
664
665                                 char temp[str_len+1];
666
667                                 if (data)
668                                         len += snprintf(temp_data + len, buf_size - len, "%s ", data);
669
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 : "");
673                                 }
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 : "");
677                                 }
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 : "");
681                                 }
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 : "");
685                                 }
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 : "");
689                                 }
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 : "");
693                                 }
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 : "");
697                                 }
698                                 free(data);
699                                 data = temp_data;
700                         }
701                 } while (CONTACTS_ERROR_NONE == contacts_list_next(address_list));
702         }
703
704         if (contact->note) {
705                 contacts_list_h note_list = (contacts_list_h)contact->note;
706                 ctsvc_note_s *note;
707                 contacts_list_first(note_list);
708                 do {
709                         contacts_list_get_current_record_p(note_list, (contacts_record_h*)&note);
710                         if (note && note->note) {
711                                 int len = strlen(note->note);
712                                 char temp[len+1];
713                                 bool had = __ctsvc_contact_check_token(note->note, temp, len);
714
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");
720                                         free(data);
721                                         free(number);
722                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
723                                         /* LCOV_EXCL_STOP */
724                                 }
725
726                                 if (data) {
727                                         snprintf(temp_data, buf_size, "%s %s %s", data, note->note,
728                                                         (had ? temp : ""));
729                                 } else {
730                                         snprintf(temp_data, buf_size, "%s %s", note->note,
731                                                         (had ? temp : ""));
732                                 }
733                                 free(data);
734                                 data = temp_data;
735                         }
736                 } while (CONTACTS_ERROR_NONE == contacts_list_next(note_list));
737         }
738
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);
743                 do {
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);
747                                 char temp[len+1];
748                                 bool had = __ctsvc_contact_check_token(messenger->im_id, temp, len);
749
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");
755                                         free(data);
756                                         free(number);
757                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
758                                         /* LCOV_EXCL_STOP */
759                                 }
760
761                                 if (data) {
762                                         snprintf(temp_data, buf_size, "%s %s %s", data, messenger->im_id,
763                                                         (had ? temp : ""));
764                                 } else {
765                                         snprintf(temp_data, buf_size, "%s %s", messenger->im_id,
766                                                         (had ? temp : ""));
767                                 }
768                                 free(data);
769                                 data = temp_data;
770                         }
771                 } while (CONTACTS_ERROR_NONE == contacts_list_next(messenger_list));
772         }
773
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);
778                 do {
779                         contacts_list_get_current_record_p(relationship_list, (contacts_record_h*)&relationship);
780                         if (relationship && relationship->name) {
781                                 int len = strlen(relationship->name);
782                                 char temp[len+1];
783                                 bool had = __ctsvc_contact_check_token(relationship->name, temp, len);
784
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");
790                                         free(data);
791                                         free(number);
792                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
793                                         /* LCOV_EXCL_STOP */
794                                 }
795
796                                 if (data) {
797                                         snprintf(temp_data, buf_size, "%s %s %s", data, relationship->name,
798                                                         (had ? temp : ""));
799                                 } else {
800                                         snprintf(temp_data, buf_size, "%s %s", relationship->name,
801                                                         (had ? temp : ""));
802                                 }
803                                 free(data);
804                                 data = temp_data;
805                         }
806                 } while (CONTACTS_ERROR_NONE == contacts_list_next(relationship_list));
807         }
808
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);
813                 do {
814                         contacts_list_get_current_record_p(company_list, (contacts_record_h*)&company);
815                         if (company) {
816                                 bool had;
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);
825                                 len = 0;
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");
831                                         free(data);
832                                         free(number);
833                                         return CONTACTS_ERROR_OUT_OF_MEMORY;
834                                         /* LCOV_EXCL_STOP */
835                                 }
836
837                                 char temp[str_len+1];
838
839                                 if (data)
840                                         len += snprintf(temp_data + len, buf_size - len, "%s ", data);
841                                 if (company->name) {
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 : "");
844                                 }
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 : "");
848                                 }
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 : "");
852                                 }
853                                 if (company->role) {
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 : "");
856                                 }
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 : "");
860                                 }
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 : "");
864                                 }
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 : "");
868                                 }
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 : "");
872                                 }
873
874                                 free(data);
875                                 data = temp_data;
876                         }
877                 } while (CONTACTS_ERROR_NONE == contacts_list_next(company_list));
878         }
879
880         *search_number = number;
881         if (data)
882                 *search_data = data;
883
884         return CONTACTS_ERROR_NONE;
885 }
886
887 static inline int __ctsvc_contact_refresh_lookup_data(int contact_id, ctsvc_contact_s *contact)
888 {
889         CTS_FN_CALL;
890         int ret, len = 0, temp_len = 0;
891         char query[CTS_SQL_MAX_LEN] = {0};
892
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);
899                 return ret;
900                 /* LCOV_EXCL_STOP */
901         }
902
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);
909                 return ret;
910                 /* LCOV_EXCL_STOP */
911         }
912
913         if (contact == NULL)
914                 return CONTACTS_ERROR_NO_DATA;
915
916         if (contact->name) {
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);
922                 len = 0;
923                 /* name record of contact should be one */
924                 do {
925                         contacts_list_get_current_record_p(name_list, (contacts_record_h*)&name_record);
926                         if (name_record
927                                         && (name_record->last
928                                                 || name_record->first
929                                                 || name_record->addition
930                                                 || name_record->suffix)) {
931                                 char *normalized_name = NULL;
932
933                                 /*
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
940                                  */
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)
946                                         + 1;
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;
953                                         /* LCOV_EXCL_STOP */
954                                 }
955
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);
967                                 } else {
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);
976                                 }
977
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,
981                                                 contact_id, 0);
982
983                                 ret = ctsvc_query_prepare(query, &stmt);
984                                 if (NULL == stmt) {
985                                         /* LCOV_EXCL_START */
986                                         ERR("ctsvc_query_prepare() Fail(%d)", ret);
987                                         free(temp_name);
988                                         free(normalized_name);
989                                         return ret;
990                                         /* LCOV_EXCL_STOP */
991                                 }
992
993                                 if (normalized_name)
994                                         ctsvc_stmt_bind_text(stmt, 1, normalized_name);
995
996                                 ret = ctsvc_stmt_step(stmt);
997
998                                 free(temp_name);
999                                 free(normalized_name);
1000
1001                                 ctsvc_stmt_finalize(stmt);
1002
1003                                 if (CONTACTS_ERROR_NONE != ret) {
1004                                         /* LCOV_EXCL_START */
1005                                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
1006                                         return ret;
1007                                         /* LCOV_EXCL_STOP */
1008                                 }
1009                                 break;
1010                         }
1011                 } while (CONTACTS_ERROR_NONE == contacts_list_next(name_list));
1012         }
1013
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);
1019                 len = 0;
1020                 do {
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)
1024                                         continue;
1025
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,
1029                                                 contact_id);
1030
1031                                 ret = ctsvc_query_prepare(query, &stmt);
1032                                 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
1033
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);
1041                                         return ret;
1042                                         /* LCOV_EXCL_STOP */
1043                                 }
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);
1053                                                 return ret;
1054                                                 /* LCOV_EXCL_STOP */
1055                                         }
1056                                 }
1057                                 ctsvc_stmt_finalize(stmt);
1058                         }
1059                 } while (CONTACTS_ERROR_NONE == contacts_list_next(number_list));
1060         }
1061
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);
1067                 do {
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);
1075
1076                                 ret = ctsvc_query_prepare(query, &stmt);
1077                                 if (NULL == stmt) {
1078                                         /* LCOV_EXCL_START */
1079                                         ERR("ctsvc_query_prepare() Fail(%d)", ret);
1080                                         free(normalized_nickname);
1081                                         return ret;
1082                                         /* LCOV_EXCL_STOP */
1083                                 }
1084
1085                                 if (normalized_nickname && *normalized_nickname)
1086                                         ctsvc_stmt_bind_text(stmt, 1, normalized_nickname);
1087
1088                                 ret = ctsvc_stmt_step(stmt);
1089
1090                                 free(normalized_nickname);
1091
1092                                 ctsvc_stmt_finalize(stmt);
1093
1094                                 if (CONTACTS_ERROR_NONE != ret) {
1095                                         /* LCOV_EXCL_START */
1096                                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
1097                                         return ret;
1098                                         /* LCOV_EXCL_STOP */
1099                                 }
1100                         }
1101                 } while (CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
1102         }
1103
1104         return CONTACTS_ERROR_NONE;
1105 }
1106
1107 static inline int __ctsvc_contact_update_search_data(int contact_id, bool need_refresh_lookup_data)
1108 {
1109         int ret;
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;
1116
1117         ret = ctsvc_begin_trans();
1118         RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
1119
1120         ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&contact);
1121         if (CONTACTS_ERROR_NO_DATA == ret) {
1122                 int r;
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);
1130                         return r;
1131                         /* LCOV_EXCL_STOP */
1132                 }
1133                 ctsvc_end_trans(false);
1134                 return ret;
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);
1139                 return ret;
1140                 /* LCOV_EXCL_STOP */
1141         }
1142
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);
1149                 return ret;
1150                 /* LCOV_EXCL_STOP */
1151         }
1152
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);
1159                 free(search_name);
1160                 return ret;
1161                 /* LCOV_EXCL_STOP */
1162         }
1163
1164         snprintf(query, sizeof(query),
1165                         "UPDATE %s SET name=?, number=?, data=? "
1166                         "WHERE contact_id = %d",
1167                         CTS_TABLE_SEARCH_INDEX, contact_id);
1168
1169         ret = ctsvc_query_prepare(query, &stmt);
1170         if (NULL == 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);
1175                 free(search_name);
1176                 free(search_number);
1177                 free(search_data);
1178                 return ret;
1179                 /* LCOV_EXCL_STOP */
1180         }
1181
1182         if (search_name)
1183                 ctsvc_stmt_bind_text(stmt, 1, search_name);
1184         if (search_number)
1185                 ctsvc_stmt_bind_text(stmt, 2, search_number);
1186         if (search_data)
1187                 ctsvc_stmt_bind_text(stmt, 3, search_data);
1188
1189         ret = ctsvc_stmt_step(stmt);
1190
1191         free(search_name);
1192         free(search_number);
1193         free(search_data);
1194
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);
1201                 return ret;
1202                 /* LCOV_EXCL_STOP */
1203         }
1204         ctsvc_stmt_finalize(stmt);
1205
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);
1214                         return ret;
1215                         /* LCOV_EXCL_STOP */
1216                 }
1217         }
1218
1219         contacts_record_destroy((contacts_record_h)contact, true);
1220
1221         ret = ctsvc_end_trans(true);
1222         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
1223
1224         return CONTACTS_ERROR_NONE;
1225 }
1226
1227 static bool __ctsvc_list_check_dirty(ctsvc_list_s *list)
1228 {
1229         if (list) {
1230                 if (list->deleted_records)
1231                         return true;
1232
1233                 GList *c = NULL;
1234                 for (c = list->records; c; c = c->next) {
1235                         ctsvc_record_s *s_record = c->data;
1236                         int i;
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);
1242                                 if (ret)
1243                                         return true;
1244                         }
1245                 }
1246         }
1247         return false;
1248 }
1249
1250 static bool __ctsvc_get_need_refresh_lookup_data(ctsvc_contact_s *contact)
1251 {
1252         if (__ctsvc_list_check_dirty(contact->name))
1253                 return true;
1254         if (__ctsvc_list_check_dirty(contact->numbers))
1255                 return true;
1256         if (__ctsvc_list_check_dirty(contact->nicknames))
1257                 return true;
1258         return false;
1259 }
1260
1261 static int __ctsvc_db_contact_update_record(contacts_record_h record)
1262 {
1263         int ret, len = 0;
1264         int rel_changed = 0;
1265         int version;
1266         char *set = NULL;
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;
1273
1274         ret = ctsvc_begin_trans();
1275         RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
1276
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, &current_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);
1285                 return ret;
1286                 /* LCOV_EXCL_STOP */
1287         }
1288
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 */
1295         }
1296
1297         if (current_version != contact->changed_ver)
1298                 is_invalid = true;
1299         __ctsvc_contact_check_default_data(contact);
1300
1301         /* check lookup data is dirty */
1302         bool need_update_lookup = __ctsvc_get_need_refresh_lookup_data(contact);
1303
1304         /* update data */
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);
1310                 return ret;
1311                 /* LCOV_EXCL_STOP */
1312         }
1313
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);
1320                         return rel_changed;
1321                         /* LCOV_EXCL_STOP */
1322                 }
1323         }
1324
1325         /* thumbnail */
1326         if (contact->images) {
1327                 int ret = CONTACTS_ERROR_NONE;
1328                 int count = 0;
1329                 ctsvc_image_s *image;
1330                 char *contact_image_path = NULL;
1331
1332                 contacts_list_get_count((contacts_list_h)contact->images, &count);
1333                 if (count) {
1334                         contacts_list_first((contacts_list_h)contact->images);
1335                         do {
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 */
1343                                 }
1344
1345                                 if (image->is_default)
1346                                         break;
1347                         } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
1348
1349                         contact_image_path = ctsvc_utils_get_image_path(contact->image_thumbnail_path);
1350
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);
1357
1358                                 if (image->path)
1359                                         contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
1360                         }
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);
1368                         } else {
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;
1372                                 }
1373                         }
1374                 }
1375         }
1376
1377         if (is_invalid) {
1378                 ctsvc_contact_s *temp_contact;
1379                 contacts_record_create(_contacts_contact._uri, (contacts_record_h*)&temp_contact);
1380
1381                 ret = __ctsvc_db_get_data(contact->id, temp_contact);
1382                 WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_db_get_data() Fail(%d)", ret);
1383
1384                 ctsvc_contact_make_display_name(temp_contact);
1385
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);
1392
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;
1396
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);
1399
1400                 contacts_record_destroy((contacts_record_h)temp_contact, true);
1401         } else {
1402                 ctsvc_contact_make_display_name(contact);
1403         }
1404
1405         do {
1406                 char query[CTS_SQL_MAX_LEN] = {0};
1407                 char query_set[CTS_SQL_MIN_LEN] = {0, };
1408                 cts_stmt stmt = NULL;
1409
1410                 version = ctsvc_get_next_ver();
1411
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);
1414
1415                 if (set && *set)
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)));
1431                 }
1432
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);
1435
1436                 snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE contact_id = %d", CTS_TABLE_CONTACTS, query_set, contact->id);
1437
1438                 ret = ctsvc_query_prepare(query, &stmt);
1439                 if (NULL == stmt) {
1440                         /* LCOV_EXCL_START */
1441                         ERR("ctsvc_query_prepare() Fail(%d)", ret);
1442                         break;
1443                         /* LCOV_EXCL_STOP */
1444                 }
1445
1446                 if (bind_text) {
1447                         int i = 0;
1448                         for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++) {
1449                                 const char *text = cursor->data;
1450                                 if (*text)
1451                                         ctsvc_stmt_bind_text(stmt, i, text);
1452                         }
1453                 }
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);
1459                         break;
1460                         /* LCOV_EXCL_STOP */
1461                 }
1462                 ctsvc_stmt_finalize(stmt);
1463         } while (0);
1464
1465         if (CONTACTS_ERROR_NONE != ret) {
1466                 ctsvc_end_trans(false);
1467                 CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s*)record);
1468                 free(set);
1469
1470                 if (bind_text) {
1471                         for (cursor = bind_text; cursor; cursor = cursor->next) {
1472                                 free(cursor->data);
1473                                 cursor->data = NULL;
1474                         }
1475                         g_slist_free(bind_text);
1476                 }
1477                 return ret;
1478         }
1479
1480         ctsvc_set_contact_noti();
1481         if (0 < rel_changed)
1482                 ctsvc_set_group_rel_noti();
1483
1484         __ctsvc_contact_update_search_data(contact->id, need_update_lookup);
1485         ctsvc_db_update_person((contacts_record_h)contact);
1486
1487         CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s*)record);
1488         free(set);
1489
1490         if (bind_text) {
1491                 for (cursor = bind_text; cursor; cursor = cursor->next) {
1492                         free(cursor->data);
1493                         cursor->data = NULL;
1494                 }
1495                 g_slist_free(bind_text);
1496         }
1497
1498         ret = ctsvc_end_trans(true);
1499         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
1500
1501         return CONTACTS_ERROR_NONE;
1502 }
1503
1504 static int __ctsvc_db_contact_get_all_records(int offset, int limit, contacts_list_h *out_list)
1505 {
1506         int ret;
1507         int len;
1508         int contact_id;
1509         cts_stmt stmt;
1510         char query[CTS_SQL_MAX_LEN] = {0};
1511         contacts_list_h list;
1512
1513         len = snprintf(query, sizeof(query),
1514                         "SELECT contact_id FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0");
1515
1516         if (0 != limit) {
1517                 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
1518                 if (0 < offset)
1519                         len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
1520         }
1521
1522         ret = ctsvc_query_prepare(query, &stmt);
1523         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
1524
1525         contacts_list_create(&list);
1526         while ((ret = ctsvc_stmt_step(stmt))) {
1527                 contacts_record_h record;
1528                 if (1 != ret) {
1529                         /* LCOV_EXCL_START */
1530                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
1531                         ctsvc_stmt_finalize(stmt);
1532                         contacts_list_destroy(list, true);
1533                         return ret;
1534                         /* LCOV_EXCL_STOP */
1535                 }
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);
1543                         return ret;
1544                         /* LCOV_EXCL_STOP */
1545                 }
1546                 ctsvc_list_prepend(list, record);
1547         }
1548         ctsvc_stmt_finalize(stmt);
1549         ctsvc_list_reverse(list);
1550
1551         *out_list = (contacts_list_h)list;
1552         return CONTACTS_ERROR_NONE;
1553 }
1554
1555 static int __ctsvc_db_contact_get_changed_ver(int contact_id, ctsvc_contact_s *contact)
1556 {
1557         int ret;
1558         int version;
1559         char query[CTS_SQL_MAX_LEN] = {0};
1560
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;
1567         return ret;
1568 }
1569
1570 static int __ctsvc_db_contact_get_records_with_query(contacts_query_h query, int offset, int limit, contacts_list_h *out_list)
1571 {
1572         int ret;
1573         int i;
1574         int field_count;
1575         ctsvc_query_s *s_query;
1576         cts_stmt stmt;
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;
1581         int contact_id = 0;
1582
1583         RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
1584         s_query = (ctsvc_query_s*)query;
1585
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;
1590                                 break;
1591                         }
1592                 }
1593         } else {
1594                 s_query->projection_count = 0;
1595                 had_contact_id = true;
1596         }
1597
1598         if (false == had_contact_id) {
1599                 int *tmp = (int *)realloc(s_query->projection, sizeof(unsigned int)*(s_query->projection_count+1));
1600                 if (NULL == tmp) {
1601                         /* LCOV_EXCL_START */
1602                         ERR("realloc() Fail");
1603                         return CONTACTS_ERROR_OUT_OF_MEMORY;
1604                         /* LCOV_EXCL_STOP */
1605                 } else {
1606                         s_query->projection = tmp;
1607                 }
1608
1609                 s_query->projection[s_query->projection_count] = CTSVC_PROPERTY_CONTACT_ID;
1610                 s_query->projection_count++;
1611         }
1612
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);
1615
1616         contacts_list_create(&list);
1617         while ((ret = ctsvc_stmt_step(stmt))) {
1618                 contacts_record_h record;
1619                 if (1 != ret) {
1620                         /* LCOV_EXCL_START */
1621                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
1622                         ctsvc_stmt_finalize(stmt);
1623                         contacts_list_destroy(list, true);
1624                         return ret;
1625                         /* LCOV_EXCL_STOP */
1626                 }
1627
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;
1632                 } else {
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);
1636
1637                         if (CONTACTS_ERROR_NONE != ret)
1638                                 ASSERT_NOT_REACHED("To set projection is failed.\n");
1639                 }
1640
1641                 for (i = 0; i < field_count; i++) {
1642                         char *temp;
1643                         int property_id;
1644                         if (0 == s_query->projection_count)
1645                                 property_id = s_query->properties[i].property_id;
1646                         else
1647                                 property_id = s_query->projection[i];
1648
1649                         switch (property_id) {
1650                         case CTSVC_PROPERTY_CONTACT_ID:
1651                                 contact_id = ctsvc_stmt_get_int(stmt, i);
1652                                 if (had_contact_id)
1653                                         contact->id = contact_id;
1654                                 break;
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);
1659                                 break;
1660                         case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
1661                                 contact->display_source_type = ctsvc_stmt_get_int(stmt, i);
1662                                 break;
1663                         case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
1664                                 contact->addressbook_id = ctsvc_stmt_get_int(stmt, i);
1665                                 break;
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);
1670                                 break;
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);
1677                                 }
1678                                 break;
1679                         case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
1680                                 contact->is_favorite = ctsvc_stmt_get_int(stmt, i);
1681                                 break;
1682                         case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
1683                                 contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
1684                                 break;
1685                         case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
1686                                 contact->has_email = ctsvc_stmt_get_int(stmt, i);
1687                                 break;
1688                         case CTSVC_PROPERTY_CONTACT_PERSON_ID:
1689                                 contact->person_id = ctsvc_stmt_get_int(stmt, i);
1690                                 break;
1691                         case CTSVC_PROPERTY_CONTACT_UID:
1692                                 temp = ctsvc_stmt_get_text(stmt, i);
1693                                 free(contact->uid);
1694                                 contact->uid = SAFE_STRDUP(temp);
1695                                 break;
1696                         case CTSVC_PROPERTY_CONTACT_VIBRATION:
1697                                 temp = ctsvc_stmt_get_text(stmt, i);
1698                                 free(contact->vibration);
1699                                 contact->vibration = SAFE_STRDUP(temp);
1700                                 break;
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);
1705                                 break;
1706                         case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
1707                                 contact->changed_time = ctsvc_stmt_get_int(stmt, i);
1708                                 break;
1709                         case CTSVC_PROPERTY_CONTACT_LINK_MODE:
1710                                 contact->link_mode = ctsvc_stmt_get_int(stmt, i);
1711                                 break;
1712                         default:
1713                                 break;
1714                         }
1715                 }
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);
1723                         return ret;
1724                         /* LCOV_EXCL_STOP */
1725                 }
1726
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);
1733                         return ret;
1734                         /* LCOV_EXCL_STOP */
1735                 }
1736
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);
1743                         return ret;
1744                         /* LCOV_EXCL_STOP */
1745                 }
1746
1747                 ctsvc_list_prepend(list, record);
1748         }
1749         ctsvc_stmt_finalize(stmt);
1750         ctsvc_list_reverse(list);
1751
1752         *out_list = (contacts_list_h)list;
1753
1754         return CONTACTS_ERROR_NONE;
1755 }
1756
1757
1758 static int __ctsvc_contact_insert_data(ctsvc_contact_s *contact)
1759 {
1760         int ret;
1761
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);
1768                         return ret;
1769                         /* LCOV_EXCL_STOP */
1770                 }
1771         }
1772
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);
1779                         return ret;
1780                         /* LCOV_EXCL_STOP */
1781                 }
1782         }
1783
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);
1790                         return ret;
1791                         /* LCOV_EXCL_STOP */
1792                 }
1793         }
1794
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);
1801                         return ret;
1802                         /* LCOV_EXCL_STOP */
1803                 }
1804         }
1805
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);
1812                         return ret;
1813                         /* LCOV_EXCL_STOP */
1814                 }
1815         }
1816
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);
1823                         return ret;
1824                         /* LCOV_EXCL_STOP */
1825                 }
1826         }
1827
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);
1834                         return ret;
1835                         /* LCOV_EXCL_STOP */
1836                 }
1837         }
1838
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);
1845                         return ret;
1846                         /* LCOV_EXCL_STOP */
1847                 }
1848         }
1849
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);
1856                         return ret;
1857                         /* LCOV_EXCL_STOP */
1858                 }
1859         }
1860
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);
1867                         return ret;
1868                         /* LCOV_EXCL_STOP */
1869                 }
1870         }
1871
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);
1878                         return ret;
1879                         /* LCOV_EXCL_STOP */
1880                 }
1881         }
1882
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);
1889                         return ret;
1890                         /* LCOV_EXCL_STOP */
1891                 }
1892         }
1893
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);
1900                         return ret;
1901                         /* LCOV_EXCL_STOP */
1902                 }
1903         }
1904
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);
1911                         return ret;
1912                         /* LCOV_EXCL_STOP */
1913                 }
1914         }
1915
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);
1922                         return ret;
1923                         /* LCOV_EXCL_STOP */
1924                 }
1925         }
1926
1927         return CONTACTS_ERROR_NONE;
1928 }
1929
1930 static inline int __ctsvc_contact_insert_search_data(int contact_id, bool need_insert_lookup_data)
1931 {
1932         int ret;
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;
1939
1940         ret = ctsvc_begin_trans();
1941         RETVM_IF(ret, ret, "contacts_begin_trans() Fail(%d)", ret);
1942
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);
1948                 return ret;
1949                 /* LCOV_EXCL_STOP */
1950         }
1951
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);
1958                 return ret;
1959                 /* LCOV_EXCL_STOP */
1960         }
1961
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);
1968                 free(search_name);
1969                 return ret;
1970                 /* LCOV_EXCL_STOP */
1971         }
1972
1973         snprintf(query, sizeof(query),
1974                         "INSERT INTO %s(contact_id, name, number, data) "
1975                         "VALUES(%d, ?, ?, ?)",
1976                         CTS_TABLE_SEARCH_INDEX, contact_id);
1977
1978         ret = ctsvc_query_prepare(query, &stmt);
1979         if (NULL == 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);
1984                 free(search_name);
1985                 free(search_number);
1986                 free(search_data);
1987                 return ret;
1988                 /* LCOV_EXCL_STOP */
1989         }
1990
1991         if (search_name)
1992                 ctsvc_stmt_bind_text(stmt, 1, search_name);
1993         if (search_number)
1994                 ctsvc_stmt_bind_text(stmt, 2, search_number);
1995         if (search_data)
1996                 ctsvc_stmt_bind_text(stmt, 3, search_data);
1997
1998         ret = ctsvc_stmt_step(stmt);
1999
2000         free(search_name);
2001         free(search_number);
2002         free(search_data);
2003
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);
2010                 return ret;
2011                 /* LCOV_EXCL_STOP */
2012         }
2013         ctsvc_stmt_finalize(stmt);
2014
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);
2023                         return ret;
2024                         /* LCOV_EXCL_STOP */
2025                 }
2026         }
2027
2028         contacts_record_destroy((contacts_record_h)contact, true);
2029
2030         ret = ctsvc_end_trans(true);
2031         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
2032
2033         return CONTACTS_ERROR_NONE;
2034 }
2035
2036 static inline int __ctsvc_contact_insert_grouprel(int contact_id, contacts_list_h group_list)
2037 {
2038         CTS_FN_CALL;
2039         ctsvc_group_relation_s *grouprel;
2040         int rel_changed = 0;
2041         int count;
2042         int ret;
2043
2044         RETV_IF(NULL == group_list, CONTACTS_ERROR_INVALID_PARAMETER);
2045         ret = contacts_list_get_count(group_list, &count);
2046         if (0 == count)
2047                 return CONTACTS_ERROR_NONE;
2048
2049         contacts_list_first(group_list);
2050         do {
2051                 contacts_list_get_current_record_p(group_list, (contacts_record_h*)&grouprel);
2052                 if (NULL == grouprel)
2053                         continue;
2054
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);
2059                         if (0 < ret)
2060                                 rel_changed += ret;
2061                 }
2062         } while (CONTACTS_ERROR_NONE == contacts_list_next(group_list));
2063
2064         if (rel_changed)
2065                 return rel_changed;
2066         else
2067                 return CONTACTS_ERROR_NONE;
2068 }
2069
2070 static inline int __ctsvc_find_person_to_link_with_number(const char *number,
2071                 int addressbook_id, int *person_id)
2072 {
2073         int ret;
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];
2078
2079         ret = ctsvc_clean_number(number, clean_num, sizeof(clean_num), true);
2080         if (0 < ret) {
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];
2084                 if (0 < ret) {
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);
2087                 }
2088
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);
2097
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);
2103                 if (1 == ret) {
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;
2108                 }
2109                 ctsvc_stmt_finalize(stmt);
2110                 DBG("result ret(%d) person_id(%d)", ret, *person_id);
2111                 return ret;
2112         }
2113
2114         return CONTACTS_ERROR_INVALID_PARAMETER;
2115 }
2116
2117 static inline int __ctsvc_find_person_to_link_with_email(const char *email_addr, int addressbook_id, int *person_id)
2118 {
2119         int ret;
2120         cts_stmt stmt = NULL;
2121         char query[CTS_SQL_MIN_LEN] = {0};
2122
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);
2129
2130         ret = ctsvc_query_prepare(query, &stmt);
2131         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
2132
2133         ctsvc_stmt_bind_text(stmt, 1, email_addr);
2134         ret = ctsvc_stmt_step(stmt);
2135         if (1 == ret) {
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;
2140         }
2141
2142         ctsvc_stmt_finalize(stmt);
2143         DBG("result ret(%d) person_id(%d)", ret, *person_id);
2144
2145         return ret;
2146 }
2147
2148 static inline int __ctsvc_find_person_to_link(contacts_record_h record, int addressbook_id, int *person_id)
2149 {
2150         int ret;
2151         ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2152         ctsvc_number_s *number_data;
2153         ctsvc_email_s *email_data;
2154         GList *cursor;
2155
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);
2160
2161                         if (ret == CONTACTS_ERROR_NONE && 0 < *person_id)
2162                                 return ret;
2163                 }
2164         }
2165
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);
2170
2171                         if (ret == CONTACTS_ERROR_NONE && 0 < *person_id)
2172                                 return ret;
2173                 }
2174         }
2175
2176         return CONTACTS_ERROR_NO_DATA;
2177 }
2178
2179 static int __ctsvc_db_contact_insert_record(contacts_record_h record, int *id)
2180 {
2181         int version;
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;
2186
2187         ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2188         int rel_changed = 0;
2189         cts_stmt stmt = NULL;
2190
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);
2197
2198         if (contact->link_mode == CONTACTS_CONTACT_LINK_MODE_IGNORE_ONCE)
2199                 auto_link_enabled = false;
2200
2201         ret = ctsvc_begin_trans();
2202         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Fail(%d)", ret);
2203
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 */
2210         }
2211
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);
2217                 return ret;
2218                 /* LCOV_EXCL_STOP */
2219         }
2220         contact->id = ret;
2221         if (id)
2222                 *id = ret;
2223
2224         ctsvc_contact_make_display_name(contact);
2225         __ctsvc_contact_check_default_data(contact);
2226
2227         /* check lookup data is dirty */
2228         bool need_insert_lookup = __ctsvc_get_need_refresh_lookup_data(contact);
2229
2230         /* Insert Data */
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);
2236                 return ret;
2237                 /* LCOV_EXCL_STOP */
2238         }
2239
2240         /* thumbnail */
2241         free(contact->image_thumbnail_path);
2242         contact->image_thumbnail_path = NULL;
2243         if (contact->images) {
2244                 int count = 0;
2245                 ctsvc_image_s *image;
2246
2247                 contacts_list_get_count((contacts_list_h)contact->images, &count);
2248                 if (count) {
2249                         contacts_list_first((contacts_list_h)contact->images);
2250                         do {
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 */
2258                                 }
2259
2260                                 if (image->path && image->is_default) {
2261                                         contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
2262                                         break;
2263                                 }
2264                         } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
2265                 }
2266         }
2267
2268         version = ctsvc_get_next_ver();
2269
2270         if (contact->person_id) {
2271                 int id;
2272
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 */
2283                 }
2284
2285                 auto_linked = true;
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;
2291                         auto_linked = true;
2292                 } else {
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);
2299                                 return ret;
2300                                 /* LCOV_EXCL_STOP */
2301                         }
2302                         contact->person_id = ret;
2303                 }
2304         } else {
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);
2311                         return ret;
2312                         /* LCOV_EXCL_STOP */
2313                 }
2314                 contact->person_id = ret;
2315         }
2316
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);
2331
2332         ret = ctsvc_query_prepare(query, &stmt);
2333         if (NULL == stmt) {
2334                 /* LCOV_EXCL_START */
2335                 ERR("ctsvc_query_prepare() Fail(%d)", ret);
2336                 ctsvc_end_trans(false);
2337                 return ret;
2338                 /* LCOV_EXCL_STOP */
2339         }
2340
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);
2353         if (contact->uid)
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);
2363
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);
2370                 return ret;
2371                 /* LCOV_EXCL_STOP */
2372         }
2373         ctsvc_stmt_finalize(stmt);
2374
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);
2382                         return rel_changed;
2383                         /* LCOV_EXCL_STOP */
2384                 }
2385         }
2386
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);
2392                 return ret;
2393                 /* LCOV_EXCL_STOP */
2394         }
2395
2396         /* person aggregation when auto_linked */
2397         if (auto_linked)
2398                 ctsvc_person_aggregate(contact->person_id);
2399
2400 #ifdef ENABLE_LOG_FEATURE
2401         /* update phonelog */
2402         if (contact->numbers) {
2403                 int count;
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);
2408                         return ret;
2409                 }
2410                 contacts_list_first((contacts_list_h)contact->numbers);
2411                 if (0 < count) {
2412                         ctsvc_number_s *number_record;
2413                         do {
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));
2418                 }
2419         }
2420 #endif /* ENABLE_LOG_FEATURE */
2421         if (rel_changed)
2422                 ctsvc_set_group_rel_noti();
2423         ctsvc_set_contact_noti();
2424
2425         ret = ctsvc_end_trans(true);
2426         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_svc_end_trans() Fail(%d)", ret);
2427
2428         return CONTACTS_ERROR_NONE;
2429 }
2430
2431 static int __ctsvc_db_contact_replace_record(contacts_record_h record, int contact_id)
2432 {
2433         CTS_FN_CALL;
2434         int ret, len;
2435         int rel_changed = 0;
2436         int person_id;
2437         int addressbook_id;
2438         char query[CTS_SQL_MAX_LEN] = {0};
2439         ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
2440         cts_stmt stmt = NULL;
2441         int version;
2442
2443         ret = ctsvc_begin_trans();
2444         RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
2445
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);
2450         if (NULL == stmt) {
2451                 /* LCOV_EXCL_START */
2452                 ERR("ctsvc_query_prepare fail(%d)", ret);
2453                 ctsvc_end_trans(false);
2454                 return ret;
2455                 /* LCOV_EXCL_STOP */
2456         }
2457         ret = ctsvc_stmt_step(stmt);
2458         if (1 != ret) {
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;
2465                 else
2466                         return ret;
2467                 /* LCOV_EXCL_STOP */
2468         }
2469
2470         addressbook_id = ctsvc_stmt_get_int(stmt, 0);
2471         person_id = ctsvc_stmt_get_int(stmt, 1);
2472         ctsvc_stmt_finalize(stmt);
2473
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 */
2480         }
2481
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);
2486
2487         /* remove current child data */
2488         snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE contact_id = %d",
2489                         contact_id);
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);
2495                 return ret;
2496                 /* LCOV_EXCL_STOP */
2497         }
2498
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);
2504                 return ret;
2505                 /* LCOV_EXCL_STOP */
2506         }
2507
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);
2516                 return ret;
2517                 /* LCOV_EXCL_STOP */
2518         }
2519
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);
2527                         return rel_changed;
2528                         /* LCOV_EXCL_STOP */
2529                 }
2530         }
2531
2532         /* thumbnail */
2533         if (contact->images) {
2534                 int ret = CONTACTS_ERROR_NONE;
2535                 int count = 0;
2536                 ctsvc_image_s *image;
2537                 char *contact_image_path = NULL;
2538
2539                 contacts_list_get_count((contacts_list_h)contact->images, &count);
2540                 if (count) {
2541                         contacts_list_first((contacts_list_h)contact->images);
2542                         do {
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 */
2551                                 }
2552
2553                                 if (image->is_default)
2554                                         break;
2555                         } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->images));
2556
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);
2562
2563                                 if (image->path)
2564                                         contact->image_thumbnail_path = ctsvc_utils_make_thumbnail(image->path);
2565                         }
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);
2572                         } else {
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;
2576                                 }
2577                         }
2578                 }
2579         }
2580         version = ctsvc_get_next_ver();
2581
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);
2594
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);
2597
2598         len += snprintf(query+len, sizeof(query)-len, " WHERE contact_id=%d", contact->id);
2599
2600         ret = ctsvc_query_prepare(query, &stmt);
2601         if (NULL == stmt) {
2602                 /* LCOV_EXCL_START */
2603                 ERR("ctsvc_query_prepare() Fail(%d)", ret);
2604                 ctsvc_end_trans(false);
2605                 return ret;
2606                 /* LCOV_EXCL_STOP */
2607         }
2608
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);
2621         if (contact->uid)
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);
2631
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);
2638                 return ret;
2639                 /* LCOV_EXCL_STOP */
2640         }
2641         ctsvc_stmt_finalize(stmt);
2642
2643         ctsvc_set_contact_noti();
2644         if (0 < rel_changed)
2645                 ctsvc_set_group_rel_noti();
2646
2647         __ctsvc_contact_update_search_data(contact->id, true);
2648         ctsvc_db_update_person((contacts_record_h)contact);
2649
2650         ret = ctsvc_end_trans(true);
2651
2652         if (ret < CONTACTS_ERROR_NONE)
2653                 return ret;
2654         else
2655                 return CONTACTS_ERROR_NONE;
2656 }
2657
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,
2669         .get_count = NULL,
2670         .get_count_with_query = NULL,
2671         .replace_record = __ctsvc_db_contact_replace_record,
2672         .replace_records = NULL,
2673 };
2674