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