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