[SVACE Issue Fixes]
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_plugin_event.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_db_init.h"
25 #include "ctsvc_db_access_control.h"
26 #include "ctsvc_db_plugin_event_helper.h"
27 #include "ctsvc_db_plugin_contact_helper.h"
28 #include "ctsvc_record.h"
29 #include "ctsvc_db_query.h"
30 #include "ctsvc_list.h"
31 #include "ctsvc_notification.h"
32
33
34 static int __ctsvc_db_event_insert_record(contacts_record_h record, int *id)
35 {
36         int ret;
37         int addressbook_id;
38         char query[CTS_SQL_MAX_LEN] = {0};
39         ctsvc_event_s *event = (ctsvc_event_s*)record;
40
41         RETVM_IF(event->date <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
42                         "event date(%d)", event->date);
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", event->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", event->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_event_insert(record, event->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(event->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_event_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, data3, data4, data5 "
119                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
120                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
121                         "WHERE id = %d AND datatype = %d ",
122                         id, CONTACTS_DATA_TYPE_EVENT);
123
124         ret = ctsvc_query_prepare(query, &stmt);
125         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
126
127         ret = ctsvc_stmt_step(stmt);
128         if (1 /*CTS_TRUE*/ != ret) {
129                 /* LCOV_EXCL_START */
130                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
131                 ctsvc_stmt_finalize(stmt);
132                 if (CONTACTS_ERROR_NONE == ret)
133                         return CONTACTS_ERROR_NO_DATA;
134                 else
135                         return ret;
136                 /* LCOV_EXCL_STOP */
137         }
138
139         ctsvc_db_event_get_value_from_stmt(stmt, out_record, 0);
140
141         ctsvc_stmt_finalize(stmt);
142
143         return CONTACTS_ERROR_NONE;
144 }
145
146 static int __ctsvc_db_event_update_record(contacts_record_h record)
147 {
148         int ret;
149         int addressbook_id;
150         char query[CTS_SQL_MAX_LEN] = {0};
151         ctsvc_event_s *event = (ctsvc_event_s*)record;
152
153         ret = ctsvc_begin_trans();
154         if (CONTACTS_ERROR_NONE != ret) {
155                 /* LCOV_EXCL_START */
156                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
157                 return ret;
158                 /* LCOV_EXCL_STOP */
159         }
160
161         snprintf(query, sizeof(query),
162                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", event->contact_id);
163         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
164         if (CONTACTS_ERROR_NONE != ret) {
165                 /* LCOV_EXCL_START */
166                 ERR("No data : contact_id (%d) is not exist", event->contact_id);
167                 ctsvc_end_trans(false);
168                 return ret;
169                 /* LCOV_EXCL_STOP */
170         }
171
172         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
173                 /* LCOV_EXCL_START */
174                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
175                 ctsvc_end_trans(false);
176                 return CONTACTS_ERROR_PERMISSION_DENIED;
177                 /* LCOV_EXCL_STOP */
178         }
179
180         ret = ctsvc_db_event_update(record, false);
181         if (CONTACTS_ERROR_NONE != ret) {
182                 /* LCOV_EXCL_START */
183                 ERR("update record Fail(%d)", ret);
184                 ctsvc_end_trans(false);
185                 return ret;
186                 /* LCOV_EXCL_STOP */
187         }
188
189         /* TODO ; contact display event update */
190         ret = ctsvc_db_contact_update_changed_time(event->contact_id);
191         if (CONTACTS_ERROR_NONE != ret) {
192                 /* LCOV_EXCL_START */
193                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
194                 ctsvc_end_trans(false);
195                 return ret;
196                 /* LCOV_EXCL_STOP */
197         }
198         ctsvc_set_person_noti();
199
200         ret = ctsvc_end_trans(true);
201         if (ret < CONTACTS_ERROR_NONE) {
202                 /* LCOV_EXCL_START */
203                 ERR("ctsvc_end_trans() Fail(%d)", ret);
204                 return ret;
205                 /* LCOV_EXCL_STOP */
206         } else {
207                 return CONTACTS_ERROR_NONE;
208         }
209 }
210
211 static int __ctsvc_db_event_delete_record(int id)
212 {
213         int ret;
214         int contact_id;
215         char query[CTS_SQL_MAX_LEN] = {0};
216         cts_stmt stmt = NULL;
217         int addressbook_id;
218
219         ret = ctsvc_begin_trans();
220         if (CONTACTS_ERROR_NONE != ret) {
221                 /* LCOV_EXCL_START */
222                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
223                 return ret;
224                 /* LCOV_EXCL_STOP */
225         }
226
227         snprintf(query, sizeof(query),
228                         "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
229                         "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
230         ret = ctsvc_query_prepare(query, &stmt);
231         if (NULL == stmt) {
232                 /* LCOV_EXCL_START */
233                 ERR("ctsvc_query_prepare() Fail(%d)", ret);
234                 ctsvc_end_trans(false);
235                 return ret;
236                 /* LCOV_EXCL_STOP */
237         }
238         ret = ctsvc_stmt_step(stmt);
239         if (1 != ret) {
240                 /* LCOV_EXCL_START */
241                 ERR("The id(%d) is Invalid(%d)", id, ret);
242                 ctsvc_stmt_finalize(stmt);
243                 ctsvc_end_trans(false);
244                 if (CONTACTS_ERROR_NONE == ret)
245                         return CONTACTS_ERROR_NO_DATA;
246                 else
247                         return ret;
248                 /* LCOV_EXCL_STOP */
249         }
250
251         contact_id = ctsvc_stmt_get_int(stmt, 0);
252         addressbook_id = ctsvc_stmt_get_int(stmt, 1);
253         ctsvc_stmt_finalize(stmt);
254
255         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
256                 /* LCOV_EXCL_START */
257                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
258                 ctsvc_end_trans(false);
259                 return CONTACTS_ERROR_PERMISSION_DENIED;
260                 /* LCOV_EXCL_STOP */
261         }
262
263         ret = ctsvc_db_event_delete(id, false);
264         if (CONTACTS_ERROR_NONE != ret) {
265                 /* LCOV_EXCL_START */
266                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
267                 ctsvc_end_trans(false);
268                 return ret;
269                 /* LCOV_EXCL_STOP */
270         }
271
272         ret = ctsvc_db_contact_update_changed_time(contact_id);
273         if (CONTACTS_ERROR_NONE != ret) {
274                 /* LCOV_EXCL_START */
275                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
276                 ctsvc_end_trans(false);
277                 return ret;
278                 /* LCOV_EXCL_STOP */
279         }
280         ctsvc_set_person_noti();
281
282         ret = ctsvc_end_trans(true);
283         if (ret < CONTACTS_ERROR_NONE) {
284                 /* LCOV_EXCL_START */
285                 ERR("ctsvc_end_trans() Fail(%d)", ret);
286                 return ret;
287                 /* LCOV_EXCL_STOP */
288         } else {
289                 return CONTACTS_ERROR_NONE;
290         }
291 }
292
293 static int __ctsvc_db_event_get_all_records(int offset, int limit, contacts_list_h *out_list)
294 {
295         int len;
296         int ret;
297         contacts_list_h list;
298         ctsvc_event_s *event;
299         cts_stmt stmt = NULL;
300         char query[CTS_SQL_MAX_LEN] = {0};
301
302         len = snprintf(query, sizeof(query),
303                         "SELECT id, data.contact_id, is_default, data1, data2, data3, data4, data5 "
304                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
305                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
306                         "WHERE datatype = %d AND is_my_profile=0 ",
307                         CONTACTS_DATA_TYPE_EVENT);
308
309         if (0 != limit) {
310                 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
311                 if (0 < offset)
312                         len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
313         }
314
315         ret = ctsvc_query_prepare(query, &stmt);
316         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
317
318         contacts_list_create(&list);
319         while ((ret = ctsvc_stmt_step(stmt))) {
320                 if (1 /*CTS_TRUE */ != ret) {
321                         /* LCOV_EXCL_START */
322                         ERR("DB : ctsvc_stmt_step fail(%d)", ret);
323                         ctsvc_stmt_finalize(stmt);
324                         contacts_list_destroy(list, true);
325                         return ret;
326                         /* LCOV_EXCL_STOP */
327                 }
328                 ctsvc_db_event_get_value_from_stmt(stmt, (contacts_record_h*)&event, 0);
329                 ctsvc_list_prepend(list, (contacts_record_h)event);
330         }
331         ctsvc_stmt_finalize(stmt);
332         ctsvc_list_reverse(list);
333
334         *out_list = list;
335         return CONTACTS_ERROR_NONE;
336 }
337
338 static int __ctsvc_db_event_get_records_with_query(contacts_query_h query, int offset,
339                 int limit, contacts_list_h *out_list)
340 {
341         int ret;
342         int i;
343         int field_count;
344         ctsvc_query_s *s_query;
345         cts_stmt stmt;
346         contacts_list_h list;
347         ctsvc_event_s *event;
348
349         RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
350         s_query = (ctsvc_query_s*)query;
351
352         ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
353         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
354
355         contacts_list_create(&list);
356         while ((ret = ctsvc_stmt_step(stmt))) {
357                 contacts_record_h record;
358                 if (1 /*CTS_TRUE */ != ret) {
359                         /* LCOV_EXCL_START */
360                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
361                         ctsvc_stmt_finalize(stmt);
362                         contacts_list_destroy(list, true);
363                         return ret;
364                         /* LCOV_EXCL_STOP */
365                 }
366
367                 contacts_record_create(_contacts_event._uri, &record);
368                 event = (ctsvc_event_s*)record;
369                 if (0 == s_query->projection_count) {
370                         field_count = s_query->property_count;
371                 } else {
372                         field_count = s_query->projection_count;
373                         ret = ctsvc_record_set_projection_flags(record, s_query->projection,
374                                         s_query->projection_count, s_query->property_count);
375
376                         if (CONTACTS_ERROR_NONE != ret)
377                                 ASSERT_NOT_REACHED("To set projection is Fail.\n");
378                 }
379
380                 for (i = 0; i < field_count; i++) {
381                         char *temp;
382                         int property_id;
383                         if (0 == s_query->projection_count)
384                                 property_id = s_query->properties[i].property_id;
385                         else
386                                 property_id = s_query->projection[i];
387
388                         switch (property_id) {
389                         case CTSVC_PROPERTY_EVENT_ID:
390                                 event->id = ctsvc_stmt_get_int(stmt, i);
391                                 break;
392                         case CTSVC_PROPERTY_EVENT_CONTACT_ID:
393                                 event->contact_id = ctsvc_stmt_get_int(stmt, i);
394                                 break;
395                         case CTSVC_PROPERTY_EVENT_TYPE:
396                                 event->type = ctsvc_stmt_get_int(stmt, i);
397                                 break;
398                         case CTSVC_PROPERTY_EVENT_LABEL:
399                                 temp = ctsvc_stmt_get_text(stmt, i);
400                                 free(event->label);
401                                 event->label = SAFE_STRDUP(temp);
402                                 break;
403                         case CTSVC_PROPERTY_EVENT_DATE:
404                                 event->date = ctsvc_stmt_get_int(stmt, i);
405                                 break;
406                         case CTSVC_PROPERTY_EVENT_CALENDAR_TYPE:
407                                 event->calendar_type = ctsvc_stmt_get_int(stmt, i);
408                                 break;
409                         case CTSVC_PROPERTY_EVENT_IS_LEAP_MONTH:
410                                 event->is_leap_month = ctsvc_stmt_get_int(stmt, i);
411                                 break;
412                         default:
413                                 break;
414                         }
415                 }
416                 ctsvc_list_prepend(list, record);
417         }
418         ctsvc_stmt_finalize(stmt);
419         ctsvc_list_reverse(list);
420
421         *out_list = list;
422         return CONTACTS_ERROR_NONE;
423 }
424
425 ctsvc_db_plugin_info_s ctsvc_db_plugin_event = {
426         .is_query_only = false,
427         .insert_record = __ctsvc_db_event_insert_record,
428         .get_record = __ctsvc_db_event_get_record,
429         .update_record = __ctsvc_db_event_update_record,
430         .delete_record = __ctsvc_db_event_delete_record,
431         .get_all_records = __ctsvc_db_event_get_all_records,
432         .get_records_with_query = __ctsvc_db_event_get_records_with_query,
433         .insert_records = NULL,
434         .update_records = NULL,
435         .delete_records = NULL,
436         .get_count = NULL,
437         .get_count_with_query = NULL,
438         .replace_record = NULL,
439         .replace_records = NULL,
440 };
441