[SVACE Issue Fixes]
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_plugin_name.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 "contacts.h"
20 #include "ctsvc_internal.h"
21 #include "ctsvc_db_schema.h"
22 #include "ctsvc_db_sqlite.h"
23 #include "ctsvc_db_utils.h"
24 #include "ctsvc_normalize.h"
25 #include "ctsvc_db_init.h"
26 #include "ctsvc_db_query.h"
27 #include "ctsvc_db_access_control.h"
28 #include "ctsvc_db_plugin_contact_helper.h"
29 #include "ctsvc_db_plugin_name_helper.h"
30 #include "ctsvc_record.h"
31 #include "ctsvc_list.h"
32 #include "ctsvc_notification.h"
33
34
35 static int __ctsvc_db_name_insert_record(contacts_record_h record, int *id)
36 {
37         int ret;
38         int name_id = 0;
39         int addressbook_id;
40         char query[CTS_SQL_MAX_LEN] = {0};
41         ctsvc_name_s *name = (ctsvc_name_s*)record;
42
43         ret = ctsvc_begin_trans();
44         if (CONTACTS_ERROR_NONE != ret) {
45                 /* LCOV_EXCL_START */
46                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
47                 return ret;
48                 /* LCOV_EXCL_STOP */
49         }
50
51         snprintf(query, sizeof(query),
52                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id);
53         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
54         if (CONTACTS_ERROR_NONE != ret) {
55                 ctsvc_end_trans(false);
56                 if (CONTACTS_ERROR_NO_DATA == ret) {
57                         /* LCOV_EXCL_START */
58                         ERR("No data : contact_id (%d) is not exist", name->contact_id);
59                         return CONTACTS_ERROR_INVALID_PARAMETER;
60                         /* LCOV_EXCL_STOP */
61                 } else {
62                         /* LCOV_EXCL_START */
63                         ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
64                         return ret;
65                         /* LCOV_EXCL_STOP */
66                 }
67         }
68
69         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
70                 /* LCOV_EXCL_START */
71                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
72                 ctsvc_end_trans(false);
73                 return CONTACTS_ERROR_PERMISSION_DENIED;
74                 /* LCOV_EXCL_STOP */
75         }
76
77         snprintf(query, sizeof(query),
78                         "SELECT id FROM "CTS_TABLE_DATA" WHERE contact_id = %d AND datatype=%d", name->contact_id, CONTACTS_DATA_TYPE_NAME);
79         ret = ctsvc_query_get_first_int_result(query, &name_id);
80         if (name_id) {
81                 /* LCOV_EXCL_START */
82                 ERR("name_id (%d) is exist", name_id);
83                 ctsvc_end_trans(false);
84                 return CONTACTS_ERROR_INVALID_PARAMETER;
85                 /* LCOV_EXCL_STOP */
86         }
87
88         ret = ctsvc_db_name_insert(record, name->contact_id, false, id);
89         if (CONTACTS_ERROR_NONE != ret) {
90                 /* LCOV_EXCL_START */
91                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
92                 ctsvc_end_trans(false);
93                 return ret;
94                 /* LCOV_EXCL_STOP */
95         }
96
97         ctsvc_contact_update_display_name(name->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
98
99         ret = ctsvc_db_contact_update_changed_time(name->contact_id);
100         if (CONTACTS_ERROR_NONE != ret) {
101                 /* LCOV_EXCL_START */
102                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
103                 ctsvc_end_trans(false);
104                 return ret;
105                 /* LCOV_EXCL_STOP */
106         }
107         ctsvc_set_person_noti();
108
109         ret = ctsvc_end_trans(true);
110         if (ret < CONTACTS_ERROR_NONE) {
111                 /* LCOV_EXCL_START */
112                 ERR("ctsvc_end_trans() Fail(%d)", ret);
113                 return ret;
114                 /* LCOV_EXCL_STOP */
115         } else {
116                 return CONTACTS_ERROR_NONE;
117         }
118 }
119
120 static int __ctsvc_db_name_get_record(int id, contacts_record_h *out_record)
121 {
122         int ret;
123         cts_stmt stmt = NULL;
124         char query[CTS_SQL_MAX_LEN] = {0};
125
126         RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
127         *out_record = NULL;
128
129         snprintf(query, sizeof(query),
130                         "SELECT id, data.contact_id, is_default, data1, data2, "
131                         "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
132                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
133                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
134                         "WHERE id = %d AND datatype = %d ",
135                         id, CONTACTS_DATA_TYPE_NAME);
136
137         ret = ctsvc_query_prepare(query, &stmt);
138         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
139
140         ret = ctsvc_stmt_step(stmt);
141         if (1 /*CTS_TRUE*/ != ret) {
142                 /* LCOV_EXCL_START */
143                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
144                 ctsvc_stmt_finalize(stmt);
145                 if (CONTACTS_ERROR_NONE == ret)
146                         return CONTACTS_ERROR_NO_DATA;
147                 else
148                         return ret;
149                 /* LCOV_EXCL_STOP */
150         }
151
152         ctsvc_db_name_get_value_from_stmt(stmt, out_record, 0);
153         ctsvc_stmt_finalize(stmt);
154
155         return CONTACTS_ERROR_NONE;
156 }
157
158 static int __ctsvc_db_name_update_record(contacts_record_h record)
159 {
160         int ret;
161         int addressbook_id;
162         char query[CTS_SQL_MAX_LEN] = {0};
163         ctsvc_name_s *name = (ctsvc_name_s*)record;
164
165         RETVM_IF(NULL == name->first && NULL == name->last && NULL == name->addition &&
166                         NULL == name->prefix && NULL == name->suffix && NULL == name->phonetic_first &&
167                         NULL == name->phonetic_middle && NULL == name->phonetic_last, CONTACTS_ERROR_INVALID_PARAMETER, "name is empty");
168
169         ret = ctsvc_begin_trans();
170         if (CONTACTS_ERROR_NONE != ret) {
171                 /* LCOV_EXCL_START */
172                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
173                 return ret;
174                 /* LCOV_EXCL_STOP */
175         }
176
177         snprintf(query, sizeof(query),
178                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id);
179         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
180         if (CONTACTS_ERROR_NONE != ret) {
181                 /* LCOV_EXCL_START */
182                 ERR("No data : contact_id (%d) is not exist", name->contact_id);
183                 ctsvc_end_trans(false);
184                 return ret;
185                 /* LCOV_EXCL_STOP */
186         }
187
188         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
189                 /* LCOV_EXCL_START */
190                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
191                 ctsvc_end_trans(false);
192                 return CONTACTS_ERROR_PERMISSION_DENIED;
193                 /* LCOV_EXCL_STOP */
194         }
195
196         ret = ctsvc_db_name_update(record, false);
197         if (CONTACTS_ERROR_NONE != ret) {
198                 /* LCOV_EXCL_START */
199                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
200                 ctsvc_end_trans(false);
201                 return ret;
202                 /* LCOV_EXCL_STOP */
203         }
204
205         ctsvc_contact_update_display_name(name->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
206
207         ret = ctsvc_db_contact_update_changed_time(name->contact_id);
208         if (CONTACTS_ERROR_NONE != ret) {
209                 /* LCOV_EXCL_START */
210                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
211                 ctsvc_end_trans(false);
212                 return ret;
213                 /* LCOV_EXCL_STOP */
214         }
215         ctsvc_set_person_noti();
216
217         ret = ctsvc_end_trans(true);
218         if (ret < CONTACTS_ERROR_NONE) {
219                 /* LCOV_EXCL_START */
220                 ERR("ctsvc_end_trans() Fail(%d)", ret);
221                 return ret;
222                 /* LCOV_EXCL_STOP */
223         } else {
224                 return CONTACTS_ERROR_NONE;
225         }
226 }
227
228
229 static int __ctsvc_db_name_delete_record(int id)
230 {
231         int ret;
232         int contact_id;
233         int addressbook_id;
234         cts_stmt stmt = NULL;
235         char query[CTS_SQL_MAX_LEN] = {0};
236
237         ret = ctsvc_begin_trans();
238         if (CONTACTS_ERROR_NONE != ret) {
239                 /* LCOV_EXCL_START */
240                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
241                 return ret;
242                 /* LCOV_EXCL_STOP */
243         }
244
245         snprintf(query, sizeof(query),
246                         "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
247                         "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
248         ret = ctsvc_query_prepare(query, &stmt);
249         if (NULL == stmt) {
250                 /* LCOV_EXCL_START */
251                 ERR("ctsvc_query_prepare Fail(%d)", ret);
252                 ctsvc_end_trans(false);
253                 return ret;
254                 /* LCOV_EXCL_STOP */
255         }
256         ret = ctsvc_stmt_step(stmt);
257         if (1 != ret) {
258                 /* LCOV_EXCL_START */
259                 ERR("The id(%d) is Invalid(%d)", id, ret);
260                 ctsvc_stmt_finalize(stmt);
261                 ctsvc_end_trans(false);
262                 if (CONTACTS_ERROR_NONE == ret)
263                         return CONTACTS_ERROR_NO_DATA;
264                 else
265                         return ret;
266                 /* LCOV_EXCL_STOP */
267         }
268
269         contact_id = ctsvc_stmt_get_int(stmt, 0);
270         addressbook_id = ctsvc_stmt_get_int(stmt, 1);
271         ctsvc_stmt_finalize(stmt);
272
273         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
274                 /* LCOV_EXCL_START */
275                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
276                 ctsvc_end_trans(false);
277                 return CONTACTS_ERROR_PERMISSION_DENIED;
278                 /* LCOV_EXCL_STOP */
279         }
280
281         ret = ctsvc_db_name_delete(id, false);
282         if (CONTACTS_ERROR_NONE != ret) {
283                 /* LCOV_EXCL_START */
284                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
285                 ctsvc_end_trans(false);
286                 return ret;
287                 /* LCOV_EXCL_STOP */
288         }
289
290         ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
291
292         ret = ctsvc_db_contact_update_changed_time(contact_id);
293         if (CONTACTS_ERROR_NONE != ret) {
294                 /* LCOV_EXCL_START */
295                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
296                 ctsvc_end_trans(false);
297                 return ret;
298                 /* LCOV_EXCL_STOP */
299         }
300         ctsvc_set_person_noti();
301
302         ret = ctsvc_end_trans(true);
303         if (ret < CONTACTS_ERROR_NONE) {
304                 /* LCOV_EXCL_START */
305                 ERR("ctsvc_end_trans() Fail(%d)", ret);
306                 return ret;
307                 /* LCOV_EXCL_STOP */
308         } else {
309                 return CONTACTS_ERROR_NONE;
310         }
311 }
312
313 static int __ctsvc_db_name_get_all_records(int offset, int limit, contacts_list_h *out_list)
314 {
315         int len;
316         int ret;
317         contacts_list_h list;
318         ctsvc_name_s *name;
319         cts_stmt stmt = NULL;
320         char query[CTS_SQL_MAX_LEN] = {0};
321
322         len = snprintf(query, sizeof(query),
323                         "SELECT id, data.contact_id, is_default, data1, data2, "
324                         "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
325                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
326                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
327                         "WHERE datatype = %d AND is_my_profile=0 ",
328                         CONTACTS_DATA_TYPE_NAME);
329
330         if (0 != limit) {
331                 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
332                 if (0 < offset)
333                         len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
334         }
335
336         ret = ctsvc_query_prepare(query, &stmt);
337         RETVM_IF(NULL == stmt, ret, "   ctsvc_query_prepare() Fail(%d)", ret);
338
339         contacts_list_create(&list);
340         while ((ret = ctsvc_stmt_step(stmt))) {
341                 if (1 != ret) {
342                         /* LCOV_EXCL_START */
343                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
344                         ctsvc_stmt_finalize(stmt);
345                         contacts_list_destroy(list, true);
346                         return ret;
347                         /* LCOV_EXCL_STOP */
348                 }
349                 ctsvc_db_name_get_value_from_stmt(stmt, (contacts_record_h*)&name, 0);
350                 ctsvc_list_prepend(list, (contacts_record_h)name);
351         }
352
353         ctsvc_stmt_finalize(stmt);
354         ctsvc_list_reverse(list);
355
356         *out_list = list;
357         return CONTACTS_ERROR_NONE;
358 }
359
360 static int __ctsvc_db_name_get_records_with_query(contacts_query_h query, int offset,
361                 int limit, contacts_list_h *out_list)
362 {
363         int ret;
364         int i;
365         int field_count;
366         ctsvc_query_s *s_query;
367         cts_stmt stmt;
368         contacts_list_h list;
369         ctsvc_name_s *name;
370
371         RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
372         s_query = (ctsvc_query_s*)query;
373
374         ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
375         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
376
377         contacts_list_create(&list);
378         while ((ret = ctsvc_stmt_step(stmt))) {
379                 contacts_record_h record;
380                 if (1 != ret) {
381                         /* LCOV_EXCL_START */
382                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
383                         ctsvc_stmt_finalize(stmt);
384                         contacts_list_destroy(list, true);
385                         return ret;
386                         /* LCOV_EXCL_STOP */
387                 }
388
389                 contacts_record_create(_contacts_name._uri, &record);
390                 name = (ctsvc_name_s*)record;
391                 if (0 == s_query->projection_count) {
392                         field_count = s_query->property_count;
393                 } else {
394                         field_count = s_query->projection_count;
395                         ret = ctsvc_record_set_projection_flags(record, s_query->projection,
396                                         s_query->projection_count, s_query->property_count);
397
398                         if (CONTACTS_ERROR_NONE !=  ret)
399                                 ASSERT_NOT_REACHED("To set projection is Fail.\n");
400                 }
401
402                 for (i = 0; i < field_count; i++) {
403                         char *temp;
404                         int property_id;
405                         if (0 == s_query->projection_count)
406                                 property_id = s_query->properties[i].property_id;
407                         else
408                                 property_id = s_query->projection[i];
409
410                         switch (property_id) {
411                         case CTSVC_PROPERTY_NAME_ID:
412                                 name->id = ctsvc_stmt_get_int(stmt, i);
413                                 break;
414                         case CTSVC_PROPERTY_NAME_CONTACT_ID:
415                                 name->contact_id = ctsvc_stmt_get_int(stmt, i);
416                                 break;
417                         case CTSVC_PROPERTY_NAME_FIRST:
418                                 temp = ctsvc_stmt_get_text(stmt, i);
419                                 free(name->first);
420                                 name->first = SAFE_STRDUP(temp);
421                                 break;
422                         case CTSVC_PROPERTY_NAME_LAST:
423                                 temp = ctsvc_stmt_get_text(stmt, i);
424                                 free(name->last);
425                                 name->last = SAFE_STRDUP(temp);
426                                 break;
427                         case CTSVC_PROPERTY_NAME_ADDITION:
428                                 temp = ctsvc_stmt_get_text(stmt, i);
429                                 free(name->addition);
430                                 name->addition = SAFE_STRDUP(temp);
431                                 break;
432                         case CTSVC_PROPERTY_NAME_SUFFIX:
433                                 temp = ctsvc_stmt_get_text(stmt, i);
434                                 free(name->suffix);
435                                 name->suffix = SAFE_STRDUP(temp);
436                                 break;
437                         case CTSVC_PROPERTY_NAME_PREFIX:
438                                 temp = ctsvc_stmt_get_text(stmt, i);
439                                 free(name->prefix);
440                                 name->prefix = SAFE_STRDUP(temp);
441                                 break;
442                         case CTSVC_PROPERTY_NAME_PHONETIC_FIRST:
443                                 temp = ctsvc_stmt_get_text(stmt, i);
444                                 free(name->phonetic_first);
445                                 name->phonetic_first = SAFE_STRDUP(temp);
446                                 break;
447                         case CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE:
448                                 temp = ctsvc_stmt_get_text(stmt, i);
449                                 free(name->phonetic_middle);
450                                 name->phonetic_middle = SAFE_STRDUP(temp);
451                                 break;
452                         case CTSVC_PROPERTY_NAME_PHONETIC_LAST:
453                                 temp = ctsvc_stmt_get_text(stmt, i);
454                                 free(name->phonetic_last);
455                                 name->phonetic_last = SAFE_STRDUP(temp);
456                                 break;
457                         default:
458                                 break;
459                         }
460                 }
461                 ctsvc_list_prepend(list, record);
462         }
463         ctsvc_stmt_finalize(stmt);
464         ctsvc_list_reverse(list);
465
466         *out_list = list;
467         return CONTACTS_ERROR_NONE;
468 }
469
470 ctsvc_db_plugin_info_s ctsvc_db_plugin_name = {
471         .is_query_only = false,
472         .insert_record = __ctsvc_db_name_insert_record,
473         .get_record = __ctsvc_db_name_get_record,
474         .update_record = __ctsvc_db_name_update_record,
475         .delete_record = __ctsvc_db_name_delete_record,
476         .get_all_records = __ctsvc_db_name_get_all_records,
477         .get_records_with_query = __ctsvc_db_name_get_records_with_query,
478         .insert_records = NULL,
479         .update_records = NULL,
480         .delete_records = NULL,
481         .get_count = NULL,
482         .get_count_with_query = NULL,
483         .replace_record = NULL,
484         .replace_records = NULL,
485 };
486