4 * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "cal_internal.h"
23 #include "cal_typedef.h"
25 #include "cal_record.h"
27 #include "cal_db_util.h"
29 #include "cal_db_query.h"
30 #include "cal_db_plugin_extended_helper.h"
31 #include "cal_utils.h"
33 static int _cal_db_extended_insert_record(calendar_record_h record, int* id);
34 static int _cal_db_extended_get_record(int id, calendar_record_h* out_record);
35 static int _cal_db_extended_update_record(calendar_record_h record);
36 static int _cal_db_extended_delete_record(int id);
37 static int _cal_db_extended_get_all_records(int offset, int limit, calendar_list_h* out_list);
38 static int _cal_db_extended_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
39 static int _cal_db_extended_insert_records(const calendar_list_h list, int** ids);
40 static int _cal_db_extended_update_records(const calendar_list_h list);
41 static int _cal_db_extended_delete_records(int ids[], int count);
42 static int _cal_db_extended_get_count(int *out_count);
43 static int _cal_db_extended_get_count_with_query(calendar_query_h query, int *out_count);
44 static int _cal_db_extended_replace_record(calendar_record_h record, int id);
45 static int _cal_db_extended_replace_records(const calendar_list_h list, int ids[], int count);
50 static void _cal_db_extended_get_stmt(sqlite3_stmt *stmt, calendar_record_h record);
51 static void _cal_db_extended_get_property_stmt(sqlite3_stmt *stmt,
52 unsigned int property, int stmt_count, calendar_record_h record);
53 static void _cal_db_extended_get_projection_stmt(sqlite3_stmt *stmt,
54 const unsigned int *projection, const int projection_count,
55 calendar_record_h record);
56 static void _cal_db_extended_get_stmt(sqlite3_stmt *stmt, calendar_record_h record);
57 static int _cal_db_extended_update_projection(calendar_record_h record);
59 cal_db_plugin_cb_s cal_db_extended_plugin_cb = {
60 .is_query_only = false,
61 .insert_record = _cal_db_extended_insert_record,
62 .get_record = _cal_db_extended_get_record,
63 .update_record = _cal_db_extended_update_record,
64 .delete_record = _cal_db_extended_delete_record,
65 .get_all_records = _cal_db_extended_get_all_records,
66 .get_records_with_query = _cal_db_extended_get_records_with_query,
67 .insert_records = _cal_db_extended_insert_records,
68 .update_records = _cal_db_extended_update_records,
69 .delete_records = _cal_db_extended_delete_records,
70 .get_count = _cal_db_extended_get_count,
71 .get_count_with_query = _cal_db_extended_get_count_with_query,
72 .replace_record = _cal_db_extended_replace_record,
73 .replace_records = _cal_db_extended_replace_records
76 static int _cal_db_extended_insert_record(calendar_record_h record, int* id)
78 cal_extended_s* extended = (cal_extended_s*)(record);
79 RETV_IF(NULL == extended, CALENDAR_ERROR_INVALID_PARAMETER);
80 RETVM_IF(extended->record_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "record_id(%d)", extended->record_id);
81 return cal_db_extended_insert_record(record, extended->record_id, extended->record_type, id);
84 static int _cal_db_extended_get_record(int id, calendar_record_h* out_record)
87 char query[CAL_DB_SQL_MAX_LEN];
88 sqlite3_stmt *stmt = NULL;
90 ret = calendar_record_create(_calendar_extended_property._uri, out_record);
91 if (CALENDAR_ERROR_NONE != ret) {
93 ERR("calendar_record_create() Fail(%d)", ret);
94 return CALENDAR_ERROR_OUT_OF_MEMORY;
98 snprintf(query, sizeof(query), "SELECT * FROM %s WHERE id=%d",
99 CAL_TABLE_EXTENDED, id);
100 ret = cal_db_util_query_prepare(query, &stmt);
101 if (CALENDAR_ERROR_NONE != ret) {
102 /* LCOV_EXCL_START */
103 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
104 SECURE("query[%s]", query);
105 calendar_record_destroy(*out_record, true);
111 ret = cal_db_util_stmt_step(stmt);
112 if (CAL_SQLITE_ROW != ret) {
113 /* LCOV_EXCL_START */
114 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
115 sqlite3_finalize(stmt);
116 calendar_record_destroy(*out_record, true);
122 _cal_db_extended_get_stmt(stmt, *out_record);
124 sqlite3_finalize(stmt);
127 return CALENDAR_ERROR_NONE;
130 static int _cal_db_extended_update_record(calendar_record_h record)
132 char query[CAL_DB_SQL_MAX_LEN] = {0};
133 sqlite3_stmt *stmt = NULL;
134 cal_extended_s* extended_info = (cal_extended_s*)(record);
137 RETV_IF(NULL == extended_info, CALENDAR_ERROR_INVALID_PARAMETER);
139 if (extended_info->common.properties_flags)
140 return _cal_db_extended_update_projection(record);
142 snprintf(query, sizeof(query), "UPDATE %s SET "
149 extended_info->record_id,
150 extended_info->record_type,
153 ret = cal_db_util_query_prepare(query, &stmt);
154 if (CALENDAR_ERROR_NONE != ret) {
155 /* LCOV_EXCL_START */
156 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
157 SECURE("query[%s]", query);
162 if (extended_info->key)
163 cal_db_util_stmt_bind_text(stmt, 1, extended_info->key);
165 if (extended_info->value)
166 cal_db_util_stmt_bind_text(stmt, 2, extended_info->value);
168 ret = cal_db_util_stmt_step(stmt);
169 sqlite3_finalize(stmt);
170 if (CALENDAR_ERROR_NONE != ret) {
171 /* LCOV_EXCL_START */
172 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
177 return CALENDAR_ERROR_NONE;
180 static int _cal_db_extended_delete_record(int id)
182 char query[CAL_DB_SQL_MAX_LEN] = {0};
185 snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d",
186 CAL_TABLE_EXTENDED, id);
187 ret = cal_db_util_query_exec(query);
188 if (CALENDAR_ERROR_NONE != ret) {
189 /* LCOV_EXCL_START */
190 ERR("cal_db_util_query_exec() Fail(%d)", ret);
191 SECURE("[%s]", query);
195 return CALENDAR_ERROR_NONE;
198 static int _cal_db_extended_replace_record(calendar_record_h record, int id)
201 char query[CAL_DB_SQL_MAX_LEN] = {0};
202 sqlite3_stmt *stmt = NULL;
203 cal_extended_s* extended_info = (cal_extended_s*)(record);
205 RETV_IF(NULL == extended_info, CALENDAR_ERROR_INVALID_PARAMETER);
206 extended_info->id = id;
208 if (extended_info->common.properties_flags)
209 return _cal_db_extended_update_projection(record);
211 snprintf(query, sizeof(query), "UPDATE %s SET "
218 extended_info->record_id,
219 extended_info->record_type,
222 ret = cal_db_util_query_prepare(query, &stmt);
223 if (CALENDAR_ERROR_NONE != ret) {
224 /* LCOV_EXCL_START */
225 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
226 SECURE("query[%s]", query);
231 if (extended_info->key)
232 cal_db_util_stmt_bind_text(stmt, 1, extended_info->key);
234 if (extended_info->value)
235 cal_db_util_stmt_bind_text(stmt, 2, extended_info->value);
237 ret = cal_db_util_stmt_step(stmt);
238 sqlite3_finalize(stmt);
239 if (CALENDAR_ERROR_NONE != ret) {
240 /* LCOV_EXCL_START */
241 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
246 return CALENDAR_ERROR_NONE;
249 static int _cal_db_extended_get_all_records(int offset, int limit, calendar_list_h* out_list)
251 int ret = CALENDAR_ERROR_NONE;
252 char query[CAL_DB_SQL_MAX_LEN] = {0};
253 char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
254 char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
255 sqlite3_stmt *stmt = NULL;
257 RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
259 ret = calendar_list_create(out_list);
260 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
263 snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
266 snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
268 snprintf(query, sizeof(query), "SELECT * FROM %s %s %s", CAL_TABLE_EXTENDED, limitquery, offsetquery);
270 ret = cal_db_util_query_prepare(query, &stmt);
271 if (CALENDAR_ERROR_NONE != ret) {
272 /* LCOV_EXCL_START */
273 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
274 SECURE("query[%s]", query);
275 calendar_list_destroy(*out_list, true);
281 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
282 calendar_record_h record;
283 ret = calendar_record_create(_calendar_extended_property._uri, &record);
284 if (CALENDAR_ERROR_NONE != ret) {
285 /* LCOV_EXCL_START */
286 calendar_list_destroy(*out_list, true);
288 sqlite3_finalize(stmt);
292 _cal_db_extended_get_stmt(stmt, record);
294 ret = calendar_list_add(*out_list, record);
295 if (CALENDAR_ERROR_NONE != ret) {
296 /* LCOV_EXCL_START */
297 calendar_list_destroy(*out_list, true);
299 calendar_record_destroy(record, true);
300 sqlite3_finalize(stmt);
306 sqlite3_finalize(stmt);
307 return CALENDAR_ERROR_NONE;
310 static int _cal_db_extended_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
312 cal_query_s *que = NULL;
313 int ret = CALENDAR_ERROR_NONE;
314 char *condition = NULL;
315 char *projection = NULL;
317 GSList *bind_text = NULL, *cursor = NULL;
318 char *query_str = NULL;
319 sqlite3_stmt *stmt = NULL;
322 que = (cal_query_s *)query;
326 ret = cal_db_query_create_condition(query, &condition, &bind_text);
327 if (CALENDAR_ERROR_NONE != ret) {
328 /* LCOV_EXCL_START */
329 ERR("cal_db_query_create_condition() Fail(%d), ret");
335 /* make: projection */
336 ret = cal_db_query_create_projection(query, &projection);
338 /* query: projection */
340 cal_db_append_string(&query_str, "SELECT");
341 cal_db_append_string(&query_str, projection);
342 cal_db_append_string(&query_str, "FROM");
343 cal_db_append_string(&query_str, CAL_TABLE_EXTENDED);
344 CAL_FREE(projection);
346 cal_db_append_string(&query_str, "SELECT * FROM");
347 cal_db_append_string(&query_str, CAL_TABLE_EXTENDED);
350 /* query: condition */
352 cal_db_append_string(&query_str, "WHERE");
353 cal_db_append_string(&query_str, condition);
358 ret = cal_db_query_create_order(query, condition, &order);
360 cal_db_append_string(&query_str, order);
364 char buf[CAL_STR_SHORT_LEN32] = {0};
366 snprintf(buf, sizeof(buf), "LIMIT %d", limit);
367 cal_db_append_string(&query_str, buf);
369 snprintf(buf, sizeof(buf), "OFFSET %d", offset);
370 cal_db_append_string(&query_str, buf);
375 ret = cal_db_util_query_prepare(query_str, &stmt);
376 if (CALENDAR_ERROR_NONE != ret) {
377 /* LCOV_EXCL_START */
378 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
379 SECURE("query[%s]", query_str);
381 g_slist_free_full(bind_text, free);
391 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
392 cal_db_util_stmt_bind_text(stmt, i, cursor->data);
395 ret = calendar_list_create(out_list);
396 if (CALENDAR_ERROR_NONE != ret) {
397 /* LCOV_EXCL_START */
398 ERR("calendar_list_create() Fail");
400 g_slist_free_full(bind_text, free);
404 sqlite3_finalize(stmt);
409 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
410 calendar_record_h record;
411 ret = calendar_record_create(_calendar_extended_property._uri, &record);
412 if (CALENDAR_ERROR_NONE != ret) {
413 /* LCOV_EXCL_START */
414 calendar_list_destroy(*out_list, true);
418 g_slist_free_full(bind_text, free);
422 sqlite3_finalize(stmt);
426 if (0 < que->projection_count) {
427 cal_record_set_projection(record,
428 que->projection, que->projection_count, que->property_count);
430 _cal_db_extended_get_projection_stmt(stmt,
431 que->projection, que->projection_count,
434 _cal_db_extended_get_stmt(stmt, record);
437 ret = calendar_list_add(*out_list, record);
438 if (CALENDAR_ERROR_NONE != ret) {
439 /* LCOV_EXCL_START */
440 calendar_list_destroy(*out_list, true);
442 calendar_record_destroy(record, true);
445 g_slist_free_full(bind_text, free);
449 sqlite3_finalize(stmt);
456 g_slist_free_full(bind_text, free);
460 sqlite3_finalize(stmt);
462 return CALENDAR_ERROR_NONE;
464 static int _cal_db_extended_insert_records(const calendar_list_h list, int** ids)
466 calendar_record_h record;
472 ret = calendar_list_get_count(list, &count);
473 if (CALENDAR_ERROR_NONE != ret) {
474 /* LCOV_EXCL_START */
475 ERR("list get error");
480 id = calloc(1, sizeof(int)*count);
482 RETVM_IF(NULL == id, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc() Fail");
484 ret = calendar_list_first(list);
485 if (CALENDAR_ERROR_NONE != ret) {
486 /* LCOV_EXCL_START */
487 ERR("list first error");
493 if (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(list, &record)) {
494 ret = _cal_db_extended_insert_record(record, &id[i]);
495 if (CALENDAR_ERROR_NONE != ret) {
496 /* LCOV_EXCL_START */
497 ERR("_cal_db_extended_insert_record() Fail(%d)", ret);
499 return CALENDAR_ERROR_DB_FAILED;
504 } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
511 return CALENDAR_ERROR_NONE;
514 static int _cal_db_extended_update_records(const calendar_list_h list)
516 calendar_record_h record;
519 ret = calendar_list_first(list);
520 if (CALENDAR_ERROR_NONE != ret) {
521 /* LCOV_EXCL_START */
522 ERR("list first error");
527 if (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(list, &record)) {
528 ret = _cal_db_extended_update_record(record);
529 if (CALENDAR_ERROR_NONE != ret) {
530 /* LCOV_EXCL_START */
531 ERR("_cal_db_extended_update_record() Fail(%d)", ret);
532 return CALENDAR_ERROR_DB_FAILED;
536 } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
538 return CALENDAR_ERROR_NONE;
541 static int _cal_db_extended_delete_records(int ids[], int count)
545 for (i = 0; i < count; i++) {
546 ret = _cal_db_extended_delete_record(ids[i]);
547 if (CALENDAR_ERROR_NONE != ret) {
548 /* LCOV_EXCL_START */
549 ERR("_cal_db_extended_delete_record() Fail(%d)", ret);
550 return CALENDAR_ERROR_DB_FAILED;
554 return CALENDAR_ERROR_NONE;
557 static int _cal_db_extended_replace_records(const calendar_list_h list, int ids[], int count)
559 calendar_record_h record;
564 /* LCOV_EXCL_START */
565 ERR("Invalid argument: list is NULL");
566 return CALENDAR_ERROR_INVALID_PARAMETER;
570 ret = calendar_list_first(list);
571 if (CALENDAR_ERROR_NONE != ret) {
572 /* LCOV_EXCL_START */
573 ERR("list first error");
578 for (i = 0; i < count; i++) {
579 if (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(list, &record)) {
580 ret = _cal_db_extended_replace_record(record, ids[i]);
581 if (CALENDAR_ERROR_NONE != ret) {
582 /* LCOV_EXCL_START */
583 ERR("_cal_db_extended_replace_record() Fail(%d)", ret);
584 return CALENDAR_ERROR_DB_FAILED;
588 if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
592 return CALENDAR_ERROR_NONE;
595 static int _cal_db_extended_get_count(int *out_count)
597 char query[CAL_DB_SQL_MAX_LEN] = {0};
601 RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
603 snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_EXTENDED);
605 ret = cal_db_util_query_get_first_int_result(query, NULL, &count);
606 if (CALENDAR_ERROR_NONE != ret) {
607 /* LCOV_EXCL_START */
608 ERR("cal_db_util_query_get_first_int_result() Fail");
612 DBG("%s=%d", query, count);
615 return CALENDAR_ERROR_NONE;
618 static int _cal_db_extended_get_count_with_query(calendar_query_h query, int *out_count)
620 cal_query_s *que = NULL;
621 int ret = CALENDAR_ERROR_NONE;
622 char *condition = NULL;
623 char *query_str = NULL;
626 GSList *bind_text = NULL;
628 que = (cal_query_s *)query;
630 if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EXTENDED)) {
631 table_name = cal_strdup(CAL_TABLE_EXTENDED);
633 /* LCOV_EXCL_START */
634 ERR("uri(%s) not support get records with query", que->view_uri);
635 return CALENDAR_ERROR_INVALID_PARAMETER;
641 ret = cal_db_query_create_condition(query, &condition, &bind_text);
642 if (CALENDAR_ERROR_NONE != ret) {
643 /* LCOV_EXCL_START */
644 ERR("cal_db_query_create_condition() Fail(%d), ret");
645 CAL_FREE(table_name);
652 cal_db_append_string(&query_str, "SELECT count(*) FROM");
653 cal_db_append_string(&query_str, table_name);
654 CAL_FREE(table_name);
656 /* query: condition */
658 cal_db_append_string(&query_str, "WHERE");
659 cal_db_append_string(&query_str, condition);
664 ret = cal_db_util_query_get_first_int_result(query_str, NULL, &count);
665 if (CALENDAR_ERROR_NONE != ret) {
666 /* LCOV_EXCL_START */
667 ERR("cal_db_util_query_get_first_int_result() Fail");
669 g_slist_free_full(bind_text, free);
676 DBG("%s=%d", query_str, count);
681 g_slist_free_full(bind_text, free);
685 return CALENDAR_ERROR_NONE;
688 static void _cal_db_extended_get_stmt(sqlite3_stmt *stmt, calendar_record_h record)
690 cal_extended_s* extended = (cal_extended_s*)(record);
692 const unsigned char *temp;
694 extended->id = sqlite3_column_int(stmt, count++);
695 extended->record_id = sqlite3_column_int(stmt, count++);
696 extended->record_type = sqlite3_column_int(stmt, count++);
698 temp = sqlite3_column_text(stmt, count++);
699 extended->key = cal_strdup((const char*)temp);
701 temp = sqlite3_column_text(stmt, count++);
702 extended->value = cal_strdup((const char*)temp);
705 static void _cal_db_extended_get_property_stmt(sqlite3_stmt *stmt,
706 unsigned int property, int stmt_count, calendar_record_h record)
708 cal_extended_s* extended = (cal_extended_s*)(record);
709 const unsigned char *temp;
712 case CAL_PROPERTY_EXTENDED_ID:
713 extended->id = sqlite3_column_int(stmt, stmt_count);
715 case CAL_PROPERTY_EXTENDED_RECORD_ID:
716 extended->record_id = sqlite3_column_int(stmt, stmt_count);
718 case CAL_PROPERTY_EXTENDED_RECORD_TYPE:
719 extended->record_type = sqlite3_column_int(stmt, stmt_count);
721 case CAL_PROPERTY_EXTENDED_KEY:
722 temp = sqlite3_column_text(stmt, stmt_count);
723 extended->key = cal_strdup((const char*)temp);
725 case CAL_PROPERTY_EXTENDED_VALUE:
726 temp = sqlite3_column_text(stmt, stmt_count);
727 extended->value = cal_strdup((const char*)temp);
730 sqlite3_column_int(stmt, stmt_count);
737 static void _cal_db_extended_get_projection_stmt(sqlite3_stmt *stmt,
738 const unsigned int *projection, const int projection_count,
739 calendar_record_h record)
743 for (i = 0; i < projection_count; i++)
744 _cal_db_extended_get_property_stmt(stmt, projection[i], i, record);
747 static int _cal_db_extended_update_projection(calendar_record_h record)
750 char query[CAL_DB_SQL_MAX_LEN] = {0};
751 sqlite3_stmt *stmt = NULL;
752 cal_extended_s* extended = (cal_extended_s*)(record);
754 GSList *bind_text = NULL;
755 GSList *cursor = NULL;
757 ret = cal_db_query_create_projection_update_set(record, &set, &bind_text);
758 RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
760 snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE id = %d",
761 CAL_TABLE_EXTENDED, set, extended->id);
763 ret = cal_db_util_query_prepare(query, &stmt);
764 if (CALENDAR_ERROR_NONE != ret) {
765 /* LCOV_EXCL_START */
766 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
767 SECURE("query[%s]", query);
770 g_slist_free_full(bind_text, free);
779 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
780 cal_db_util_stmt_bind_text(stmt, i, cursor->data);
783 ret = cal_db_util_stmt_step(stmt);
784 sqlite3_finalize(stmt);
787 g_slist_free_full(bind_text, free);
790 if (CALENDAR_ERROR_NONE != ret) {
791 /* LCOV_EXCL_START */
792 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
797 return CALENDAR_ERROR_NONE;