e5f4b3db6411ff2d86f06460d0f4271cd870cc06
[platform/core/pim/calendar-service.git] / server / db / cal_db_plugin_instance_normal.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 "cal_internal.h"
23 #include "cal_typedef.h"
24 #include "cal_view.h"
25 #include "cal_record.h"
26
27 #include "cal_db_util.h"
28 #include "cal_db.h"
29 #include "cal_db_query.h"
30 #include "cal_access_control.h"
31 #include "cal_utils.h"
32
33 static int _cal_db_instance_normal_delete_record(int id);
34 static int _cal_db_instance_normal_get_all_records(int offset, int limit, calendar_list_h* out_list);
35 static int _cal_db_instance_normal_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
36 static int _cal_db_instance_normal_get_count(int *out_count);
37 static int _cal_db_instance_normal_get_count_with_query(calendar_query_h query, int *out_count);
38
39 /*
40  * static function
41  */
42 static void _cal_db_instance_normal_get_stmt(sqlite3_stmt *stmt, calendar_record_h record);
43 static void _cal_db_instance_normal_get_property_stmt(sqlite3_stmt *stmt,
44                 unsigned int property, int *stmt_count, calendar_record_h record);
45 static void _cal_db_instance_normal_get_projection_stmt(sqlite3_stmt *stmt,
46                 const unsigned int *projection, const int projection_count,
47                 calendar_record_h record);
48
49 cal_db_plugin_cb_s cal_db_instance_normal_plugin_cb = {
50         .is_query_only = false,
51         .insert_record = NULL,
52         .get_record = NULL,
53         .update_record = NULL,
54         .delete_record = _cal_db_instance_normal_delete_record,
55         .get_all_records = _cal_db_instance_normal_get_all_records,
56         .get_records_with_query = _cal_db_instance_normal_get_records_with_query,
57         .insert_records = NULL,
58         .update_records = NULL,
59         .delete_records = NULL,
60         .get_count = _cal_db_instance_normal_get_count,
61         .get_count_with_query = _cal_db_instance_normal_get_count_with_query,
62         .replace_record = NULL,
63         .replace_records = NULL
64 };
65
66 static int _cal_db_instance_normal_delete_record(int id)
67 {
68         int ret = 0;
69         char query[CAL_DB_SQL_MAX_LEN] = {0};
70
71         RETVM_IF(id < 0, CALENDAR_ERROR_INVALID_PARAMETER,
72                         "Invalid argument: id(%d) < 0", id);
73
74         snprintf(query, sizeof(query),
75                         "DELETE FROM %s "
76                         "WHERE event_id = %d ",
77                         CAL_TABLE_NORMAL_INSTANCE,
78                         id);
79
80         ret = cal_db_util_query_exec(query);
81         if (CALENDAR_ERROR_NONE != ret) {
82                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
83                 SECURE("[%s]", query);
84                 return ret;
85         }
86
87         return CALENDAR_ERROR_NONE;
88 }
89
90 static int _cal_db_instance_normal_get_all_records(int offset, int limit, calendar_list_h* out_list)
91 {
92         int ret = CALENDAR_ERROR_NONE;
93         char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
94         char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
95         sqlite3_stmt *stmt = NULL;
96
97         RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
98
99         ret = calendar_list_create(out_list);
100         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
101
102         if (0 < offset)
103                 snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
104         if (0 < limit)
105                 snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
106
107         char *query_str = NULL;
108         cal_db_append_string(&query_str, "SELECT * FROM");
109         cal_db_append_string(&query_str, CAL_VIEW_TABLE_NORMAL_INSTANCE);
110         cal_db_append_string(&query_str, limitquery);
111         cal_db_append_string(&query_str, offsetquery);
112
113         ret = cal_db_util_query_prepare(query_str, &stmt);
114         if (CALENDAR_ERROR_NONE != ret) {
115                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
116                 SECURE("query[%s]", query_str);
117                 calendar_list_destroy(*out_list, true);
118                 *out_list = NULL;
119                 free(query_str);
120                 return ret;
121         }
122
123         SECURE("[TEST]---------query[%s]", query_str);
124         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
125                 calendar_record_h record;
126                 ret = calendar_record_create(_calendar_instance_utime_calendar_book._uri, &record);
127                 if (CALENDAR_ERROR_NONE != ret) {
128                         calendar_list_destroy(*out_list, true);
129                         *out_list = NULL;
130                         sqlite3_finalize(stmt);
131                         CAL_FREE(query_str);
132                         return ret;
133                 }
134                 _cal_db_instance_normal_get_stmt(stmt, record);
135
136                 ret = calendar_list_add(*out_list, record);
137                 if (CALENDAR_ERROR_NONE != ret) {
138                         calendar_list_destroy(*out_list, true);
139                         *out_list = NULL;
140                         calendar_record_destroy(record, true);
141                         sqlite3_finalize(stmt);
142                         CAL_FREE(query_str);
143                         return ret;
144                 }
145         }
146         sqlite3_finalize(stmt);
147         CAL_FREE(query_str);
148
149         return CALENDAR_ERROR_NONE;
150 }
151
152 static int _cal_db_instance_normal_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
153 {
154         cal_query_s *que = NULL;
155         int ret = CALENDAR_ERROR_NONE;
156         char *condition = NULL;
157         char *projection = NULL;
158         GSList *bind_text = NULL, *cursor = NULL;
159         sqlite3_stmt *stmt = NULL;
160         int i = 0;
161         char *table_name;
162
163         que = (cal_query_s *)query;
164
165         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_UTIME_CALENDAR)) {
166                 table_name = cal_strdup(CAL_VIEW_TABLE_NORMAL_INSTANCE);
167         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_UTIME_CALENDAR_EXTENDED)) {
168                 table_name = cal_strdup(CAL_VIEW_TABLE_NORMAL_INSTANCE_EXTENDED);
169         } else {
170                 ERR("uri(%s) not support get records with query", que->view_uri);
171                 return CALENDAR_ERROR_INVALID_PARAMETER;
172         }
173
174         /* make filter */
175         if (que->filter) {
176                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
177                 if (CALENDAR_ERROR_NONE != ret) {
178                         CAL_FREE(table_name);
179                         ERR("cal_db_query_create_condition() Fail(%d), ret");
180                         return ret;
181                 }
182         }
183
184         /* make: projection */
185         ret = cal_db_query_create_projection(query, &projection);
186
187         char *query_str = NULL;
188         /* query: projection */
189         if (projection) {
190                 cal_db_append_string(&query_str, "SELECT");
191                 cal_db_append_string(&query_str, projection);
192                 cal_db_append_string(&query_str, "FROM");
193                 cal_db_append_string(&query_str, table_name);
194                 CAL_FREE(projection);
195         } else {
196                 cal_db_append_string(&query_str, "SELECT * FROM");
197                 cal_db_append_string(&query_str, table_name);
198         }
199         CAL_FREE(table_name);
200
201         /* query: condition */
202         if (condition) {
203                 cal_db_append_string(&query_str, "WHERE (");
204                 cal_db_append_string(&query_str, condition);
205                 cal_db_append_string(&query_str, ")");
206         }
207
208         /* order */
209         char *order = NULL;
210         ret = cal_db_query_create_order(query, condition, &order);
211         if (order) {
212                 cal_db_append_string(&query_str, order);
213                 CAL_FREE(order);
214         }
215         CAL_FREE(condition);
216
217         /* limit, offset */
218         char buf[CAL_STR_SHORT_LEN32] = {0};
219         if (0 < limit) {
220                 snprintf(buf, sizeof(buf), "LIMIT %d", limit);
221                 cal_db_append_string(&query_str, buf);
222
223                 if (0 < offset) {
224                         snprintf(buf, sizeof(buf), "OFFSET %d", offset);
225                         cal_db_append_string(&query_str, buf);
226                 }
227         }
228
229         /* query */
230         ret = cal_db_util_query_prepare(query_str, &stmt);
231         if (CALENDAR_ERROR_NONE != ret) {
232                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
233                 SECURE("query[%s]", query_str);
234                 if (bind_text) {
235                         g_slist_free_full(bind_text, free);
236                         bind_text = NULL;
237                 }
238                 free(query_str);
239                 return ret;
240         }
241
242         /* bind text */
243         if (bind_text) {
244                 g_slist_length(bind_text);
245                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
246                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
247         }
248
249         ret = calendar_list_create(out_list);
250         if (CALENDAR_ERROR_NONE != ret) {
251                 if (bind_text) {
252                         g_slist_free_full(bind_text, free);
253                         bind_text = NULL;
254                 }
255                 ERR("calendar_list_create() Fail");
256                 sqlite3_finalize(stmt);
257                 CAL_FREE(query_str);
258                 return ret;
259         }
260
261         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
262                 calendar_record_h record;
263                 ret = calendar_record_create(que->view_uri, &record);
264                 if (CALENDAR_ERROR_NONE != ret) {
265                         calendar_list_destroy(*out_list, true);
266                         *out_list = NULL;
267
268                         if (bind_text) {
269                                 g_slist_free_full(bind_text, free);
270                                 bind_text = NULL;
271                         }
272                         sqlite3_finalize(stmt);
273                         return ret;
274                 }
275                 if (0 < que->projection_count) {
276                         cal_record_set_projection(record,
277                                         que->projection, que->projection_count, que->property_count);
278
279                         _cal_db_instance_normal_get_projection_stmt(stmt,
280                                         que->projection, que->projection_count,
281                                         record);
282                 } else {
283                         _cal_db_instance_normal_get_stmt(stmt, record);
284                 }
285
286                 ret = calendar_list_add(*out_list, record);
287                 if (CALENDAR_ERROR_NONE != ret) {
288                         calendar_list_destroy(*out_list, true);
289                         *out_list = NULL;
290                         calendar_record_destroy(record, true);
291
292                         if (bind_text) {
293                                 g_slist_free_full(bind_text, free);
294                                 bind_text = NULL;
295                         }
296                         sqlite3_finalize(stmt);
297                         CAL_FREE(query_str);
298                         return ret;
299                 }
300         }
301
302         if (bind_text) {
303                 g_slist_free_full(bind_text, free);
304                 bind_text = NULL;
305         }
306         sqlite3_finalize(stmt);
307         CAL_FREE(query_str);
308
309         return CALENDAR_ERROR_NONE;
310 }
311
312 static int _cal_db_instance_normal_get_count(int *out_count)
313 {
314         RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
315
316         char *query_str = NULL;
317         cal_db_append_string(&query_str, "SELECT count(*) FROM");
318         cal_db_append_string(&query_str, CAL_TABLE_NORMAL_INSTANCE);
319
320         int ret = 0;
321         int count = 0;
322         ret = cal_db_util_query_get_first_int_result(query_str, NULL, &count);
323         if (CALENDAR_ERROR_NONE != ret) {
324                 ERR("cal_db_util_query_get_first_int_result() Fail");
325                 CAL_FREE(query_str);
326                 return ret;
327         }
328         DBG("count(%d) str[%s]", count, query_str);
329         CAL_FREE(query_str);
330
331         *out_count = count;
332         return CALENDAR_ERROR_NONE;
333 }
334
335 static int _cal_db_instance_normal_get_count_with_query(calendar_query_h query, int *out_count)
336 {
337         cal_query_s *que = NULL;
338         int ret = CALENDAR_ERROR_NONE;
339         char *condition = NULL;
340         char *table_name;
341         int count = 0;
342         GSList *bind_text = NULL;
343
344         que = (cal_query_s *)query;
345
346         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_UTIME_CALENDAR)) {
347                 table_name = cal_strdup(CAL_VIEW_TABLE_NORMAL_INSTANCE);
348         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_UTIME_CALENDAR_EXTENDED)) {
349                 table_name = cal_strdup(CAL_VIEW_TABLE_NORMAL_INSTANCE_EXTENDED);
350         } else {
351                 ERR("uri(%s) not support get records with query", que->view_uri);
352                 return CALENDAR_ERROR_INVALID_PARAMETER;
353         }
354
355         /* make filter */
356         if (que->filter) {
357                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
358                 if (CALENDAR_ERROR_NONE != ret) {
359                         CAL_FREE(table_name);
360                         ERR("cal_db_query_create_condition() Fail(%d), ret");
361                         return ret;
362                 }
363         }
364
365         char *query_str = NULL;
366         /* query: select */
367         cal_db_append_string(&query_str, "SELECT count(*) FROM");
368         cal_db_append_string(&query_str, table_name);
369         CAL_FREE(table_name);
370
371         /* query: condition */
372         if (condition) {
373                 cal_db_append_string(&query_str,  "WHERE (");
374                 cal_db_append_string(&query_str, condition);
375                 cal_db_append_string(&query_str, ")");
376                 CAL_FREE(condition);
377         }
378
379         /* query */
380         ret = cal_db_util_query_get_first_int_result(query_str, bind_text, &count);
381         if (CALENDAR_ERROR_NONE != ret) {
382                 ERR("cal_db_util_query_get_first_int_result() Fail");
383                 if (bind_text) {
384                         g_slist_free_full(bind_text, free);
385                         bind_text = NULL;
386                 }
387
388                 CAL_FREE(query_str);
389                 return ret;
390         }
391         DBG("count(%d) str[%s]", count, query_str);
392
393         if (out_count) *out_count = count;
394         if (bind_text) {
395                 g_slist_free_full(bind_text, free);
396                 bind_text = NULL;
397         }
398
399         CAL_FREE(query_str);
400         return CALENDAR_ERROR_NONE;
401 }
402
403 static void _cal_db_instance_normal_get_stmt(sqlite3_stmt *stmt, calendar_record_h record)
404 {
405         cal_instance_normal_s* instance =  (cal_instance_normal_s*)(record);
406         const unsigned char *temp;
407         int count = 0;
408
409         instance->event_id = sqlite3_column_int(stmt, count++);
410         instance->start.type = sqlite3_column_int(stmt, count++);
411         instance->start.time.utime = sqlite3_column_int64(stmt, count++);
412         count++; /* datatime */
413         instance->end.type = sqlite3_column_int(stmt, count++);
414         instance->end.time.utime = sqlite3_column_int64(stmt, count++);
415         count++; /* datatime */
416
417         temp = sqlite3_column_text(stmt, count++);
418         instance->summary = cal_strdup((const char*)temp);
419
420         temp = sqlite3_column_text(stmt, count++);
421         instance->description = cal_strdup((const char*)temp);
422
423         temp = sqlite3_column_text(stmt, count++);
424         instance->location = cal_strdup((const char*)temp);
425
426         instance->busy_status = sqlite3_column_int(stmt, count++);
427
428         instance->event_status = sqlite3_column_int(stmt, count++);
429
430         instance->priority = sqlite3_column_int(stmt, count++);
431
432         instance->sensitivity = sqlite3_column_int(stmt, count++);
433
434         instance->has_rrule = sqlite3_column_int(stmt, count++);
435         if (0 < instance->has_rrule)
436                 instance->has_rrule = 1;
437
438         instance->latitude = sqlite3_column_double(stmt, count++);
439         instance->longitude = sqlite3_column_double(stmt, count++);
440         instance->has_alarm = sqlite3_column_int(stmt, count++);
441         instance->original_event_id = sqlite3_column_int(stmt, count++);
442         instance->calendar_id = sqlite3_column_int(stmt, count++);
443         instance->last_mod = sqlite3_column_int64(stmt, count++);
444
445         temp = sqlite3_column_text(stmt, count++);
446         instance->sync_data1 = cal_strdup((const char*)temp);
447
448         return;
449 }
450
451 static void _cal_db_instance_normal_get_property_stmt(sqlite3_stmt *stmt,
452                 unsigned int property, int *stmt_count, calendar_record_h record)
453 {
454         cal_instance_normal_s* instance =  (cal_instance_normal_s*)(record);
455         const unsigned char *temp;
456
457         switch (property) {
458         case CAL_PROPERTY_INSTANCE_NORMAL_START:
459                 instance->start.type = CALENDAR_TIME_UTIME;
460                 *stmt_count = *stmt_count+1;
461                 instance->start.time.utime = sqlite3_column_int64(stmt, *stmt_count);
462                 *stmt_count = *stmt_count+1; /* datatime */
463                 break;
464         case CAL_PROPERTY_INSTANCE_NORMAL_END:
465                 instance->end.type = CALENDAR_TIME_UTIME;
466                 sqlite3_column_int(stmt, *stmt_count);
467                 *stmt_count = *stmt_count+1;
468                 instance->end.time.utime = sqlite3_column_int64(stmt, *stmt_count);
469                 *stmt_count = *stmt_count+1; /* datatime */
470                 break;
471         case CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY:
472                 temp = sqlite3_column_text(stmt, *stmt_count);
473                 instance->summary = cal_strdup((const char*)temp);
474                 break;
475         case CAL_PROPERTY_INSTANCE_NORMAL_LOCATION:
476                 temp = sqlite3_column_text(stmt, *stmt_count);
477                 instance->location = cal_strdup((const char*)temp);
478                 break;
479         case CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID:
480                 instance->calendar_id = sqlite3_column_int(stmt, *stmt_count);
481                 break;
482         case CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION:
483                 temp = sqlite3_column_text(stmt, *stmt_count);
484                 instance->description = cal_strdup((const char*)temp);
485                 break;
486         case CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS:
487                 instance->busy_status = sqlite3_column_int(stmt, *stmt_count);
488                 break;
489         case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS:
490                 instance->event_status = sqlite3_column_int(stmt, *stmt_count);
491                 break;
492         case CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY:
493                 instance->priority = sqlite3_column_int(stmt, *stmt_count);
494                 break;
495         case CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY:
496                 instance->sensitivity = sqlite3_column_int(stmt, *stmt_count);
497                 break;
498         case CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE:
499                 instance->has_rrule = sqlite3_column_int(stmt, *stmt_count);
500                 if (0 < instance->has_rrule)
501                         instance->has_rrule = 1;
502
503                 break;
504         case CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE:
505                 instance->latitude = sqlite3_column_double(stmt, *stmt_count);
506                 break;
507         case CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE:
508                 instance->longitude = sqlite3_column_double(stmt, *stmt_count);
509                 break;
510         case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID:
511                 instance->event_id = sqlite3_column_int(stmt, *stmt_count);
512                 break;
513         case CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM:
514                 instance->has_alarm = sqlite3_column_int(stmt, *stmt_count);
515                 break;
516         case CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID:
517                 instance->original_event_id = sqlite3_column_int(stmt, *stmt_count);
518                 break;
519         case CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME:
520                 instance->last_mod = sqlite3_column_int64(stmt, *stmt_count);
521                 break;
522         case CAL_PROPERTY_INSTANCE_NORMAL_SYNC_DATA1:
523                 temp = sqlite3_column_text(stmt, *stmt_count);
524                 instance->sync_data1 = cal_strdup((const char*)temp);
525                 break;
526         default:
527                 sqlite3_column_int(stmt, *stmt_count);
528                 break;
529         }
530
531         *stmt_count = *stmt_count+1;
532
533         return;
534 }
535
536 static void _cal_db_instance_normal_get_projection_stmt(sqlite3_stmt *stmt,
537                 const unsigned int *projection, const int projection_count,
538                 calendar_record_h record)
539 {
540         int i = 0;
541         int stmt_count = 0;
542
543         for (i = 0; i < projection_count; i++)
544                 _cal_db_instance_normal_get_property_stmt(stmt, projection[i], &stmt_count, record);
545 }