9e9061a9a6c58a6122cff6a863242f88ffdd9037
[platform/core/pim/calendar-service.git] / server / db / cal_db_plugin_extended.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdlib.h>
21
22 #include "cal_internal.h"
23 #include "cal_typedef.h"
24 #include "cal_view.h"
25 #include "cal_record.h"
26
27 #include "cal_db_util.h"
28 #include "cal_db.h"
29 #include "cal_db_query.h"
30 #include "cal_db_plugin_extended_helper.h"
31 #include "cal_utils.h"
32
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);
46
47 /*
48  * static function
49  */
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);
58
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
74 };
75
76 static int _cal_db_extended_insert_record(calendar_record_h record, int* id)
77 {
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);
82 }
83
84 static int _cal_db_extended_get_record(int id, calendar_record_h* out_record)
85 {
86         int ret = 0;
87         char query[CAL_DB_SQL_MAX_LEN];
88         sqlite3_stmt *stmt = NULL;
89
90         ret = calendar_record_create(_calendar_extended_property._uri, out_record);
91         if (CALENDAR_ERROR_NONE != ret) {
92                 /* LCOV_EXCL_START */
93                 ERR("calendar_record_create() Fail(%d)", ret);
94                 return CALENDAR_ERROR_OUT_OF_MEMORY;
95                 /* LCOV_EXCL_STOP */
96         }
97
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);
106                 *out_record = NULL;
107                 return ret;
108                 /* LCOV_EXCL_STOP */
109         }
110
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);
117                 *out_record = NULL;
118                 return ret;
119                 /* LCOV_EXCL_STOP */
120         }
121
122         _cal_db_extended_get_stmt(stmt, *out_record);
123
124         sqlite3_finalize(stmt);
125         stmt = NULL;
126
127         return CALENDAR_ERROR_NONE;
128 }
129
130 static int _cal_db_extended_update_record(calendar_record_h record)
131 {
132         char query[CAL_DB_SQL_MAX_LEN] = {0};
133         sqlite3_stmt *stmt = NULL;
134         cal_extended_s* extended_info =  (cal_extended_s*)(record);
135         int ret = 0;
136
137         RETV_IF(NULL == extended_info, CALENDAR_ERROR_INVALID_PARAMETER);
138
139         if (extended_info->common.properties_flags)
140                 return _cal_db_extended_update_projection(record);
141
142         snprintf(query, sizeof(query), "UPDATE %s SET "
143                         "record_id=%d,"
144                         "record_type=%d,"
145                         "key=?,"
146                         "value=? "
147                         "WHERE id = %d",
148                         CAL_TABLE_EXTENDED,
149                         extended_info->record_id,
150                         extended_info->record_type,
151                         extended_info->id);
152
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);
158                 return ret;
159                 /* LCOV_EXCL_STOP */
160         }
161
162         if (extended_info->key)
163                 cal_db_util_stmt_bind_text(stmt, 1, extended_info->key);
164
165         if (extended_info->value)
166                 cal_db_util_stmt_bind_text(stmt, 2, extended_info->value);
167
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);
173                 return ret;
174                 /* LCOV_EXCL_STOP */
175         }
176
177         return CALENDAR_ERROR_NONE;
178 }
179
180 static int _cal_db_extended_delete_record(int id)
181 {
182         char query[CAL_DB_SQL_MAX_LEN] = {0};
183         int ret = 0;
184
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);
192                 return ret;
193                 /* LCOV_EXCL_STOP */
194         }
195         return CALENDAR_ERROR_NONE;
196 }
197
198 static int _cal_db_extended_replace_record(calendar_record_h record, int id)
199 {
200         int ret = 0;
201         char query[CAL_DB_SQL_MAX_LEN] = {0};
202         sqlite3_stmt *stmt = NULL;
203         cal_extended_s* extended_info =  (cal_extended_s*)(record);
204
205         RETV_IF(NULL == extended_info, CALENDAR_ERROR_INVALID_PARAMETER);
206         extended_info->id = id;
207
208         if (extended_info->common.properties_flags)
209                 return _cal_db_extended_update_projection(record);
210
211         snprintf(query, sizeof(query), "UPDATE %s SET "
212                         "record_id=%d,"
213                         "record_type=%d,"
214                         "key=?,"
215                         "value=? "
216                         "WHERE id = %d",
217                         CAL_TABLE_EXTENDED,
218                         extended_info->record_id,
219                         extended_info->record_type,
220                         id);
221
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);
227                 return ret;
228                 /* LCOV_EXCL_STOP */
229         }
230
231         if (extended_info->key)
232                 cal_db_util_stmt_bind_text(stmt, 1, extended_info->key);
233
234         if (extended_info->value)
235                 cal_db_util_stmt_bind_text(stmt, 2, extended_info->value);
236
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);
242                 return ret;
243                 /* LCOV_EXCL_STOP */
244         }
245
246         return CALENDAR_ERROR_NONE;
247 }
248
249 static int _cal_db_extended_get_all_records(int offset, int limit, calendar_list_h* out_list)
250 {
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;
256
257         RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
258
259         ret = calendar_list_create(out_list);
260         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
261
262         if (0 < offset)
263                 snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
264
265         if (0 < limit)
266                 snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
267
268         snprintf(query, sizeof(query), "SELECT * FROM %s %s %s", CAL_TABLE_EXTENDED, limitquery, offsetquery);
269
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);
276                 *out_list = NULL;
277                 return ret;
278                 /* LCOV_EXCL_STOP */
279         }
280
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);
287                         *out_list = NULL;
288                         sqlite3_finalize(stmt);
289                         return ret;
290                         /* LCOV_EXCL_STOP */
291                 }
292                 _cal_db_extended_get_stmt(stmt, record);
293
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);
298                         *out_list = NULL;
299                         calendar_record_destroy(record, true);
300                         sqlite3_finalize(stmt);
301                         return ret;
302                         /* LCOV_EXCL_STOP */
303                 }
304         }
305
306         sqlite3_finalize(stmt);
307         return CALENDAR_ERROR_NONE;
308 }
309
310 static int _cal_db_extended_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
311 {
312         cal_query_s *que = NULL;
313         int ret = CALENDAR_ERROR_NONE;
314         char *condition = NULL;
315         char *projection = NULL;
316         char *order = NULL;
317         GSList *bind_text = NULL, *cursor = NULL;
318         char *query_str = NULL;
319         sqlite3_stmt *stmt = NULL;
320         int i = 0;
321
322         que = (cal_query_s *)query;
323
324         /* make filter */
325         if (que->filter) {
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");
330                         return ret;
331                         /* LCOV_EXCL_STOP */
332                 }
333         }
334
335         /* make: projection */
336         ret = cal_db_query_create_projection(query, &projection);
337
338         /* query: projection */
339         if (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);
345         } else {
346                 cal_db_append_string(&query_str, "SELECT * FROM");
347                 cal_db_append_string(&query_str, CAL_TABLE_EXTENDED);
348         }
349
350         /* query: condition */
351         if (condition) {
352                 cal_db_append_string(&query_str, "WHERE");
353                 cal_db_append_string(&query_str, condition);
354                 CAL_FREE(condition);
355         }
356
357         /* order */
358         ret = cal_db_query_create_order(query, condition, &order);
359         if (order) {
360                 cal_db_append_string(&query_str, order);
361                 CAL_FREE(order);
362         }
363
364         char buf[CAL_STR_SHORT_LEN32] = {0};
365         if (0 < limit) {
366                 snprintf(buf, sizeof(buf), "LIMIT %d", limit);
367                 cal_db_append_string(&query_str, buf);
368                 if (0 < offset) {
369                         snprintf(buf, sizeof(buf), "OFFSET %d", offset);
370                         cal_db_append_string(&query_str, buf);
371                 }
372         }
373
374         /* query */
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);
380                 if (bind_text) {
381                         g_slist_free_full(bind_text, free);
382                         bind_text = NULL;
383                 }
384                 free(query_str);
385                 return ret;
386                 /* LCOV_EXCL_STOP */
387         }
388
389         /* bind text */
390         if (bind_text) {
391                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
392                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
393         }
394
395         ret = calendar_list_create(out_list);
396         if (CALENDAR_ERROR_NONE != ret) {
397                 /* LCOV_EXCL_START */
398                 ERR("calendar_list_create() Fail");
399                 if (bind_text) {
400                         g_slist_free_full(bind_text, free);
401                         bind_text = NULL;
402                 }
403                 CAL_FREE(query_str);
404                 sqlite3_finalize(stmt);
405                 return ret;
406                 /* LCOV_EXCL_STOP */
407         }
408
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);
415                         *out_list = NULL;
416
417                         if (bind_text) {
418                                 g_slist_free_full(bind_text, free);
419                                 bind_text = NULL;
420                         }
421                         CAL_FREE(query_str);
422                         sqlite3_finalize(stmt);
423                         return ret;
424                         /* LCOV_EXCL_STOP */
425                 }
426                 if (0 < que->projection_count) {
427                         cal_record_set_projection(record,
428                                         que->projection, que->projection_count, que->property_count);
429
430                         _cal_db_extended_get_projection_stmt(stmt,
431                                         que->projection, que->projection_count,
432                                         record);
433                 } else {
434                         _cal_db_extended_get_stmt(stmt, record);
435                 }
436
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);
441                         *out_list = NULL;
442                         calendar_record_destroy(record, true);
443
444                         if (bind_text) {
445                                 g_slist_free_full(bind_text, free);
446                                 bind_text = NULL;
447                         }
448                         CAL_FREE(query_str);
449                         sqlite3_finalize(stmt);
450                         return ret;
451                         /* LCOV_EXCL_STOP */
452                 }
453         }
454
455         if (bind_text) {
456                 g_slist_free_full(bind_text, free);
457                 bind_text = NULL;
458         }
459         CAL_FREE(query_str);
460         sqlite3_finalize(stmt);
461
462         return CALENDAR_ERROR_NONE;
463 }
464 static int _cal_db_extended_insert_records(const calendar_list_h list, int** ids)
465 {
466         calendar_record_h record;
467         int ret = 0;
468         int count = 0;
469         int i = 0;
470         int *id = NULL;
471
472         ret = calendar_list_get_count(list, &count);
473         if (CALENDAR_ERROR_NONE != ret) {
474                 /* LCOV_EXCL_START */
475                 ERR("list get error");
476                 return ret;
477                 /* LCOV_EXCL_STOP */
478         }
479
480         id = calloc(1, sizeof(int)*count);
481
482         RETVM_IF(NULL == id, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc() Fail");
483
484         ret = calendar_list_first(list);
485         if (CALENDAR_ERROR_NONE != ret) {
486                 /* LCOV_EXCL_START */
487                 ERR("list first error");
488                 CAL_FREE(id);
489                 return ret;
490                 /* LCOV_EXCL_STOP */
491         }
492         do {
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);
498                                 CAL_FREE(id);
499                                 return CALENDAR_ERROR_DB_FAILED;
500                                 /* LCOV_EXCL_STOP */
501                         }
502                 }
503                 i++;
504         } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
505
506         if (ids)
507                 *ids = id;
508         else
509                 CAL_FREE(id);
510
511         return CALENDAR_ERROR_NONE;
512 }
513
514 static int _cal_db_extended_update_records(const calendar_list_h list)
515 {
516         calendar_record_h record;
517         int ret = 0;
518
519         ret = calendar_list_first(list);
520         if (CALENDAR_ERROR_NONE != ret) {
521                 /* LCOV_EXCL_START */
522                 ERR("list first error");
523                 return ret;
524                 /* LCOV_EXCL_STOP */
525         }
526         do {
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;
533                                 /* LCOV_EXCL_STOP */
534                         }
535                 }
536         } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
537
538         return CALENDAR_ERROR_NONE;
539 }
540
541 static int _cal_db_extended_delete_records(int ids[], int count)
542 {
543         int ret = 0;
544         int i = 0;
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;
551                         /* LCOV_EXCL_STOP */
552                 }
553         }
554         return CALENDAR_ERROR_NONE;
555 }
556
557 static int _cal_db_extended_replace_records(const calendar_list_h list, int ids[], int count)
558 {
559         calendar_record_h record;
560         int i;
561         int ret = 0;
562
563         if (NULL == list) {
564                 /* LCOV_EXCL_START */
565                 ERR("Invalid argument: list is NULL");
566                 return CALENDAR_ERROR_INVALID_PARAMETER;
567                 /* LCOV_EXCL_STOP */
568         }
569
570         ret = calendar_list_first(list);
571         if (CALENDAR_ERROR_NONE != ret) {
572                 /* LCOV_EXCL_START */
573                 ERR("list first error");
574                 return ret;
575                 /* LCOV_EXCL_STOP */
576         }
577
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;
585                                 /* LCOV_EXCL_STOP */
586                         }
587                 }
588                 if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
589                         break;
590         }
591
592         return CALENDAR_ERROR_NONE;
593 }
594
595 static int _cal_db_extended_get_count(int *out_count)
596 {
597         char query[CAL_DB_SQL_MAX_LEN] = {0};
598         int count = 0;
599         int ret;
600
601         RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
602
603         snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_EXTENDED);
604
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");
609                 return ret;
610                 /* LCOV_EXCL_STOP */
611         }
612         DBG("%s=%d", query, count);
613
614         *out_count = count;
615         return CALENDAR_ERROR_NONE;
616 }
617
618 static int _cal_db_extended_get_count_with_query(calendar_query_h query, int *out_count)
619 {
620         cal_query_s *que = NULL;
621         int ret = CALENDAR_ERROR_NONE;
622         char *condition = NULL;
623         char *query_str = NULL;
624         char *table_name;
625         int count = 0;
626         GSList *bind_text = NULL;
627
628         que = (cal_query_s *)query;
629
630         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EXTENDED)) {
631                 table_name = cal_strdup(CAL_TABLE_EXTENDED);
632         } else {
633                 /* LCOV_EXCL_START */
634                 ERR("uri(%s) not support get records with query", que->view_uri);
635                 return CALENDAR_ERROR_INVALID_PARAMETER;
636                 /* LCOV_EXCL_STOP */
637         }
638
639         /* make filter */
640         if (que->filter) {
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);
646                         return ret;
647                         /* LCOV_EXCL_STOP */
648                 }
649         }
650
651         /* query: select */
652         cal_db_append_string(&query_str, "SELECT count(*) FROM");
653         cal_db_append_string(&query_str, table_name);
654         CAL_FREE(table_name);
655
656         /* query: condition */
657         if (condition) {
658                 cal_db_append_string(&query_str, "WHERE");
659                 cal_db_append_string(&query_str, condition);
660                 CAL_FREE(condition);
661         }
662
663         /* query */
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");
668                 if (bind_text) {
669                         g_slist_free_full(bind_text, free);
670                         bind_text = NULL;
671                 }
672                 CAL_FREE(query_str);
673                 return ret;
674                 /* LCOV_EXCL_STOP */
675         }
676         DBG("%s=%d", query_str, count);
677
678         *out_count = count;
679
680         if (bind_text) {
681                 g_slist_free_full(bind_text, free);
682                 bind_text = NULL;
683         }
684         CAL_FREE(query_str);
685         return CALENDAR_ERROR_NONE;
686 }
687
688 static void _cal_db_extended_get_stmt(sqlite3_stmt *stmt, calendar_record_h record)
689 {
690         cal_extended_s* extended =  (cal_extended_s*)(record);
691         int count = 0;
692         const unsigned char *temp;
693
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++);
697
698         temp = sqlite3_column_text(stmt, count++);
699         extended->key = cal_strdup((const char*)temp);
700
701         temp = sqlite3_column_text(stmt, count++);
702         extended->value = cal_strdup((const char*)temp);
703 }
704
705 static void _cal_db_extended_get_property_stmt(sqlite3_stmt *stmt,
706                 unsigned int property, int stmt_count, calendar_record_h record)
707 {
708         cal_extended_s* extended =  (cal_extended_s*)(record);
709         const unsigned char *temp;
710
711         switch (property) {
712         case CAL_PROPERTY_EXTENDED_ID:
713                 extended->id = sqlite3_column_int(stmt, stmt_count);
714                 break;
715         case CAL_PROPERTY_EXTENDED_RECORD_ID:
716                 extended->record_id = sqlite3_column_int(stmt, stmt_count);
717                 break;
718         case CAL_PROPERTY_EXTENDED_RECORD_TYPE:
719                 extended->record_type = sqlite3_column_int(stmt, stmt_count);
720                 break;
721         case CAL_PROPERTY_EXTENDED_KEY:
722                 temp = sqlite3_column_text(stmt, stmt_count);
723                 extended->key = cal_strdup((const char*)temp);
724                 break;
725         case CAL_PROPERTY_EXTENDED_VALUE:
726                 temp = sqlite3_column_text(stmt, stmt_count);
727                 extended->value = cal_strdup((const char*)temp);
728                 break;
729         default:
730                 sqlite3_column_int(stmt, stmt_count);
731                 break;
732         }
733
734         return;
735 }
736
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)
740 {
741         int i = 0;
742
743         for (i = 0; i < projection_count; i++)
744                 _cal_db_extended_get_property_stmt(stmt, projection[i], i, record);
745 }
746
747 static int _cal_db_extended_update_projection(calendar_record_h record)
748 {
749         int ret = 0;
750         char query[CAL_DB_SQL_MAX_LEN] = {0};
751         sqlite3_stmt *stmt = NULL;
752         cal_extended_s* extended =  (cal_extended_s*)(record);
753         char* set = NULL;
754         GSList *bind_text = NULL;
755         GSList *cursor = NULL;
756
757         ret = cal_db_query_create_projection_update_set(record, &set, &bind_text);
758         RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
759
760         snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE id = %d",
761                         CAL_TABLE_EXTENDED, set, extended->id);
762
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);
768                 free(set);
769                 if (bind_text) {
770                         g_slist_free_full(bind_text, free);
771                         bind_text = NULL;
772                 }
773                 return ret;
774                 /* LCOV_EXCL_STOP */
775         }
776
777         if (bind_text) {
778                 int i = 0;
779                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
780                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
781         }
782
783         ret = cal_db_util_stmt_step(stmt);
784         sqlite3_finalize(stmt);
785         free(set);
786         if (bind_text) {
787                 g_slist_free_full(bind_text, free);
788                 bind_text = NULL;
789         }
790         if (CALENDAR_ERROR_NONE != ret) {
791                 /* LCOV_EXCL_START */
792                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
793                 return ret;
794                 /* LCOV_EXCL_STOP */
795         }
796
797         return CALENDAR_ERROR_NONE;
798 }