add comment LCOV_EXCL
[platform/core/pim/calendar-service.git] / server / db / cal_db_rrule.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 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 <stdlib.h>
21 #include "cal_internal.h"
22 #include "cal_typedef.h"
23 #include "cal_db_util.h"
24 #include "cal_db.h"
25 #include "cal_view.h"
26 #include "cal_time.h"
27 #include "cal_utils.h"
28
29 void cal_db_rrule_get_rrule_from_record(calendar_record_h record, cal_rrule_s **out_rrule)
30 {
31         RET_IF(NULL == record);
32
33         cal_rrule_s *rrule = NULL;
34         cal_record_s *rec = (cal_record_s *)record;
35         switch (rec->type) {
36         case CAL_RECORD_TYPE_EVENT:
37                 if (CALENDAR_RECURRENCE_NONE == ((cal_event_s *)record)->freq)
38                         break;
39                 rrule = calloc(1, sizeof(cal_rrule_s));
40                 if (NULL == rrule)
41                         break;
42                 rrule->freq = ((cal_event_s *)record)->freq;
43                 rrule->interval = ((cal_event_s *)record)->interval;
44                 rrule->bysecond = ((cal_event_s *)record)->bysecond;
45                 rrule->byminute = ((cal_event_s *)record)->byminute;
46                 rrule->byhour = ((cal_event_s *)record)->byhour;
47                 rrule->byday = ((cal_event_s *)record)->byday;
48                 rrule->bymonthday = ((cal_event_s *)record)->bymonthday;
49                 rrule->byyearday = ((cal_event_s *)record)->byyearday;
50                 rrule->byweekno = ((cal_event_s *)record)->byweekno;
51                 rrule->bymonth = ((cal_event_s *)record)->bymonth;
52                 rrule->bysetpos = ((cal_event_s *)record)->bysetpos;
53                 rrule->wkst = ((cal_event_s *)record)->wkst;
54                 rrule->range_type = ((cal_event_s *)record)->range_type;
55                 switch (rrule->range_type) {
56                 case CALENDAR_RANGE_UNTIL:
57                         rrule->until = ((cal_event_s *)record)->until;
58                         break;
59                 case CALENDAR_RANGE_COUNT:
60                         rrule->count = ((cal_event_s *)record)->count;
61                         break;
62                 case CALENDAR_RANGE_NONE:
63                         break;
64                 }
65                 break;
66         case CAL_RECORD_TYPE_TODO:
67                 if (CALENDAR_RECURRENCE_NONE == ((cal_todo_s *)record)->freq)
68                         break;
69                 rrule = calloc(1, sizeof(cal_rrule_s));
70                 if (NULL == rrule)
71                         break;
72                 rrule->freq = ((cal_todo_s *)record)->freq;
73                 rrule->interval = ((cal_todo_s *)record)->interval;
74                 rrule->bysecond = ((cal_todo_s *)record)->bysecond;
75                 rrule->byminute = ((cal_todo_s *)record)->byminute;
76                 rrule->byhour = ((cal_todo_s *)record)->byhour;
77                 rrule->byday = ((cal_todo_s *)record)->byday;
78                 rrule->bymonthday = ((cal_todo_s *)record)->bymonthday;
79                 rrule->byyearday = ((cal_todo_s *)record)->byyearday;
80                 rrule->byweekno = ((cal_todo_s *)record)->byweekno;
81                 rrule->bymonth = ((cal_todo_s *)record)->bymonth;
82                 rrule->bysetpos = ((cal_todo_s *)record)->bysetpos;
83                 rrule->wkst = ((cal_todo_s *)record)->wkst;
84                 rrule->range_type = ((cal_todo_s *)record)->range_type;
85                 switch (rrule->range_type) {
86                 case CALENDAR_RANGE_UNTIL:
87                         rrule->until = ((cal_todo_s *)record)->until;
88                         break;
89                 case CALENDAR_RANGE_COUNT:
90                         rrule->count = ((cal_todo_s *)record)->count;
91                         break;
92                 case CALENDAR_RANGE_NONE:
93                         break;
94                 }
95                 break;
96         default:
97                 break;
98         }
99         *out_rrule = rrule;
100 }
101
102 void cal_db_rrule_set_rrule_to_record(cal_rrule_s *rrule, calendar_record_h record)
103 {
104         RET_IF(NULL == rrule);
105         RET_IF(NULL == record);
106
107         cal_record_s *rec = (cal_record_s *)record;
108         switch (rec->type) {
109         case CAL_RECORD_TYPE_EVENT:
110                 ((cal_event_s *)record)->freq = rrule->freq;
111                 ((cal_event_s *)record)->range_type = rrule->range_type;
112                 ((cal_event_s *)record)->until = rrule->until;
113                 ((cal_event_s *)record)->count = rrule->count;
114                 ((cal_event_s *)record)->interval = rrule->interval;
115                 ((cal_event_s *)record)->bysecond = rrule->bysecond;
116                 ((cal_event_s *)record)->byminute = rrule->byminute;
117                 ((cal_event_s *)record)->byhour = rrule->byhour;
118                 ((cal_event_s *)record)->byday = rrule->byday;
119                 ((cal_event_s *)record)->bymonthday = rrule->bymonthday;
120                 ((cal_event_s *)record)->byyearday = rrule->byyearday;
121                 ((cal_event_s *)record)->byweekno = rrule->byweekno;
122                 ((cal_event_s *)record)->bymonth = rrule->bymonth;
123                 ((cal_event_s *)record)->bysetpos = rrule->bysetpos;
124                 ((cal_event_s *)record)->wkst = rrule->wkst;
125                 break;
126         case CAL_RECORD_TYPE_TODO:
127                 ((cal_todo_s *)record)->freq = rrule->freq;
128                 ((cal_todo_s *)record)->range_type = rrule->range_type;
129                 ((cal_todo_s *)record)->until = rrule->until;
130                 ((cal_todo_s *)record)->count = rrule->count;
131                 ((cal_todo_s *)record)->interval = rrule->interval;
132                 ((cal_todo_s *)record)->bysecond = rrule->bysecond;
133                 ((cal_todo_s *)record)->byminute = rrule->byminute;
134                 ((cal_todo_s *)record)->byhour = rrule->byhour;
135                 ((cal_todo_s *)record)->byday = rrule->byday;
136                 ((cal_todo_s *)record)->bymonthday = rrule->bymonthday;
137                 ((cal_todo_s *)record)->byyearday = rrule->byyearday;
138                 ((cal_todo_s *)record)->byweekno = rrule->byweekno;
139                 ((cal_todo_s *)record)->bymonth = rrule->bymonth;
140                 ((cal_todo_s *)record)->bysetpos = rrule->bysetpos;
141                 ((cal_todo_s *)record)->wkst = rrule->wkst;
142                 break;
143         default:
144                 break;
145         }
146 }
147
148 int _cal_db_rrule_insert_record(int id, cal_rrule_s *rrule)
149 {
150         RETV_IF(NULL == rrule, CALENDAR_ERROR_INVALID_PARAMETER);
151
152         int rrule_id;
153         int index;
154         char query[CAL_DB_SQL_MAX_LEN] = {0};
155         char until_datetime[CAL_STR_SHORT_LEN32] = {0};
156         sqlite3_stmt *stmt = NULL;
157         int ret = 0;
158
159         RETVM_IF(rrule == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
160                         "Invalid argument: rrule is NULL");
161
162         snprintf(query, sizeof(query),
163                         "INSERT INTO %s ("
164                         "event_id, freq, range_type, "
165                         "until_type, until_utime, until_datetime, "
166                         "count, interval, "
167                         "bysecond, byminute, byhour, byday, "
168                         "bymonthday, byyearday, byweekno, bymonth, "
169                         "bysetpos, wkst "
170                         ") VALUES ("
171                         "%d, %d, %d, "
172                         "%d, %lld, ?, "
173                         "%d, %d, "
174                         "?, ?, ?, ?, "
175                         "?, ?, ?, ?, "
176                         "?, %d "
177                         ") ",
178                         CAL_TABLE_RRULE,
179                         id, rrule->freq, rrule->range_type,
180                         rrule->until.type, rrule->until.time.utime,
181                         rrule->count, rrule->interval,
182                         rrule->wkst);
183
184         ret = cal_db_util_query_prepare(query, &stmt);
185         if (CALENDAR_ERROR_NONE != ret) {
186                 /* LCOV_EXCL_START */
187                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
188                 SECURE("query[%s]", query);
189                 return ret;
190                 /* LCOV_EXCL_STOP */
191         }
192
193         index = 1;
194
195         if (CALENDAR_TIME_LOCALTIME == rrule->until.type) {
196                 snprintf(until_datetime, sizeof(until_datetime), CAL_FORMAT_LOCAL_DATETIME,
197                                 rrule->until.time.date.year,
198                                 rrule->until.time.date.month,
199                                 rrule->until.time.date.mday,
200                                 rrule->until.time.date.hour,
201                                 rrule->until.time.date.minute,
202                                 rrule->until.time.date.second);
203                 cal_db_util_stmt_bind_text(stmt, index, until_datetime);
204         }
205         index++;
206
207         if (rrule->bysecond)
208                 cal_db_util_stmt_bind_text(stmt, index, rrule->bysecond);
209         index++;
210
211         if (rrule->byminute)
212                 cal_db_util_stmt_bind_text(stmt, index, rrule->byminute);
213         index++;
214
215         if (rrule->byhour)
216                 cal_db_util_stmt_bind_text(stmt, index, rrule->byhour);
217         index++;
218
219         if (rrule->byday)
220                 cal_db_util_stmt_bind_text(stmt, index, rrule->byday);
221         index++;
222
223         if (rrule->bymonthday)
224                 cal_db_util_stmt_bind_text(stmt, index, rrule->bymonthday);
225         index++;
226
227         if (rrule->byyearday)
228                 cal_db_util_stmt_bind_text(stmt, index, rrule->byyearday);
229         index++;
230
231         if (rrule->byweekno)
232                 cal_db_util_stmt_bind_text(stmt, index, rrule->byweekno);
233         index++;
234
235         if (rrule->bymonth)
236                 cal_db_util_stmt_bind_text(stmt, index, rrule->bymonth);
237         index++;
238
239         if (rrule->bysetpos)
240                 cal_db_util_stmt_bind_text(stmt, index, rrule->bysetpos);
241         index++;
242
243         ret = cal_db_util_stmt_step(stmt);
244         sqlite3_finalize(stmt);
245         if (CALENDAR_ERROR_NONE != ret) {
246                 /* LCOV_EXCL_START */
247                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
248                 return ret;
249                 /* LCOV_EXCL_STOP */
250         }
251
252         rrule_id = cal_db_util_last_insert_id();
253         DBG("rrule_id(%d)", rrule_id);
254         return CALENDAR_ERROR_NONE;
255 }
256
257 int cal_db_rrule_get_rrule(int id, cal_rrule_s **rrule)
258 {
259         char query[CAL_DB_SQL_MAX_LEN];
260         int index;
261         sqlite3_stmt *stmt = NULL;
262         cal_rrule_s *_rrule = NULL;
263         const unsigned char *temp;
264         int ret = 0;
265
266         snprintf(query, sizeof(query),
267                         "SELECT id, event_id, freq, range_type, until_type, until_utime, "
268                         "until_datetime, count, interval, bysecond, byminute, byhour, byday, "
269                         "bymonthday, byyearday, byweekno, bymonth, bysetpos, wkst "
270                         "FROM %s WHERE event_id = %d ",
271                         CAL_TABLE_RRULE, id);
272
273         ret = cal_db_util_query_prepare(query, &stmt);
274         if (CALENDAR_ERROR_NONE != ret) {
275                 /* LCOV_EXCL_START */
276                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
277                 SECURE("query[%s]", query);
278                 return ret;
279                 /* LCOV_EXCL_STOP */
280         }
281
282         ret = cal_db_util_stmt_step(stmt);
283         if (CAL_SQLITE_ROW != ret) {
284                 /* LCOV_EXCL_START */
285                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
286                 SECURE("query[%s]", query);
287                 sqlite3_finalize(stmt);
288                 return ret;
289                 /* LCOV_EXCL_STOP */
290         }
291
292         _rrule = calloc(1, sizeof(cal_rrule_s));
293         RETVM_IF(NULL == _rrule, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc() Fail");
294
295         index = 0;
296         sqlite3_column_int(stmt, index++); /* id */
297         sqlite3_column_int(stmt, index++); /* event_id */
298         _rrule->freq = sqlite3_column_int(stmt, index++);
299
300         _rrule->range_type = sqlite3_column_int(stmt, index++);
301         _rrule->until.type = sqlite3_column_int(stmt, index++);
302         _rrule->until.time.utime = sqlite3_column_int64(stmt, index++);
303
304         temp = sqlite3_column_text(stmt, index++);
305         if (temp) {
306                 if (CALENDAR_TIME_LOCALTIME == _rrule->until.type) {
307                         sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME,
308                                         &_rrule->until.time.date.year,
309                                         &_rrule->until.time.date.month,
310                                         &_rrule->until.time.date.mday,
311                                         &_rrule->until.time.date.hour,
312                                         &_rrule->until.time.date.minute,
313                                         &_rrule->until.time.date.second);
314                 }
315         }
316
317         _rrule->count = sqlite3_column_int(stmt, index++);
318         _rrule->interval = sqlite3_column_int(stmt, index++);
319
320         temp = sqlite3_column_text(stmt, index++);
321         _rrule->bysecond = cal_strdup((const char*)temp);
322
323         temp = sqlite3_column_text(stmt, index++);
324         _rrule->byminute = cal_strdup((const char*)temp);
325
326         temp = sqlite3_column_text(stmt, index++);
327         _rrule->byhour = cal_strdup((const char*)temp);
328
329         temp = sqlite3_column_text(stmt, index++);
330         _rrule->byday = cal_strdup((const char*)temp);
331
332         temp = sqlite3_column_text(stmt, index++);
333         _rrule->bymonthday = cal_strdup((const char*)temp);
334
335         temp = sqlite3_column_text(stmt, index++);
336         _rrule->byyearday = cal_strdup((const char*)temp);
337
338         temp = sqlite3_column_text(stmt, index++);
339         _rrule->byweekno = cal_strdup((const char*)temp);
340
341         temp = sqlite3_column_text(stmt, index++);
342         _rrule->bymonth = cal_strdup((const char*)temp);
343
344         temp = sqlite3_column_text(stmt, index++);
345         _rrule->bysetpos = cal_strdup((const char*)temp);
346
347         _rrule->wkst = sqlite3_column_int(stmt, index++);
348
349         sqlite3_finalize(stmt);
350
351         *rrule = _rrule;
352         return CALENDAR_ERROR_NONE;
353 }
354
355 static int _cal_db_rrule_delete_record(int id)
356 {
357         char query[CAL_DB_SQL_MAX_LEN] = {0};
358         int ret = 0;
359
360         snprintf(query, sizeof(query),
361                         "DELETE FROM %s WHERE event_id = %d ",
362                         CAL_TABLE_RRULE, id);
363
364         ret = cal_db_util_query_exec(query);
365         if (CALENDAR_ERROR_NONE != ret) {
366                 /* LCOV_EXCL_START */
367                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
368                 SECURE("[%s]", query);
369                 return ret;
370                 /* LCOV_EXCL_STOP */
371         }
372
373         return CALENDAR_ERROR_NONE;
374 }
375
376 static int _cal_db_rrule_has_record(int id, int *has_record)
377 {
378         int ret = CALENDAR_ERROR_NONE;
379         int count = 0;
380         char query[CAL_DB_SQL_MAX_LEN] = {0};
381
382         snprintf(query, sizeof(query),
383                         "SELECT count(*) FROM %s WHERE event_id = %d ",
384                         CAL_TABLE_RRULE, id);
385
386         ret = cal_db_util_query_get_first_int_result(query, NULL, &count);
387         if (CALENDAR_ERROR_NONE != ret) {
388                 /* LCOV_EXCL_START */
389                 ERR("cal_db_util_query_get_first_int_result() failed");
390                 return ret;
391                 /* LCOV_EXCL_STOP */
392         }
393
394         *has_record = 0 < count ? 1 : 0;
395         return CALENDAR_ERROR_NONE;
396 }
397
398 static int _cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
399 {
400         int ret = 0;
401         char query[CAL_DB_SQL_MAX_LEN] = {0};
402         char until_datetime[CAL_STR_SHORT_LEN32] = {0};
403         sqlite3_stmt *stmt = NULL;
404
405         snprintf(query, sizeof(query),
406                         "UPDATE %s SET "
407                         "freq = %d, "
408                         "range_type = %d, "
409                         "until_type = %d, "
410                         "until_utime = %lld, "
411                         "until_datetime = ?, "
412                         "count = %d, "
413                         "interval = %d, "
414                         "bysecond = ?, "
415                         "byminute= ?, "
416                         "byhour = ?, "
417                         "byday = ?, "
418                         "bymonthday = ?, "
419                         "byyearday = ?, "
420                         "byweekno = ?, "
421                         "bymonth = ?, "
422                         "bysetpos = ?, "
423                         "wkst = %d "
424                         "WHERE event_id = %d ",
425                         CAL_TABLE_RRULE,
426                         rrule->freq,
427                         rrule->range_type,
428                         rrule->until.type,
429                         rrule->until.time.utime,
430                         rrule->count,
431                         rrule->interval,
432                         rrule->wkst,
433                         id);
434
435         ret = cal_db_util_query_prepare(query, &stmt);
436         if (CALENDAR_ERROR_NONE != ret) {
437                 /* LCOV_EXCL_START */
438                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
439                 SECURE("query[%s]", query);
440                 return ret;
441                 /* LCOV_EXCL_STOP */
442         }
443
444         int index = 1;
445         if (CALENDAR_TIME_LOCALTIME == rrule->until.type) {
446                 snprintf(until_datetime, sizeof(until_datetime), CAL_FORMAT_LOCAL_DATETIME,
447                                 rrule->until.time.date.year,
448                                 rrule->until.time.date.month,
449                                 rrule->until.time.date.mday,
450                                 rrule->until.time.date.hour,
451                                 rrule->until.time.date.minute,
452                                 rrule->until.time.date.second);
453                 cal_db_util_stmt_bind_text(stmt, index, until_datetime);
454         }
455         index++;
456
457         if (rrule->bysecond)
458                 cal_db_util_stmt_bind_text(stmt, index, rrule->bysecond);
459         index++;
460
461         if (rrule->byminute)
462                 cal_db_util_stmt_bind_text(stmt, index, rrule->byminute);
463         index++;
464
465         if (rrule->byhour)
466                 cal_db_util_stmt_bind_text(stmt, index, rrule->byhour);
467         index++;
468
469         if (rrule->byday)
470                 cal_db_util_stmt_bind_text(stmt, index, rrule->byday);
471         index++;
472
473         if (rrule->bymonthday)
474                 cal_db_util_stmt_bind_text(stmt, index, rrule->bymonthday);
475         index++;
476
477         if (rrule->byyearday)
478                 cal_db_util_stmt_bind_text(stmt, index, rrule->byyearday);
479         index++;
480
481         if (rrule->byweekno)
482                 cal_db_util_stmt_bind_text(stmt, index, rrule->byweekno);
483         index++;
484
485         if (rrule->bymonth)
486                 cal_db_util_stmt_bind_text(stmt, index, rrule->bymonth);
487         index++;
488
489         if (rrule->bysetpos)
490                 cal_db_util_stmt_bind_text(stmt, index, rrule->bysetpos);
491         index++;
492
493         ret = cal_db_util_stmt_step(stmt);
494         sqlite3_finalize(stmt);
495         if (CALENDAR_ERROR_NONE != ret) {
496                 /* LCOV_EXCL_START */
497                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
498                 return ret;
499                 /* LCOV_EXCL_STOP */
500         }
501
502         return CALENDAR_ERROR_NONE;
503 }
504
505 int cal_db_rrule_insert_record(int id, cal_rrule_s *rrule)
506 {
507         RETVM_IF(NULL == rrule, CALENDAR_ERROR_INVALID_PARAMETER,
508                         "Invalid argument: rrule is NULL");
509
510         if (CALENDAR_RECURRENCE_NONE != rrule->freq)
511                 _cal_db_rrule_insert_record(id, rrule);
512
513         return CALENDAR_ERROR_NONE;
514 }
515
516 int cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
517 {
518         int has_record = 0;
519
520         if (NULL == rrule || rrule->freq == CALENDAR_RECURRENCE_NONE) {
521                 DBG("freq is NONE");
522                 _cal_db_rrule_delete_record(id);
523                 return CALENDAR_ERROR_NONE;
524         } else {
525                 _cal_db_rrule_has_record(id, &has_record);
526                 if (has_record)
527                         _cal_db_rrule_update_record(id, rrule);
528                 else
529                         _cal_db_rrule_insert_record(id, rrule);
530         }
531         return CALENDAR_ERROR_NONE;
532 }
533