c2a8251d9eeb64349cdda54edf62b01640388a1d
[platform/core/pim/calendar-service.git] / server / db / cal_db_plugin_alarm.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
22 #include "calendar_db.h"
23
24 #include "cal_internal.h"
25 #include "cal_typedef.h"
26 #include "cal_view.h"
27 #include "cal_time.h"
28 #include "cal_record.h"
29
30 #include "cal_db_util.h"
31 #include "cal_db.h"
32 #include "cal_db_query.h"
33 #include "cal_db_instance.h"
34 #include "cal_db_plugin_alarm_helper.h"
35 #include "cal_utils.h"
36
37 /* static int _cal_db_alarm_get_record(int id, calendar_record_h* out_record); */
38 static int _cal_db_alarm_get_all_records(int offset, int limit, calendar_list_h *out_list);
39 static int _cal_db_alarm_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
40 static int _cal_db_alarm_get_count(int *out_count);
41 static int _cal_db_alarm_get_count_with_query(calendar_query_h query, int *out_count);
42
43 cal_db_plugin_cb_s cal_db_alarm_plugin_cb = {
44         .is_query_only =  false,
45         .insert_record = NULL,
46         .update_record = NULL,
47         .delete_record = NULL,
48         .replace_record = NULL,
49         .insert_records = NULL,
50         .update_records = NULL,
51         .delete_records = NULL,
52         .replace_records = NULL,
53         .get_record = NULL,
54         .get_all_records = _cal_db_alarm_get_all_records,
55         .get_records_with_query = _cal_db_alarm_get_records_with_query,
56         .get_count = _cal_db_alarm_get_count,
57         .get_count_with_query = _cal_db_alarm_get_count_with_query
58 };
59
60 static void _cal_db_alarm_get_stmt(sqlite3_stmt *stmt, calendar_record_h record)
61 {
62         cal_alarm_s *alarm = NULL;
63         int index;
64         const unsigned char *temp;
65
66         alarm = (cal_alarm_s*)(record);
67
68         index = 0;
69         alarm->parent_id = sqlite3_column_int(stmt, index++);
70         alarm->remind_tick = sqlite3_column_int(stmt, index++);
71         alarm->remind_tick_unit = sqlite3_column_int(stmt, index++);
72
73         temp = sqlite3_column_text(stmt, index++);
74         alarm->alarm_description = cal_strdup((const char*)temp);
75
76         alarm->alarm.type = sqlite3_column_int(stmt, index++);
77         index++; /* alarm_id */
78         temp = sqlite3_column_text(stmt, index++);
79         alarm->alarm_summary = cal_strdup((const char*)temp);
80
81         alarm->alarm_action = sqlite3_column_int(stmt, index++);
82
83         temp = sqlite3_column_text(stmt, index++);
84         alarm->alarm_attach = cal_strdup((const char*)temp);
85
86         if (alarm->alarm.type == CALENDAR_TIME_UTIME) {
87                 alarm->alarm.time.utime = sqlite3_column_int64(stmt, index++);
88                 index++; /* datetime */
89         } else {
90                 index++; /* utime */
91                 temp = sqlite3_column_text(stmt, index++);
92                 if (temp) {
93                         int y = 0, m = 0, d = 0;
94                         int h = 0, n = 0, s = 0;
95                         switch (strlen((const char *)temp)) {
96                         case 8:
97                                 sscanf((const char *)temp, CAL_DATETIME_FORMAT_YYYYMMDD, &y, &m, &d);
98                                 alarm->alarm.time.date.year = y;
99                                 alarm->alarm.time.date.month = m;
100                                 alarm->alarm.time.date.mday = d;
101                                 break;
102
103                         case 15:
104                                 sscanf((const char *)temp, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS, &y, &m, &d, &h, &n, &s);
105                                 alarm->alarm.time.date.year = y;
106                                 alarm->alarm.time.date.month = m;
107                                 alarm->alarm.time.date.mday = d;
108                                 alarm->alarm.time.date.hour = h;
109                                 alarm->alarm.time.date.minute = n;
110                                 alarm->alarm.time.date.second = s;
111                                 break;
112                         }
113                 }
114         }
115         alarm->id = sqlite3_column_int(stmt, index++);
116 }
117
118 static int _cal_db_alarm_get_all_records(int offset, int limit, calendar_list_h* out_list)
119 {
120         int ret = CALENDAR_ERROR_NONE;
121         char query[CAL_DB_SQL_MAX_LEN] = {0};
122         char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
123         char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
124         sqlite3_stmt *stmt = NULL;
125
126         RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
127
128         ret = calendar_list_create(out_list);
129         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
130
131         if (0 < offset)
132                 snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
133
134         if (0 < limit)
135                 snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
136
137         snprintf(query, sizeof(query), "SELECT *, rowid FROM %s %s %s",
138                         CAL_TABLE_ALARM, limitquery, offsetquery);
139
140         ret = cal_db_util_query_prepare(query, &stmt);
141         if (CALENDAR_ERROR_NONE != ret) {
142                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
143                 SECURE("query[%s]", query);
144                 calendar_list_destroy(*out_list, true);
145                 *out_list = NULL;
146                 return ret;
147         }
148
149         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
150                 calendar_record_h record = NULL;
151                 ret = calendar_record_create(_calendar_alarm._uri, &record);
152                 if (CALENDAR_ERROR_NONE != ret) {
153                         calendar_list_destroy(*out_list, true);
154                         *out_list = NULL;
155                         sqlite3_finalize(stmt);
156                         return ret;
157                 }
158                 _cal_db_alarm_get_stmt(stmt, record);
159
160                 ret = calendar_list_add(*out_list, record);
161                 if (CALENDAR_ERROR_NONE != ret) {
162                         calendar_list_destroy(*out_list, true);
163                         *out_list = NULL;
164                         calendar_record_destroy(record, true);
165                         sqlite3_finalize(stmt);
166                         return ret;
167                 }
168         }
169         sqlite3_finalize(stmt);
170
171         return CALENDAR_ERROR_NONE;
172 }
173
174 static void _cal_db_alarm_get_property_stmt(sqlite3_stmt *stmt,
175                 unsigned int property, int *stmt_count, calendar_record_h record)
176 {
177         cal_alarm_s *alarm = NULL;
178         const unsigned char *temp;
179
180         alarm = (cal_alarm_s*)(record);
181
182         switch (property) {
183         case CAL_PROPERTY_ALARM_TICK:
184                 alarm->remind_tick = sqlite3_column_int(stmt, *stmt_count);
185                 break;
186         case CAL_PROPERTY_ALARM_TICK_UNIT:
187                 alarm->remind_tick_unit = sqlite3_column_int(stmt, *stmt_count);
188                 break;
189         case CAL_PROPERTY_ALARM_DESCRIPTION:
190                 temp = sqlite3_column_text(stmt, *stmt_count);
191                 alarm->alarm_description = cal_strdup((const char*)temp);
192                 break;
193         case CAL_PROPERTY_ALARM_PARENT_ID:
194                 alarm->parent_id = sqlite3_column_int(stmt, *stmt_count);
195                 break;
196         case CAL_PROPERTY_ALARM_SUMMARY:
197                 temp = sqlite3_column_text(stmt, *stmt_count);
198                 alarm->alarm_summary = cal_strdup((const char*)temp);
199                 break;
200         case CAL_PROPERTY_ALARM_ACTION:
201                 alarm->alarm_action = sqlite3_column_int(stmt, *stmt_count);
202                 break;
203         case CAL_PROPERTY_ALARM_ATTACH:
204                 temp = sqlite3_column_text(stmt, *stmt_count);
205                 alarm->alarm_attach = cal_strdup((const char*)temp);
206                 break;
207         case CAL_PROPERTY_ALARM_ALARM:
208                 alarm->alarm.type = sqlite3_column_int(stmt, *stmt_count);
209                 if (alarm->alarm.type == CALENDAR_TIME_UTIME) {
210                         *stmt_count = *stmt_count+1;
211                         alarm->alarm.time.utime = sqlite3_column_int64(stmt, *stmt_count);
212                         *stmt_count = *stmt_count+1; /* datetime */
213
214                 } else {
215                         *stmt_count = *stmt_count+1; /* utime */
216                         *stmt_count = *stmt_count+1;
217                         temp = sqlite3_column_text(stmt, *stmt_count);
218                         if (temp) {
219                                 int y = 0, m = 0, d = 0;
220                                 int h = 0, n = 0, s = 0;
221                                 switch (strlen((const char *)temp)) {
222                                 case 8:
223                                         sscanf((const char *)temp, CAL_DATETIME_FORMAT_YYYYMMDD, &y, &m, &d);
224                                         alarm->alarm.time.date.year = y;
225                                         alarm->alarm.time.date.month = m;
226                                         alarm->alarm.time.date.mday = d;
227                                         break;
228
229                                 case 15:
230                                         sscanf((const char *)temp, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS, &y, &m, &d, &h, &n, &s);
231                                         alarm->alarm.time.date.year = y;
232                                         alarm->alarm.time.date.month = m;
233                                         alarm->alarm.time.date.mday = d;
234                                         alarm->alarm.time.date.hour = h;
235                                         alarm->alarm.time.date.minute = n;
236                                         alarm->alarm.time.date.second = s;
237                                         break;
238                                 }
239                         }
240                 }
241                 break;
242         default:
243                 sqlite3_column_int(stmt, *stmt_count);
244                 break;
245         }
246
247         *stmt_count = *stmt_count+1;
248 }
249
250 static void _cal_db_alarm_get_projection_stmt(sqlite3_stmt *stmt,
251                 const unsigned int *projection, const int projection_count,
252                 calendar_record_h record)
253 {
254         int i = 0;
255         int stmt_count = 0;
256
257         for (i = 0; i < projection_count; i++)
258                 _cal_db_alarm_get_property_stmt(stmt, projection[i], &stmt_count, record);
259 }
260
261 static int _cal_db_alarm_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
262 {
263         cal_query_s *que = NULL;
264         int ret = CALENDAR_ERROR_NONE;
265         char *condition = NULL;
266         char *projection = NULL;
267         char *order = NULL;
268         GSList *bind_text = NULL, *cursor = NULL;
269         char *query_str = NULL;
270         sqlite3_stmt *stmt = NULL;
271         int i = 0;
272         char *table_name;
273
274         que = (cal_query_s *)query;
275
276         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_ALARM)) {
277                 table_name = cal_strdup(CAL_TABLE_ALARM);
278         } else {
279                 ERR("uri(%s) not support get records with query", que->view_uri);
280                 return CALENDAR_ERROR_INVALID_PARAMETER;
281         }
282
283         /* make filter */
284         if (que->filter) {
285                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
286                 if (CALENDAR_ERROR_NONE != ret) {
287                         CAL_FREE(table_name);
288                         ERR("cal_db_query_create_condition() Fail(%d), ret");
289                         return ret;
290                 }
291         }
292
293         /* make projection */
294         ret = cal_db_query_create_projection(query, &projection);
295
296         /* query - projection */
297         if (projection) {
298                 cal_db_append_string(&query_str, "SELECT");
299                 cal_db_append_string(&query_str, projection);
300                 cal_db_append_string(&query_str, "FROM");
301                 cal_db_append_string(&query_str, table_name);
302                 CAL_FREE(projection);
303         } else {
304                 cal_db_append_string(&query_str, "SELECT *, rowid FROM ");
305                 cal_db_append_string(&query_str, table_name);
306         }
307         CAL_FREE(table_name);
308
309         /* query - condition */
310         if (condition) {
311                 cal_db_append_string(&query_str, "WHERE");
312                 cal_db_append_string(&query_str, condition);
313                 CAL_FREE(condition);
314         }
315
316         /* ORDER */
317         ret = cal_db_query_create_order(query, condition, &order);
318         if (order) {
319                 cal_db_append_string(&query_str, order);
320                 CAL_FREE(order);
321         }
322
323         char buf[CAL_STR_SHORT_LEN32] = {0};
324         if (0 < limit) {
325                 snprintf(buf, sizeof(buf), "LIMIT %d", limit);
326                 cal_db_append_string(&query_str, buf);
327                 if (0 < offset) {
328                         snprintf(buf, sizeof(buf), "OFFSET %d", offset);
329                         cal_db_append_string(&query_str, buf);
330                 }
331         }
332
333         /* query */
334         ret = cal_db_util_query_prepare(query_str, &stmt);
335         if (CALENDAR_ERROR_NONE != ret) {
336                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
337                 SECURE("query[%s]", query_str);
338                 if (bind_text) {
339                         g_slist_free_full(bind_text, free);
340                         bind_text = NULL;
341                 }
342                 free(query_str);
343                 return ret;
344         }
345
346         /* bind text */
347         if (bind_text)  {
348                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
349                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
350         }
351
352         ret = calendar_list_create(out_list);
353         if (CALENDAR_ERROR_NONE != ret) {
354                 if (bind_text) {
355                         g_slist_free_full(bind_text, free);
356                         bind_text = NULL;
357                 }
358                 CAL_FREE(query_str);
359                 ERR("calendar_list_create() Fail");
360                 sqlite3_finalize(stmt);
361                 return ret;
362         }
363
364         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
365                 calendar_record_h record;
366                 ret = calendar_record_create(_calendar_alarm._uri, &record);
367                 if (CALENDAR_ERROR_NONE != ret) {
368                         calendar_list_destroy(*out_list, true);
369                         *out_list = NULL;
370
371                         if (bind_text) {
372                                 g_slist_free_full(bind_text, free);
373                                 bind_text = NULL;
374                         }
375                         CAL_FREE(query_str);
376                         sqlite3_finalize(stmt);
377                         return ret;
378                 }
379                 if (0 < que->projection_count) {
380                         cal_record_set_projection(record,
381                                         que->projection, que->projection_count, que->property_count);
382
383                         _cal_db_alarm_get_projection_stmt(stmt,
384                                         que->projection, que->projection_count,
385                                         record);
386                 } else {
387                         _cal_db_alarm_get_stmt(stmt, record);
388                 }
389
390                 ret = calendar_list_add(*out_list, record);
391                 if (CALENDAR_ERROR_NONE != ret) {
392                         calendar_list_destroy(*out_list, true);
393                         *out_list = NULL;
394                         calendar_record_destroy(record, true);
395
396                         if (bind_text) {
397                                 g_slist_free_full(bind_text, free);
398                                 bind_text = NULL;
399                         }
400                         CAL_FREE(query_str);
401                         sqlite3_finalize(stmt);
402                         return ret;
403                 }
404         }
405
406         if (bind_text) {
407                 g_slist_free_full(bind_text, free);
408                 bind_text = NULL;
409         }
410         CAL_FREE(query_str);
411
412         sqlite3_finalize(stmt);
413
414         return CALENDAR_ERROR_NONE;
415 }
416
417 static int _cal_db_alarm_get_count(int *out_count)
418 {
419         char query[CAL_DB_SQL_MAX_LEN] = {0};
420         int count = 0;
421         int ret;
422
423         RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
424
425         snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_ALARM);
426
427         ret = cal_db_util_query_get_first_int_result(query, NULL, &count);
428         if (CALENDAR_ERROR_NONE != ret) {
429                 ERR("cal_db_util_query_get_first_int_result() failed");
430                 return ret;
431         }
432         DBG("%s=%d", query, count);
433
434         *out_count = count;
435         return CALENDAR_ERROR_NONE;
436 }
437
438 static int _cal_db_alarm_get_count_with_query(calendar_query_h query, int *out_count)
439 {
440         cal_query_s *que = NULL;
441         int ret = CALENDAR_ERROR_NONE;
442         char *condition = NULL;
443         char *table_name;
444         int count = 0;
445         GSList *bind_text = NULL;
446
447         que = (cal_query_s *)query;
448
449         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_ALARM)) {
450                 table_name = cal_strdup(CAL_TABLE_ALARM);
451         } else {
452                 ERR("uri(%s) not support get records with query", que->view_uri);
453                 return CALENDAR_ERROR_INVALID_PARAMETER;
454         }
455
456         /* make filter */
457         if (que->filter) {
458                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
459                 if (CALENDAR_ERROR_NONE != ret) {
460                         CAL_FREE(table_name);
461                         ERR("cal_db_query_create_condition() Fail(%d), ret");
462                         return ret;
463                 }
464         }
465
466         char *query_str = NULL;
467         /* query: select */
468         cal_db_append_string(&query_str, "SELECT count(*) FROM");
469         cal_db_append_string(&query_str, table_name);
470         CAL_FREE(table_name);
471
472         /* query: condition */
473         if (condition) {
474                 cal_db_append_string(&query_str, "WHERE");
475                 cal_db_append_string(&query_str, condition);
476                 CAL_FREE(condition);
477         }
478
479         /* query */
480         ret = cal_db_util_query_get_first_int_result(query_str, bind_text, &count);
481         if (CALENDAR_ERROR_NONE != ret) {
482                 ERR("cal_db_util_query_get_first_int_result() failed");
483                 if (bind_text) {
484                         g_slist_free_full(bind_text, free);
485                         bind_text = NULL;
486                 }
487                 CAL_FREE(query_str);
488                 return ret;
489         }
490         DBG("%s=%d", query_str, count);
491
492         *out_count = count;
493
494         if (bind_text) {
495                 g_slist_free_full(bind_text, free);
496                 bind_text = NULL;
497         }
498         CAL_FREE(query_str);
499         return CALENDAR_ERROR_NONE;
500 }
501