Tizen 2.1 base
[framework/pim/calendar-service.git] / native / cal_db_plugin_instance_normal.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2013 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
31 static int __cal_db_instance_normal_insert_record(calendar_record_h record, int* id);
32 //static int __cal_db_instance_normal_get_record(int id, calendar_record_h* out_record);
33 //static int __cal_db_instance_normal_update_record(calendar_record_h record);
34 static int __cal_db_instance_normal_delete_record(int id);
35 static int __cal_db_instance_normal_get_all_records(int offset, int limit, calendar_list_h* out_list);
36 static int __cal_db_instance_normal_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
37 //static int __cal_db_instance_normal_insert_records(const calendar_list_h list);
38 //static int __cal_db_instance_normal_update_records(const calendar_list_h list);
39 //static int __cal_db_instance_normal_delete_records(int ids[], int count);
40 static int __cal_db_instance_normal_get_count(int *out_count);
41 static int __cal_db_instance_normal_get_count_with_query(calendar_query_h query, int *out_count);
42 /*
43  * static function
44  */
45 static void __cal_db_instance_normal_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
46 static void __cal_db_instance_normal_get_property_stmt(sqlite3_stmt *stmt,
47         unsigned int property, int *stmt_count, calendar_record_h record);
48 static void __cal_db_instance_normal_get_projection_stmt(sqlite3_stmt *stmt,
49         const unsigned int *projection, const int projection_count,
50         calendar_record_h record);
51
52 cal_db_plugin_cb_s _cal_db_instance_normal_plugin_cb = {
53         .is_query_only = false,
54         .insert_record=__cal_db_instance_normal_insert_record,
55         .get_record=NULL,
56         .update_record=NULL,
57         .delete_record=__cal_db_instance_normal_delete_record,
58         .get_all_records=__cal_db_instance_normal_get_all_records,
59         .get_records_with_query=__cal_db_instance_normal_get_records_with_query,
60         .insert_records=NULL,
61         .update_records=NULL,
62         .delete_records=NULL,
63     .get_count=__cal_db_instance_normal_get_count,
64     .get_count_with_query=__cal_db_instance_normal_get_count_with_query,
65     .replace_record=NULL,
66     .replace_records=NULL
67 };
68
69 static int __cal_db_instance_normal_insert_record(calendar_record_h record, int* id)
70 {
71         int index = -1;
72         char query[CAL_DB_SQL_MAX_LEN];
73         sqlite3_stmt *stmt;
74         cal_instance_normal_s *normal = NULL;
75     cal_db_util_error_e dbret = CAL_DB_OK;
76
77         normal = (cal_instance_normal_s *)(record);
78         retvm_if(NULL == normal, CALENDAR_ERROR_INVALID_PARAMETER,
79                         "Invalid argument: cal_instance_normal_s is NULL");
80
81         snprintf(query, sizeof(query),
82                         "INSERT INTO %s ("
83                         "event_id, "
84                         "dtstart_utime, dtend_utime"
85                         ") VALUES ( "
86                         "%d, "
87                         "%lld, %lld) ",
88                         CAL_TABLE_NORMAL_INSTANCE,
89                         normal->event_id,
90                         normal->dtstart_utime, normal->dtend_utime);
91
92         stmt = _cal_db_util_query_prepare(query);
93         if (NULL == stmt)
94         {
95                 DBG("query[%s]", query);
96                 ERR("_cal_db_util_query_prepare() Failed");
97                 return CALENDAR_ERROR_DB_FAILED;
98         }
99
100         dbret = _cal_db_util_stmt_step(stmt);
101         if (CAL_DB_DONE != dbret)
102         {
103                 ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
104                 sqlite3_finalize(stmt);
105                 switch (dbret)
106                 {
107                 case CAL_DB_ERROR_NO_SPACE:
108                         return CALENDAR_ERROR_FILE_NO_SPACE;
109                 default:
110                         return CALENDAR_ERROR_DB_FAILED;
111                 }
112         }
113
114         index = _cal_db_util_last_insert_id();
115         sqlite3_finalize(stmt);
116
117         //calendar_record_set_int(record, _calendar_instance_normal.id, index);
118         if (id)
119         {
120             *id = index;
121         }
122
123         return CALENDAR_ERROR_NONE;
124 }
125
126 static int __cal_db_instance_normal_delete_record(int id)
127 {
128     cal_db_util_error_e dbret = CAL_DB_OK;
129         char query[CAL_DB_SQL_MAX_LEN] = {0};
130
131         retvm_if(id < 0, CALENDAR_ERROR_INVALID_PARAMETER,
132                         "Invalid argument: id(%d) < 0", id);
133
134         snprintf(query, sizeof(query),
135                         "DELETE FROM %s "
136                         "WHERE event_id = %d ",
137                         CAL_TABLE_NORMAL_INSTANCE,
138                         id);
139
140         dbret = _cal_db_util_query_exec(query);
141         if (dbret != CAL_DB_OK)
142         {
143                 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
144                 switch (dbret)
145                 {
146                 case CAL_DB_ERROR_NO_SPACE:
147                         return CALENDAR_ERROR_FILE_NO_SPACE;
148                 default:
149                         return CALENDAR_ERROR_DB_FAILED;
150                 }
151         }
152
153         return CALENDAR_ERROR_NONE;
154 }
155
156 static int __cal_db_instance_normal_get_all_records(int offset, int limit, calendar_list_h* out_list)
157 {
158     int ret = CALENDAR_ERROR_NONE;
159     char query[CAL_DB_SQL_MAX_LEN] = {0};
160     char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
161     char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
162     sqlite3_stmt *stmt = NULL;
163
164     retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
165
166     ret = calendar_list_create(out_list);
167     retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
168
169     if (offset > 0)
170     {
171         snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
172     }
173     if (limit > 0)
174     {
175         snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
176     }
177     snprintf(query, sizeof(query),
178                         "SELECT * FROM %s %s %s",
179                         CAL_TABLE_NORMAL_INSTANCE, limitquery, offsetquery);
180
181     stmt = _cal_db_util_query_prepare(query);
182     if (NULL == stmt)
183     {
184         ERR("_cal_db_util_query_prepare() Failed");
185         calendar_list_destroy(*out_list, true);
186                 *out_list = NULL;
187         return CALENDAR_ERROR_DB_FAILED;
188     }
189
190     while(CAL_DB_ROW ==  _cal_db_util_stmt_step(stmt))
191     {
192         calendar_record_h record;
193         // stmt -> record
194         ret = calendar_record_create(_calendar_instance_normal._uri,&record);
195         if( ret != CALENDAR_ERROR_NONE )
196         {
197             calendar_list_destroy(*out_list, true);
198                         *out_list = NULL;
199             sqlite3_finalize(stmt);
200             return ret;
201         }
202         __cal_db_instance_normal_get_stmt(stmt,record);
203
204         ret = calendar_list_add(*out_list,record);
205         if( ret != CALENDAR_ERROR_NONE )
206         {
207             calendar_list_destroy(*out_list, true);
208                         *out_list = NULL;
209             calendar_record_destroy(record, true);
210             sqlite3_finalize(stmt);
211             return ret;
212         }
213     }
214     sqlite3_finalize(stmt);
215
216         return CALENDAR_ERROR_NONE;
217 }
218
219 static int __cal_db_instance_normal_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
220 {
221     cal_query_s *que = NULL;
222     int ret = CALENDAR_ERROR_NONE;
223     char *condition = NULL;
224     char *projection = NULL;
225     char *order = NULL;
226     GSList *bind_text = NULL, *cursor = NULL;
227     char strquery[CAL_DB_SQL_MAX_LEN] = {0};
228     int len;
229     sqlite3_stmt *stmt = NULL;
230     int i = 0;
231     char *table_name;
232
233     que = (cal_query_s *)query;
234
235     if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR))
236     {
237         table_name = SAFE_STRDUP(CAL_VIEW_TABLE_NORMAL_INSTANCE);
238     }
239     else
240     {
241         ERR("uri(%s) not support get records with query",que->view_uri);
242         return CALENDAR_ERROR_INVALID_PARAMETER;
243         //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
244     }
245
246     // make filter
247     if (que->filter)
248     {
249         ret = _cal_db_query_create_condition(query,
250                 &condition, &bind_text);
251         if (ret != CALENDAR_ERROR_NONE)
252         {
253             CAL_FREE(table_name);
254             ERR("filter create fail");
255             return ret;
256         }
257     }
258
259     // make projection
260     ret = _cal_db_query_create_projection(query, &projection);
261
262     // query - projection
263     if (projection)
264     {
265         len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
266     }
267     else
268     {
269         len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", table_name);
270     }
271     CAL_FREE(table_name);
272
273     // query - condition
274     if (condition)
275     {
276         len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
277     }
278
279     // ORDER
280     ret = _cal_db_query_create_order(query, &order);
281     if (order)
282     {
283         len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
284     }
285
286     if (0 < limit)
287     {
288         len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
289         if (0 < offset)
290             len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
291     }
292
293     // query
294     stmt = _cal_db_util_query_prepare(strquery);
295     if (NULL == stmt)
296     {
297         if (bind_text)
298         {
299             g_slist_free(bind_text);
300         }
301         CAL_FREE(condition);
302         CAL_FREE(projection);
303         ERR("_cal_db_util_query_prepare() Failed");
304         return CALENDAR_ERROR_DB_FAILED;
305     }
306     CAL_DBG("%s",strquery);
307
308     // bind text
309     if (bind_text)
310     {
311         len = g_slist_length(bind_text);
312         for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
313         {
314             _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
315         }
316     }
317
318     //
319     ret = calendar_list_create(out_list);
320     if (ret != CALENDAR_ERROR_NONE)
321     {
322         if (bind_text)
323         {
324             g_slist_free(bind_text);
325         }
326         CAL_FREE(condition);
327         CAL_FREE(projection);
328         ERR("calendar_list_create() Failed");
329         sqlite3_finalize(stmt);
330         return ret;
331     }
332
333     while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
334     {
335         calendar_record_h record;
336         // stmt -> record
337         ret = calendar_record_create(que->view_uri,&record);
338         if( ret != CALENDAR_ERROR_NONE )
339         {
340             calendar_list_destroy(*out_list, true);
341                         *out_list = NULL;
342
343             if (bind_text)
344             {
345                 g_slist_free(bind_text);
346             }
347             CAL_FREE(condition);
348             CAL_FREE(projection);
349             sqlite3_finalize(stmt);
350             return ret;
351         }
352         if (que->projection_count > 0)
353         {
354                         _cal_record_set_projection(record,
355                                         que->projection, que->projection_count, que->property_count);
356
357             __cal_db_instance_normal_get_projection_stmt(stmt,
358                                         que->projection, que->projection_count,
359                     record);
360         }
361         else
362         {
363             __cal_db_instance_normal_get_stmt(stmt,record);
364         }
365
366         ret = calendar_list_add(*out_list,record);
367         if( ret != CALENDAR_ERROR_NONE )
368         {
369             calendar_list_destroy(*out_list, true);
370                         *out_list = NULL;
371             calendar_record_destroy(record, true);
372
373             if (bind_text)
374             {
375                 g_slist_free(bind_text);
376             }
377             CAL_FREE(condition);
378             CAL_FREE(projection);
379             sqlite3_finalize(stmt);
380             return ret;
381         }
382     }
383
384     if (bind_text)
385     {
386         g_slist_free(bind_text);
387     }
388     CAL_FREE(condition);
389     CAL_FREE(projection);
390     sqlite3_finalize(stmt);
391
392     return CALENDAR_ERROR_NONE;
393 }
394
395 static int __cal_db_instance_normal_get_count(int *out_count)
396 {
397     char query[CAL_DB_SQL_MAX_LEN] = {0};
398     int count = 0;
399         int ret;
400
401     retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
402
403     snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_NORMAL_INSTANCE);
404
405     ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
406         if (CALENDAR_ERROR_NONE != ret)
407         {
408                 ERR("_cal_db_util_query_get_first_int_result() failed");
409                 return ret;
410         }
411     CAL_DBG("%s=%d",query,count);
412
413     *out_count = count;
414     return CALENDAR_ERROR_NONE;
415 }
416
417 static int __cal_db_instance_normal_get_count_with_query(calendar_query_h query, int *out_count)
418 {
419     cal_query_s *que = NULL;
420     int ret = CALENDAR_ERROR_NONE;
421     char *condition = NULL;
422     char strquery[CAL_DB_SQL_MAX_LEN] = {0};
423     int len;
424     char *table_name;
425     int count = 0;
426     GSList *bind_text = NULL;
427
428     que = (cal_query_s *)query;
429
430     if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR))
431     {
432         table_name = SAFE_STRDUP(CAL_VIEW_TABLE_NORMAL_INSTANCE);
433     }
434     else
435     {
436         ERR("uri(%s) not support get records with query",que->view_uri);
437         return CALENDAR_ERROR_INVALID_PARAMETER;
438         //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
439     }
440
441     // make filter
442     if (que->filter)
443     {
444         ret = _cal_db_query_create_condition(query, &condition, &bind_text);
445         if (ret != CALENDAR_ERROR_NONE)
446         {
447             CAL_FREE(table_name);
448             ERR("filter create fail");
449             return ret;
450         }
451     }
452
453     // query - select from
454
455     len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
456     CAL_FREE(table_name);
457
458     // query - condition
459     if (condition)
460     {
461         len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
462     }
463
464     // query
465     ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
466         if (CALENDAR_ERROR_NONE != ret)
467         {
468                 ERR("_cal_db_util_query_get_first_int_result() failed");
469                 if (bind_text)
470                 {
471                         g_slist_free(bind_text);
472                 }
473                 CAL_FREE(condition);
474                 return ret;
475         }
476     CAL_DBG("%s=%d",strquery,count);
477
478     if (out_count) *out_count = count;
479
480     if (bind_text)
481     {
482         g_slist_free(bind_text);
483     }
484         CAL_FREE(condition);
485     return CALENDAR_ERROR_NONE;
486 }
487
488 static void __cal_db_instance_normal_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
489 {
490     cal_instance_normal_s* instance =  (cal_instance_normal_s*)(record);
491     const unsigned char *temp;
492     int count = 0;
493
494     instance->event_id = sqlite3_column_int(stmt, count++);
495     instance->dtstart_type = sqlite3_column_int(stmt, count++);
496     instance->dtstart_utime = sqlite3_column_int64(stmt, count++);
497     sqlite3_column_text(stmt, count++);  //datetime
498     instance->dtend_type = sqlite3_column_int(stmt, count++);
499     instance->dtend_utime = sqlite3_column_int64(stmt, count++);
500     sqlite3_column_text(stmt, count++);  //datetime
501
502     temp = sqlite3_column_text(stmt, count++);
503     instance->summary = SAFE_STRDUP(temp);
504
505     temp = sqlite3_column_text(stmt, count++);
506     instance->description = SAFE_STRDUP(temp);
507
508     temp = sqlite3_column_text(stmt, count++);
509     instance->location = SAFE_STRDUP(temp);
510
511     instance->busy_status = sqlite3_column_int(stmt, count++);
512
513     instance->event_status = sqlite3_column_int(stmt, count++);
514
515     instance->priority = sqlite3_column_int(stmt, count++);
516
517     instance->sensitivity = sqlite3_column_int(stmt, count++);
518
519     instance->has_rrule = sqlite3_column_int(stmt, count++);
520     if (instance->has_rrule > 0)
521     {
522         instance->has_rrule = 1;
523     }
524
525     instance->latitude = sqlite3_column_double(stmt,count++);
526     instance->longitude = sqlite3_column_double(stmt,count++);
527     instance->has_alarm = sqlite3_column_int(stmt,count++);
528     instance->original_event_id = sqlite3_column_int(stmt, count++);
529     instance->calendar_id = sqlite3_column_int(stmt, count++);
530     instance->last_mod = sqlite3_column_int64(stmt, count++);
531
532     return;
533 }
534
535 static void __cal_db_instance_normal_get_property_stmt(sqlite3_stmt *stmt,
536         unsigned int property, int *stmt_count, calendar_record_h record)
537 {
538     cal_instance_normal_s* instance =  (cal_instance_normal_s*)(record);
539     const unsigned char *temp;
540
541     switch(property)
542     {
543     case CAL_PROPERTY_INSTANCE_NORMAL_START:
544         sqlite3_column_int(stmt,*stmt_count);
545         *stmt_count = *stmt_count+1;
546         instance->dtstart_type = CALENDAR_TIME_UTIME;//sqlite3_column_int(stmt, *stmt_count);
547         instance->dtstart_utime = sqlite3_column_int64(stmt, *stmt_count);
548         *stmt_count = *stmt_count+1;
549         sqlite3_column_text(stmt, *stmt_count);  // dtstart_datetime
550         break;
551     case CAL_PROPERTY_INSTANCE_NORMAL_END:
552         sqlite3_column_int(stmt,*stmt_count);
553         *stmt_count = *stmt_count+1;
554         instance->dtend_type = CALENDAR_TIME_UTIME;//sqlite3_column_int(stmt, *stmt_count);
555         instance->dtend_utime = sqlite3_column_int64(stmt, *stmt_count);
556         *stmt_count = *stmt_count+1;
557         sqlite3_column_text(stmt, *stmt_count);
558         break;
559     case CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY:
560         temp = sqlite3_column_text(stmt, *stmt_count);
561         instance->summary = SAFE_STRDUP(temp);
562         break;
563     case CAL_PROPERTY_INSTANCE_NORMAL_LOCATION:
564         temp = sqlite3_column_text(stmt, *stmt_count);
565         instance->location = SAFE_STRDUP(temp);
566         break;
567     case CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID:
568         instance->calendar_id = sqlite3_column_int(stmt, *stmt_count);
569         break;
570     case CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION:
571         temp = sqlite3_column_text(stmt, *stmt_count);
572         instance->description = SAFE_STRDUP(temp);
573         break;
574     case CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS:
575         instance->busy_status = sqlite3_column_int(stmt, *stmt_count);
576         break;
577     case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS:
578         instance->event_status = sqlite3_column_int(stmt, *stmt_count);
579         break;
580     case CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY:
581         instance->priority = sqlite3_column_int(stmt, *stmt_count);
582         break;
583     case CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY:
584         instance->sensitivity = sqlite3_column_int(stmt, *stmt_count);
585         break;
586     case CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE:
587         instance->has_rrule = sqlite3_column_int(stmt, *stmt_count);
588         if (instance->has_rrule > 0)
589         {
590             instance->has_rrule = 1;
591         }
592         break;
593     case CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE:
594         instance->latitude = sqlite3_column_double(stmt,*stmt_count);
595         break;
596     case CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE:
597         instance->longitude = sqlite3_column_double(stmt,*stmt_count);
598         break;
599     case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID:
600         instance->event_id = sqlite3_column_int(stmt, *stmt_count);
601         break;
602     case CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM:
603         instance->has_alarm = sqlite3_column_int(stmt, *stmt_count);
604         break;
605     case CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID:
606         instance->original_event_id = sqlite3_column_int(stmt, *stmt_count);
607         break;
608     case CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME:
609         instance->last_mod = sqlite3_column_int64(stmt, *stmt_count);
610         break;
611     default:
612         sqlite3_column_int(stmt, *stmt_count);
613         break;
614     }
615
616     *stmt_count = *stmt_count+1;
617
618     return;
619 }
620
621 static void __cal_db_instance_normal_get_projection_stmt(sqlite3_stmt *stmt,
622         const unsigned int *projection, const int projection_count,
623         calendar_record_h record)
624 {
625     int i=0;
626     int stmt_count = 0;
627
628     for(i=0;i<projection_count;i++)
629     {
630         __cal_db_instance_normal_get_property_stmt(stmt,projection[i],&stmt_count,record);
631     }
632 }