add comment LCOV_EXCL
[platform/core/pim/calendar-service.git] / server / db / cal_db_plugin_calendar.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 #include <stdlib.h>
20
21 #include "cal_internal.h"
22 #include "cal_typedef.h"
23 #include "cal_view.h"
24 #include "cal_record.h"
25
26 #include "cal_db.h"
27 #include "cal_db_util.h"
28 #include "cal_db_query.h"
29 #include "cal_access_control.h"
30 #include "cal_utils.h"
31
32 #ifdef CAL_IPC_SERVER
33 #include "cal_server_calendar_delete.h"
34 #endif
35 #include "cal_access_control.h"
36
37 /*
38  * db plugin function
39  */
40 static int _cal_db_calendar_insert_record(calendar_record_h record, int* id);
41 static int _cal_db_calendar_get_record(int id, calendar_record_h* out_record);
42 static int _cal_db_calendar_update_record(calendar_record_h record);
43 static int _cal_db_calendar_delete_record(int id);
44 static int _cal_db_calendar_get_all_records(int offset, int limit, calendar_list_h* out_list);
45 static int _cal_db_calendar_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
46 static int _cal_db_calendar_delete_records(int ids[], int count);
47 static int _cal_db_calendar_get_count(int *out_count);
48 static int _cal_db_calendar_get_count_with_query(calendar_query_h query, int *out_count);
49 static int _cal_db_calendar_replace_record(calendar_record_h record, int id);
50 static int _cal_db_calendar_replace_records(const calendar_list_h list, int ids[], int count);
51
52 /*
53  * static function
54  */
55 static void _cal_db_calendar_get_stmt(sqlite3_stmt *stmt, calendar_record_h record);
56 static void _cal_db_calendar_get_property_stmt(sqlite3_stmt *stmt,
57                 unsigned int property, int stmt_count, calendar_record_h record);
58 static void _cal_db_calendar_get_projection_stmt(sqlite3_stmt *stmt,
59                 const unsigned int *projection, const int projection_count,
60                 calendar_record_h record);
61 static int _cal_db_calendar_update_projection(calendar_record_h record);
62
63 cal_db_plugin_cb_s cal_db_calendar_plugin_cb = {
64         .is_query_only = false,
65         .insert_record = _cal_db_calendar_insert_record,
66         .get_record = _cal_db_calendar_get_record,
67         .update_record = _cal_db_calendar_update_record,
68         .delete_record = _cal_db_calendar_delete_record,
69         .get_all_records = _cal_db_calendar_get_all_records,
70         .get_records_with_query = _cal_db_calendar_get_records_with_query,
71         .insert_records = NULL, /* use insert record with bulk count */
72         .update_records = NULL,
73         .delete_records = _cal_db_calendar_delete_records,
74         .get_count = _cal_db_calendar_get_count,
75         .get_count_with_query = _cal_db_calendar_get_count_with_query,
76         .replace_record = _cal_db_calendar_replace_record,
77         .replace_records = _cal_db_calendar_replace_records
78 };
79
80 static bool _cal_db_calendar_check_value_validation(cal_book_s* calendar)
81 {
82         RETVM_IF(NULL == calendar, CALENDAR_ERROR_INVALID_PARAMETER, "calendar is NULL");
83
84         switch (calendar->store_type) {
85         case CALENDAR_BOOK_TYPE_NONE:
86         case CALENDAR_BOOK_TYPE_EVENT:
87         case CALENDAR_BOOK_TYPE_TODO:
88                 return true;
89
90         default:
91                 /* LCOV_EXCL_START */
92                 ERR("store type is invalid(%d)", calendar->store_type);
93                 return false;
94                 /* LCOV_EXCL_STOP */
95         }
96         return true;
97 }
98
99 static int _cal_db_calendar_insert_record(calendar_record_h record, int* id)
100 {
101         CAL_FN_CALL();
102
103         int ret = 0;
104
105         RETV_IF(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER);
106
107         cal_book_s *book =  (cal_book_s *)(record);
108         if (false == _cal_db_calendar_check_value_validation(book)) {
109                 /* LCOV_EXCL_START */
110                 ERR("cal_db_calendar_check_value_validation() Fail");
111                 return CALENDAR_ERROR_INVALID_PARAMETER;
112                 /* LCOV_EXCL_STOP */
113         }
114
115         char *client_label = NULL;
116         client_label = cal_access_control_get_label();
117
118         char query[CAL_DB_SQL_MAX_LEN];
119         snprintf(query, sizeof(query), "INSERT INTO %s (uid, updated, name, description, "
120                         "color, location, visibility, sync_event, account_id, store_type, "
121                         "sync_data1, sync_data2, sync_data3, sync_data4, mode, owner_label) "
122                         "VALUES (?, %d, ?, ?, ?, ?, %d, %d, %d, %d, ?, ?, ?, ?, %d, ?)",
123                         CAL_TABLE_CALENDAR, book->updated, book->visibility, book->sync_event,
124                         book->account_id, book->store_type, book->mode);
125
126         sqlite3_stmt *stmt = NULL;
127         ret = cal_db_util_query_prepare(query, &stmt);
128         if (CALENDAR_ERROR_NONE != ret) {
129                 /* LCOV_EXCL_START */
130                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
131                 SECURE("query[%s]", query);
132                 free(client_label);
133                 return ret;
134                 /* LCOV_EXCL_STOP */
135         }
136
137         if (book->uid)
138                 cal_db_util_stmt_bind_text(stmt, 1, book->uid);
139         if (book->name)
140                 cal_db_util_stmt_bind_text(stmt, 2, book->name);
141         if (book->description)
142                 cal_db_util_stmt_bind_text(stmt, 3, book->description);
143         if (book->color)
144                 cal_db_util_stmt_bind_text(stmt, 4, book->color);
145         if (book->location)
146                 cal_db_util_stmt_bind_text(stmt, 5, book->location);
147         if (book->sync_data1)
148                 cal_db_util_stmt_bind_text(stmt, 6, book->sync_data1);
149         if (book->sync_data2)
150                 cal_db_util_stmt_bind_text(stmt, 7, book->sync_data2);
151         if (book->sync_data3)
152                 cal_db_util_stmt_bind_text(stmt, 8, book->sync_data3);
153         if (book->sync_data4)
154                 cal_db_util_stmt_bind_text(stmt, 9, book->sync_data4);
155         if (client_label)
156                 cal_db_util_stmt_bind_text(stmt, 10, client_label);
157
158         ret = cal_db_util_stmt_step(stmt);
159         if (CALENDAR_ERROR_NONE != ret) {
160                 /* LCOV_EXCL_START */
161                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
162                 sqlite3_finalize(stmt);
163                 free(client_label);
164                 return ret;
165                 /* LCOV_EXCL_STOP */
166         }
167         sqlite3_finalize(stmt);
168         free(client_label);
169
170         int index = 0;
171         index = cal_db_util_last_insert_id();
172         /* access control */
173         cal_access_control_reset();
174
175         if (id)
176                 *id = index;
177
178         cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
179
180         return CALENDAR_ERROR_NONE;
181 }
182
183 static int _cal_db_calendar_get_record(int id, calendar_record_h* out_record)
184 {
185         char query[CAL_DB_SQL_MAX_LEN];
186         sqlite3_stmt *stmt = NULL;
187         int ret = 0;
188
189         ret = calendar_record_create(_calendar_book._uri, out_record);
190         if (CALENDAR_ERROR_NONE != ret) {
191                 /* LCOV_EXCL_START */
192                 ERR("calendar_record_create() Fail(%d)", ret);
193                 return CALENDAR_ERROR_OUT_OF_MEMORY;
194                 /* LCOV_EXCL_STOP */
195         }
196
197         snprintf(query, sizeof(query), "SELECT * FROM %s WHERE id=%d AND (deleted = 0)",
198                         CAL_TABLE_CALENDAR,     id);
199         ret = cal_db_util_query_prepare(query, &stmt);
200         if (CALENDAR_ERROR_NONE != ret) {
201                 /* LCOV_EXCL_START */
202                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
203                 SECURE("query[%s]", query);
204                 calendar_record_destroy(*out_record, true);
205                 *out_record = NULL;
206                 return ret;
207                 /* LCOV_EXCL_STOP */
208         }
209         ret = cal_db_util_stmt_step(stmt);
210         if (CAL_SQLITE_ROW != ret) {
211                 /* LCOV_EXCL_START */
212                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
213                 SECURE("query[%s]", query);
214                 sqlite3_finalize(stmt);
215                 calendar_record_destroy(*out_record, true);
216                 *out_record = NULL;
217                 if (CALENDAR_ERROR_NONE == ret)
218                         return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
219                 return ret;
220                 /* LCOV_EXCL_STOP */
221         }
222
223         _cal_db_calendar_get_stmt(stmt, *out_record);
224         sqlite3_finalize(stmt);
225
226         return CALENDAR_ERROR_NONE;
227 }
228
229 static int _cal_db_calendar_update_record(calendar_record_h record)
230 {
231         int ret = 0;
232
233         RETV_IF(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER);
234
235         cal_book_s* book =  (cal_book_s*)(record);
236         if (false == _cal_db_calendar_check_value_validation(book)) {
237                 /* LCOV_EXCL_START */
238                 ERR("cal_db_calendar_check_value_validation() Fail");
239                 return CALENDAR_ERROR_INVALID_PARAMETER;
240                 /* LCOV_EXCL_STOP */
241         }
242
243         if (book->common.properties_flags != NULL)
244                 return _cal_db_calendar_update_projection(record);
245
246
247         char query[CAL_DB_SQL_MAX_LEN] = {0};
248         snprintf(query, sizeof(query), "UPDATE %s SET "
249                         "uid =?, updated = %d, name =?, description =?, color =?, location =?, "
250                         "visibility =%d, sync_event =%d, account_id =%d, store_type =%d, "
251                         "sync_data1 =?, sync_data2 =?, sync_data3 =?, sync_data4 =?, mode =%d "
252                         "WHERE id =%d",
253                         CAL_TABLE_CALENDAR, book->updated, book->visibility, book->sync_event,
254                         book->account_id, book->store_type, book->mode, book->index);
255
256         sqlite3_stmt *stmt = NULL;
257         ret = cal_db_util_query_prepare(query, &stmt);
258         if (CALENDAR_ERROR_NONE != ret) {
259                 /* LCOV_EXCL_START */
260                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
261                 SECURE("query[%s]", query);
262                 return ret;
263                 /* LCOV_EXCL_STOP */
264         }
265
266         if (book->uid)
267                 cal_db_util_stmt_bind_text(stmt, 1, book->uid);
268         if (book->name)
269                 cal_db_util_stmt_bind_text(stmt, 2, book->name);
270         if (book->description)
271                 cal_db_util_stmt_bind_text(stmt, 3, book->description);
272         if (book->color)
273                 cal_db_util_stmt_bind_text(stmt, 4, book->color);
274         if (book->location)
275                 cal_db_util_stmt_bind_text(stmt, 5, book->location);
276         if (book->sync_data1)
277                 cal_db_util_stmt_bind_text(stmt, 6, book->sync_data1);
278         if (book->sync_data2)
279                 cal_db_util_stmt_bind_text(stmt, 7, book->sync_data2);
280         if (book->sync_data3)
281                 cal_db_util_stmt_bind_text(stmt, 8, book->sync_data3);
282         if (book->sync_data4)
283                 cal_db_util_stmt_bind_text(stmt, 9, book->sync_data4);
284
285         ret = cal_db_util_stmt_step(stmt);
286         if (CALENDAR_ERROR_NONE != ret) {
287                 /* LCOV_EXCL_START */
288                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
289                 sqlite3_finalize(stmt);
290                 SECURE("query[%s]", query);
291                 return ret;
292                 /* LCOV_EXCL_STOP */
293         }
294         sqlite3_finalize(stmt);
295         cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
296
297         return CALENDAR_ERROR_NONE;
298 }
299
300 static int _cal_db_calendar_delete_record(int id)
301 {
302         int ret = CALENDAR_ERROR_NONE;
303         char query[CAL_DB_SQL_MAX_LEN] = {0};
304         int calendar_book_id = -1;
305
306         snprintf(query, sizeof(query), "SELECT id FROM %s WHERE id = %d",
307                         CAL_TABLE_CALENDAR, id);
308         ret = cal_db_util_query_get_first_int_result(query, NULL, &calendar_book_id);
309         if (CALENDAR_ERROR_NONE != ret) {
310                 /* LCOV_EXCL_START */
311                 ERR("cal_db_util_query_get_first_int_result() Fail(%d)", ret);
312                 return ret;
313                 /* LCOV_EXCL_STOP */
314         }
315
316         int count = 0;
317         int count2 = 0;
318         snprintf(query, sizeof(query), "select count(*) from %s", CAL_TABLE_NORMAL_INSTANCE);
319         ret = cal_db_util_query_get_first_int_result(query, NULL, &count);
320         if (CALENDAR_ERROR_NONE != ret) {
321                 /* LCOV_EXCL_START */
322                 ERR("cal_db_util_query_get_first_int_result() Fail");
323                 return ret;
324                 /* LCOV_EXCL_STOP */
325         }
326
327         snprintf(query, sizeof(query), "select count(*) from %s", CAL_TABLE_ALLDAY_INSTANCE);
328         ret = cal_db_util_query_get_first_int_result(query, NULL, &count2);
329         if (CALENDAR_ERROR_NONE != ret) {
330                 /* LCOV_EXCL_START */
331                 ERR("cal_db_util_query_get_first_int_result() Fail");
332                 return ret;
333                 /* LCOV_EXCL_STOP */
334         }
335
336         count += count2;
337
338         if (1000 < count) {
339                 snprintf(query, sizeof(query), "UPDATE %s SET deleted = 1 WHERE id = %d", CAL_TABLE_CALENDAR, id);
340                 ret = cal_db_util_query_exec(query);
341                 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_query_exec() Fail(%d)", ret);
342                 cal_server_calendar_delete_start();
343         } else {
344                 snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d", CAL_TABLE_CALENDAR, id);
345                 ret = cal_db_util_query_exec(query);
346                 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_query_exec() Fail(%d)", ret);
347
348                 snprintf(query, sizeof(query), "DELETE FROM %s WHERE calendar_id = %d", CAL_TABLE_SCHEDULE, id);
349                 ret = cal_db_util_query_exec(query);
350                 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_query_exec() Fail(%d)", ret);
351         }
352
353         snprintf(query, sizeof(query), "DELETE FROM %s WHERE calendar_id = %d", CAL_TABLE_DELETED, id);
354         ret = cal_db_util_query_exec(query);
355         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_query_exec() Fail(%d)", ret);
356
357         cal_access_control_reset();
358
359         cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
360         return CALENDAR_ERROR_NONE;
361 }
362
363 static int _cal_db_calendar_replace_record(calendar_record_h record, int id)
364 {
365         int ret = 0;
366
367         RETV_IF(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER);
368
369         cal_book_s *book =  (cal_book_s *)(record);
370         if (false == _cal_db_calendar_check_value_validation(book)) {
371                 /* LCOV_EXCL_START */
372                 ERR("cal_db_calendar_check_value_validation() Fail");
373                 return CALENDAR_ERROR_INVALID_PARAMETER;
374                 /* LCOV_EXCL_STOP */
375         }
376
377         book->index = id;
378         if (book->common.properties_flags)
379                 return _cal_db_calendar_update_projection(record);
380
381         char query[CAL_DB_SQL_MAX_LEN] = {0};
382         snprintf(query, sizeof(query), "UPDATE %s SET "
383                         "uid =?, updated =%d, name =?, description =?, color =?, location =?, "
384                         "visibility =%d, sync_event =%d, account_id =%d, store_type =%d, "
385                         "sync_data1 =?, sync_data2 =?, sync_data3 =?, sync_data4 =?, mode =%d "
386                         "WHERE id =%d",
387                         CAL_TABLE_CALENDAR, book->updated, book->visibility, book->sync_event,
388                         book->account_id, book->store_type, book->mode, id);
389
390         sqlite3_stmt *stmt = NULL;
391         ret = cal_db_util_query_prepare(query, &stmt);
392         if (CALENDAR_ERROR_NONE != ret) {
393                 /* LCOV_EXCL_START */
394                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
395                 SECURE("query[%s]", query);
396                 return ret;
397                 /* LCOV_EXCL_STOP */
398         }
399
400         if (book->uid)
401                 cal_db_util_stmt_bind_text(stmt, 1, book->uid);
402         if (book->name)
403                 cal_db_util_stmt_bind_text(stmt, 2, book->name);
404         if (book->description)
405                 cal_db_util_stmt_bind_text(stmt, 3, book->description);
406         if (book->color)
407                 cal_db_util_stmt_bind_text(stmt, 4, book->color);
408         if (book->location)
409                 cal_db_util_stmt_bind_text(stmt, 5, book->location);
410         if (book->sync_data1)
411                 cal_db_util_stmt_bind_text(stmt, 6, book->sync_data1);
412         if (book->sync_data2)
413                 cal_db_util_stmt_bind_text(stmt, 7, book->sync_data2);
414         if (book->sync_data3)
415                 cal_db_util_stmt_bind_text(stmt, 8, book->sync_data3);
416         if (book->sync_data4)
417                 cal_db_util_stmt_bind_text(stmt, 9, book->sync_data4);
418
419         ret = cal_db_util_stmt_step(stmt);
420         if (CALENDAR_ERROR_NONE != ret) {
421                 /* LCOV_EXCL_START */
422                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
423                 sqlite3_finalize(stmt);
424                 SECURE("query[%s]", query);
425                 return ret;
426                 /* LCOV_EXCL_STOP */
427         }
428         sqlite3_finalize(stmt);
429         cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
430
431         return CALENDAR_ERROR_NONE;
432 }
433
434 static int _cal_db_calendar_get_all_records(int offset, int limit, calendar_list_h* out_list)
435 {
436         int ret = CALENDAR_ERROR_NONE;
437         char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
438         char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
439         sqlite3_stmt *stmt = NULL;
440
441         RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
442
443         ret = calendar_list_create(out_list);
444         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
445
446         if (0 < offset)
447                 snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
448         if (0 < limit)
449                 snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
450
451         char *query_str = NULL;
452         cal_db_append_string(&query_str, "SELECT * FROM");
453         cal_db_append_string(&query_str, CAL_TABLE_CALENDAR);
454         cal_db_append_string(&query_str, "WHERE deleted = 0");
455         cal_db_append_string(&query_str, limitquery);
456         cal_db_append_string(&query_str, offsetquery);
457
458         ret = cal_db_util_query_prepare(query_str, &stmt);
459         if (CALENDAR_ERROR_NONE != ret) {
460                 /* LCOV_EXCL_START */
461                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
462                 SECURE("query[%s]", query_str);
463                 calendar_list_destroy(*out_list, true);
464                 *out_list = NULL;
465                 free(query_str);
466                 return ret;
467                 /* LCOV_EXCL_STOP */
468         }
469
470         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
471                 calendar_record_h record;
472                 ret = calendar_record_create(_calendar_book._uri, &record);
473                 if (CALENDAR_ERROR_NONE != ret) {
474                         /* LCOV_EXCL_START */
475                         calendar_list_destroy(*out_list, true);
476                         *out_list = NULL;
477                         sqlite3_finalize(stmt);
478                         CAL_FREE(query_str);
479                         return ret;
480                         /* LCOV_EXCL_STOP */
481                 }
482                 _cal_db_calendar_get_stmt(stmt, record);
483
484                 ret = calendar_list_add(*out_list, record);
485                 if (CALENDAR_ERROR_NONE != ret) {
486                         /* LCOV_EXCL_START */
487                         calendar_list_destroy(*out_list, true);
488                         *out_list = NULL;
489                         calendar_record_destroy(record, true);
490                         sqlite3_finalize(stmt);
491                         CAL_FREE(query_str);
492                         return ret;
493                         /* LCOV_EXCL_STOP */
494                 }
495         }
496
497         sqlite3_finalize(stmt);
498         CAL_FREE(query_str);
499         return CALENDAR_ERROR_NONE;
500 }
501
502 static int _cal_db_calendar_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
503 {
504         cal_query_s *que = NULL;
505         int i = 0;
506         int ret = CALENDAR_ERROR_NONE;
507         char *condition = NULL;
508         GSList *bind_text = NULL, *cursor = NULL;
509         sqlite3_stmt *stmt = NULL;
510
511         que = (cal_query_s *)query;
512
513         /* make filter */
514         if (que->filter) {
515                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
516                 if (CALENDAR_ERROR_NONE != ret) {
517                         /* LCOV_EXCL_START */
518                         ERR("cal_db_query_create_condition() Fail(%d), ret");
519                         return ret;
520                         /* LCOV_EXCL_STOP */
521                 }
522         }
523
524         /* make: projection */
525         char *projection = NULL;
526         ret = cal_db_query_create_projection(query, &projection);
527
528         char *query_str = NULL;
529         /* query: projection */
530         if (projection) {
531                 cal_db_append_string(&query_str, "SELECT");
532                 cal_db_append_string(&query_str, projection);
533                 cal_db_append_string(&query_str, "FROM");
534                 cal_db_append_string(&query_str, CAL_TABLE_CALENDAR);
535                 CAL_FREE(projection);
536         } else {
537                 cal_db_append_string(&query_str, "SELECT * FROM");
538                 cal_db_append_string(&query_str, CAL_TABLE_CALENDAR);
539         }
540
541         /* query: condition */
542         if (condition) {
543                 cal_db_append_string(&query_str,  "WHERE (");
544                 cal_db_append_string(&query_str, condition);
545                 cal_db_append_string(&query_str, ") AND (deleted = 0)");
546         }
547
548         /* order */
549         char *order = NULL;
550         ret = cal_db_query_create_order(query, condition, &order);
551         if (order) {
552                 cal_db_append_string(&query_str, order);
553                 CAL_FREE(order);
554         }
555         CAL_FREE(condition);
556
557         /* limit, offset */
558         char buf[CAL_STR_SHORT_LEN32] = {0};
559         if (0 < limit) {
560                 snprintf(buf, sizeof(buf), "LIMIT %d", limit);
561                 cal_db_append_string(&query_str, buf);
562
563                 if (0 < offset) {
564                         snprintf(buf, sizeof(buf), "OFFSET %d", offset);
565                         cal_db_append_string(&query_str, buf);
566                 }
567         }
568
569         /* query */
570         ret = cal_db_util_query_prepare(query_str, &stmt);
571         SECURE("[TEST]---------query[%s]", query_str);
572         if (CALENDAR_ERROR_NONE != ret) {
573                 /* LCOV_EXCL_START */
574                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
575                 SECURE("query[%s]", query_str);
576                 if (bind_text) {
577                         g_slist_free_full(bind_text, free);
578                         bind_text = NULL;
579                 }
580                 free(query_str);
581                 return ret;
582                 /* LCOV_EXCL_STOP */
583         }
584
585         /* bind text */
586         if (bind_text) {
587                 g_slist_length(bind_text);
588                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
589                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
590         }
591
592         ret = calendar_list_create(out_list);
593         if (CALENDAR_ERROR_NONE != ret) {
594                 /* LCOV_EXCL_START */
595                 ERR("calendar_list_create() Fail");
596                 if (bind_text) {
597                         g_slist_free_full(bind_text, free);
598                         bind_text = NULL;
599                 }
600                 sqlite3_finalize(stmt);
601                 CAL_FREE(query_str);
602                 return ret;
603                 /* LCOV_EXCL_STOP */
604         }
605
606         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
607                 calendar_record_h record;
608                 ret = calendar_record_create(_calendar_book._uri, &record);
609                 if (CALENDAR_ERROR_NONE != ret) {
610                         /* LCOV_EXCL_START */
611                         ERR("calendar_record_create() Fail(%d)", ret);
612                         calendar_list_destroy(*out_list, true);
613                         *out_list = NULL;
614
615                         if (bind_text) {
616                                 g_slist_free_full(bind_text, free);
617                                 bind_text = NULL;
618                         }
619                         sqlite3_finalize(stmt);
620                         CAL_FREE(query_str);
621                         return ret;
622                         /* LCOV_EXCL_STOP */
623                 }
624
625                 if (0 < que->projection_count) {
626                         cal_record_set_projection(record,
627                                         que->projection, que->projection_count, que->property_count);
628
629                         _cal_db_calendar_get_projection_stmt(stmt,
630                                         que->projection, que->projection_count,
631                                         record);
632                 } else {
633                         _cal_db_calendar_get_stmt(stmt, record);
634                 }
635
636                 ret = calendar_list_add(*out_list, record);
637                 if (CALENDAR_ERROR_NONE != ret) {
638                         /* LCOV_EXCL_START */
639                         ERR("calendar_list_add() Fail(%d)", ret);
640                         calendar_list_destroy(*out_list, true);
641                         *out_list = NULL;
642                         calendar_record_destroy(record, true);
643
644                         if (bind_text) {
645                                 g_slist_free_full(bind_text, free);
646                                 bind_text = NULL;
647                         }
648                         sqlite3_finalize(stmt);
649                         CAL_FREE(query_str);
650                         return ret;
651                         /* LCOV_EXCL_STOP */
652                 }
653         }
654
655         if (bind_text) {
656                 g_slist_free_full(bind_text, free);
657                 bind_text = NULL;
658         }
659         sqlite3_finalize(stmt);
660         CAL_FREE(query_str);
661
662         return CALENDAR_ERROR_NONE;
663 }
664
665 static int _cal_db_calendar_delete_records(int ids[], int count)
666 {
667         int ret = 0;
668         int i = 0;
669         for (i = 0; i < count; i++) {
670                 ret = _cal_db_calendar_delete_record(ids[i]);
671                 if (CALENDAR_ERROR_NONE != ret) {
672                         /* LCOV_EXCL_START */
673                         ERR("_cal_db_calendar_delete_record() Fail(%d)", ret);
674                         return CALENDAR_ERROR_DB_FAILED;
675                         /* LCOV_EXCL_STOP */
676                 }
677         }
678         return CALENDAR_ERROR_NONE;
679 }
680
681 static int _cal_db_calendar_replace_records(const calendar_list_h list, int ids[], int count)
682 {
683         calendar_record_h record;
684         int i = 0;
685         int ret = 0;
686
687         if (NULL == list) {
688                 /* LCOV_EXCL_START */
689                 ERR("Invalid argument: list is NULL");
690                 return CALENDAR_ERROR_INVALID_PARAMETER;
691                 /* LCOV_EXCL_STOP */
692         }
693
694         ret = calendar_list_first(list);
695         if (CALENDAR_ERROR_NONE != ret) {
696                 /* LCOV_EXCL_START */
697                 ERR("list first error");
698                 return ret;
699                 /* LCOV_EXCL_STOP */
700         }
701
702         for (i = 0; i < count; i++) {
703                 if (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(list, &record)) {
704                         ret = _cal_db_calendar_replace_record(record, ids[i]);
705                         if (CALENDAR_ERROR_NONE != ret) {
706                                 /* LCOV_EXCL_START */
707                                 ERR("_cal_db_calendar_replace_record() Fail(%d)", ret);
708                                 return ret;
709                                 /* LCOV_EXCL_STOP */
710                         }
711                 }
712                 if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
713                         break;
714         }
715
716         return CALENDAR_ERROR_NONE;
717 }
718
719 static int _cal_db_calendar_get_count(int *out_count)
720 {
721         RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
722
723         char *query_str = NULL;
724         cal_db_append_string(&query_str, "SELECT count(*) FROM");
725         cal_db_append_string(&query_str, CAL_TABLE_CALENDAR);
726         cal_db_append_string(&query_str, "WHERE deleted = 0");
727
728         int ret = 0;
729         int count = 0;
730         ret = cal_db_util_query_get_first_int_result(query_str, NULL, &count);
731         if (CALENDAR_ERROR_NONE != ret) {
732                 /* LCOV_EXCL_START */
733                 ERR("cal_db_util_query_get_first_int_result() failed");
734                 CAL_FREE(query_str);
735                 return ret;
736                 /* LCOV_EXCL_STOP */
737         }
738         DBG("count(%d) str[%s]", count, query_str);
739         CAL_FREE(query_str);
740
741         *out_count = count;
742         return CALENDAR_ERROR_NONE;
743 }
744
745 static int _cal_db_calendar_get_count_with_query(calendar_query_h query, int *out_count)
746 {
747         cal_query_s *que = NULL;
748         int ret = CALENDAR_ERROR_NONE;
749         char *condition = NULL;
750         char *table_name;
751         int count = 0;
752         GSList *bind_text = NULL;
753
754         que = (cal_query_s *)query;
755
756         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_CALENDAR)) {
757                 table_name = cal_strdup(CAL_TABLE_CALENDAR);
758         } else {
759                 /* LCOV_EXCL_START */
760                 ERR("uri(%s) not support get records with query", que->view_uri);
761                 return CALENDAR_ERROR_INVALID_PARAMETER;
762                 /* LCOV_EXCL_STOP */
763         }
764
765         /* make filter */
766         if (que->filter) {
767                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
768                 if (CALENDAR_ERROR_NONE != ret) {
769                         /* LCOV_EXCL_START */
770                         ERR("cal_db_query_create_condition() Fail(%d), ret");
771                         CAL_FREE(table_name);
772                         return ret;
773                         /* LCOV_EXCL_STOP */
774                 }
775         }
776
777         char *query_str = NULL;
778         /* query: select */
779         cal_db_append_string(&query_str, "SELECT count(*) FROM");
780         cal_db_append_string(&query_str, table_name);
781         CAL_FREE(table_name);
782
783         /* query: condition */
784         if (condition) {
785                 cal_db_append_string(&query_str, "WHERE (");
786                 cal_db_append_string(&query_str, condition);
787                 cal_db_append_string(&query_str, ") AND (deleted = 0)");
788                 CAL_FREE(condition);
789         }
790
791         /* query */
792         ret = cal_db_util_query_get_first_int_result(query_str, bind_text, &count);
793         if (CALENDAR_ERROR_NONE != ret) {
794                 /* LCOV_EXCL_START */
795                 ERR("cal_db_util_query_get_first_int_result() failed");
796                 if (bind_text) {
797                         g_slist_free_full(bind_text, free);
798                         bind_text = NULL;
799                 }
800                 CAL_FREE(query_str);
801                 return ret;
802                 /* LCOV_EXCL_STOP */
803         }
804         DBG("count(%d) str[%s]", count, query_str);
805
806         if (out_count)
807                 *out_count = count;
808
809         if (bind_text) {
810                 g_slist_free_full(bind_text, free);
811                 bind_text = NULL;
812         }
813         CAL_FREE(query_str);
814         return CALENDAR_ERROR_NONE;
815 }
816
817 static void _cal_db_calendar_get_stmt(sqlite3_stmt *stmt, calendar_record_h record)
818 {
819         cal_book_s* calendar =  (cal_book_s*)(record);
820         int count = 0;
821         const unsigned char *temp;
822
823         calendar->index = sqlite3_column_int(stmt, count++);
824
825         temp = sqlite3_column_text(stmt, count++);
826         calendar->uid = cal_strdup((const char*)temp);
827
828         calendar->updated = sqlite3_column_int(stmt, count++);
829
830         temp = sqlite3_column_text(stmt, count++);
831         calendar->name = cal_strdup((const char*)temp);
832
833         temp = sqlite3_column_text(stmt, count++);
834         calendar->description = cal_strdup((const char*)temp);
835
836         temp = sqlite3_column_text(stmt, count++);
837         calendar->color = cal_strdup((const char*)temp);
838
839         temp = sqlite3_column_text(stmt, count++);
840         calendar->location = cal_strdup((const char*)temp);
841
842         calendar->visibility = sqlite3_column_int(stmt, count++);
843         calendar->sync_event = sqlite3_column_int(stmt, count++);
844         calendar->is_deleted = sqlite3_column_int(stmt, count++);
845         calendar->account_id = sqlite3_column_int(stmt, count++);
846         calendar->store_type = sqlite3_column_int(stmt, count++);
847
848         temp = sqlite3_column_text(stmt, count++);
849         calendar->sync_data1 = cal_strdup((const char*)temp);
850         temp = sqlite3_column_text(stmt, count++);
851         calendar->sync_data2 = cal_strdup((const char*)temp);
852         temp = sqlite3_column_text(stmt, count++);
853         calendar->sync_data3 = cal_strdup((const char*)temp);
854         temp = sqlite3_column_text(stmt, count++);
855         calendar->sync_data4 = cal_strdup((const char*)temp);
856
857         /* deleted */
858         sqlite3_column_int(stmt, count++);
859
860         /* mode */
861         calendar->mode = sqlite3_column_int(stmt, count++);
862
863         /* owner_label */
864         sqlite3_column_text(stmt, count++);
865 }
866
867 static void _cal_db_calendar_get_property_stmt(sqlite3_stmt *stmt,
868                 unsigned int property, int stmt_count, calendar_record_h record)
869 {
870         cal_book_s* calendar =  (cal_book_s*)(record);
871         const unsigned char *temp;
872
873         switch (property) {
874         case CAL_PROPERTY_CALENDAR_ID:
875                 calendar->index = sqlite3_column_int(stmt, stmt_count);
876                 break;
877         case CAL_PROPERTY_CALENDAR_UID:
878                 temp = sqlite3_column_text(stmt, stmt_count);
879                 calendar->uid = cal_strdup((const char*)temp);
880                 break;
881         case CAL_PROPERTY_CALENDAR_NAME:
882                 temp = sqlite3_column_text(stmt, stmt_count);
883                 calendar->name = cal_strdup((const char*)temp);
884                 break;
885         case CAL_PROPERTY_CALENDAR_DESCRIPTION:
886                 temp = sqlite3_column_text(stmt, stmt_count);
887                 calendar->description = cal_strdup((const char*)temp);
888                 break;
889         case CAL_PROPERTY_CALENDAR_COLOR:
890                 temp = sqlite3_column_text(stmt, stmt_count);
891                 calendar->color = cal_strdup((const char*)temp);
892                 break;
893         case CAL_PROPERTY_CALENDAR_LOCATION:
894                 temp = sqlite3_column_text(stmt, stmt_count);
895                 calendar->location = cal_strdup((const char*)temp);
896                 break;
897         case CAL_PROPERTY_CALENDAR_VISIBILITY:
898                 calendar->visibility = sqlite3_column_int(stmt, stmt_count);
899                 break;
900         case CAL_PROPERTY_CALENDAR_SYNC_EVENT:
901                 calendar->sync_event = sqlite3_column_int(stmt, stmt_count);
902                 break;
903         case CAL_PROPERTY_CALENDAR_ACCOUNT_ID:
904                 calendar->account_id = sqlite3_column_int(stmt, stmt_count);
905                 break;
906         case CAL_PROPERTY_CALENDAR_STORE_TYPE:
907                 calendar->store_type = sqlite3_column_int(stmt, stmt_count);
908                 break;
909         case CAL_PROPERTY_CALENDAR_SYNC_DATA1:
910                 temp = sqlite3_column_text(stmt, stmt_count);
911                 calendar->sync_data1 = cal_strdup((const char*)temp);
912                 break;
913         case CAL_PROPERTY_CALENDAR_SYNC_DATA2:
914                 temp = sqlite3_column_text(stmt, stmt_count);
915                 calendar->sync_data1 = cal_strdup((const char*)temp);
916                 break;
917         case CAL_PROPERTY_CALENDAR_SYNC_DATA3:
918                 temp = sqlite3_column_text(stmt, stmt_count);
919                 calendar->sync_data1 = cal_strdup((const char*)temp);
920                 break;
921         case CAL_PROPERTY_CALENDAR_SYNC_DATA4:
922                 temp = sqlite3_column_text(stmt, stmt_count);
923                 calendar->sync_data1 = cal_strdup((const char*)temp);
924                 break;
925         case CAL_PROPERTY_CALENDAR_MODE:
926                 calendar->mode = sqlite3_column_int(stmt, stmt_count);
927                 break;
928         default:
929                 break;
930         }
931
932         return;
933 }
934
935 static void _cal_db_calendar_get_projection_stmt(sqlite3_stmt *stmt,
936                 const unsigned int *projection, const int projection_count,
937                 calendar_record_h record)
938 {
939         int i = 0;
940
941         for (i = 0; i < projection_count; i++)
942                 _cal_db_calendar_get_property_stmt(stmt, projection[i], i, record);
943 }
944
945 static int _cal_db_calendar_update_projection(calendar_record_h record)
946 {
947         char query[CAL_DB_SQL_MAX_LEN] = {0};
948         sqlite3_stmt *stmt = NULL;
949         cal_book_s* calendar =  (cal_book_s*)(record);
950         int ret = 0;
951         char* set = NULL;
952         GSList *bind_text = NULL;
953         GSList *cursor = NULL;
954
955         ret = cal_db_query_create_projection_update_set(record, &set, &bind_text);
956         RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
957
958         snprintf(query, sizeof(query), "UPDATE %s SET %s "
959                         "WHERE id = %d",
960                         CAL_TABLE_CALENDAR, set,
961                         calendar->index);
962
963         ret = cal_db_util_query_prepare(query, &stmt);
964         if (CALENDAR_ERROR_NONE != ret) {
965                 /* LCOV_EXCL_START */
966                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
967                 SECURE("query[%s]", query);
968                 free(set);
969                 if (bind_text) {
970                         g_slist_free_full(bind_text, free);
971                         bind_text = NULL;
972                 }
973                 return ret;
974                 /* LCOV_EXCL_STOP */
975         }
976
977         /* bind */
978         if (bind_text) {
979                 int i = 0;
980                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
981                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
982         }
983
984         ret = cal_db_util_stmt_step(stmt);
985         if (CALENDAR_ERROR_NONE != ret) {
986                 /* LCOV_EXCL_START */
987                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
988                 SECURE("query[%s]", query);
989                 sqlite3_finalize(stmt);
990                 free(set);
991                 if (bind_text) {
992                         g_slist_free_full(bind_text, free);
993                         bind_text = NULL;
994                 }
995                 return ret;
996                 /* LCOV_EXCL_STOP */
997         }
998
999         sqlite3_finalize(stmt);
1000
1001         cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
1002
1003         CAL_FREE(set);
1004         if (bind_text) {
1005                 g_slist_free_full(bind_text, free);
1006                 bind_text = NULL;
1007         }
1008
1009         return CALENDAR_ERROR_NONE;
1010 }