releasing notification
[platform/core/api/notification.git] / src / notification_noti.c
1 /*
2  *  libnotification
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>, Youngsub Ko <ys4610.ko@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include <vconf.h>
27
28 #include <notification.h>
29 #include <notification_db.h>
30 #include <notification_noti.h>
31 #include <notification_debug.h>
32 #include <notification_internal.h>
33
34 #define NOTI_BURST_DELETE_UNIT 10
35
36 static int _notification_noti_bind_query_text(sqlite3_stmt * stmt, const char *name,
37                                          const char *str)
38 {
39         int ret = 0;
40         int index = 0;
41
42         index = sqlite3_bind_parameter_index(stmt, name);
43         if (index == 0) {
44                 NOTIFICATION_ERR("Insert : invalid column name");
45                 return NOTIFICATION_ERROR_FROM_DB;
46         }
47
48         ret =
49             sqlite3_bind_text(stmt, index, NOTIFICATION_CHECK_STR(str), -1,
50                               SQLITE_STATIC);
51         if (ret != SQLITE_OK) {
52                 NOTIFICATION_ERR("Insert text : %s",
53                                  NOTIFICATION_CHECK_STR(str));
54                 return NOTIFICATION_ERROR_FROM_DB;
55         }
56
57         return NOTIFICATION_ERROR_NONE;
58 }
59
60 static int _notification_noti_bind_query_double(sqlite3_stmt * stmt, const char *name,
61                                          double val)
62 {
63         int ret = 0;
64         int index = 0;
65
66         index = sqlite3_bind_parameter_index(stmt, name);
67         if (index == 0) {
68                 NOTIFICATION_ERR("Insert : invalid column name");
69                 return NOTIFICATION_ERROR_FROM_DB;
70         }
71
72         ret = sqlite3_bind_double(stmt, index, val);
73         if (ret != SQLITE_OK) {
74                 NOTIFICATION_ERR("Insert double : %f", val);
75                 return NOTIFICATION_ERROR_FROM_DB;
76         }
77
78         return NOTIFICATION_ERROR_NONE;
79 }
80
81 static int _notification_noti_check_priv_id(notification_h noti, sqlite3 * db)
82 {
83         sqlite3_stmt *stmt = NULL;
84         char query[NOTIFICATION_QUERY_MAX] = { 0, };
85         int ret = NOTIFICATION_ERROR_NONE, result = 0;
86
87         /* Make query to check priv_id exist */
88         snprintf(query, sizeof(query),
89                  "select count(*) from noti_list where caller_pkgname = '%s' and priv_id = %d",
90                  noti->caller_pkgname, noti->priv_id);
91
92         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
93         if (ret != SQLITE_OK) {
94                 NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
95                                  sqlite3_errmsg(db));
96                 return NOTIFICATION_ERROR_FROM_DB;
97         }
98
99         ret = sqlite3_step(stmt);
100         if (ret == SQLITE_ROW) {
101                 result = sqlite3_column_int(stmt, 0);
102         } else {
103                 result = 0;
104         }
105
106         sqlite3_finalize(stmt);
107
108         /* If result > 0, there is priv_id in DB */
109         if (result > 0) {
110                 return NOTIFICATION_ERROR_ALREADY_EXIST_ID;
111         }
112
113         return NOTIFICATION_ERROR_NONE;
114 }
115
116 static int _notification_noti_get_priv_id(notification_h noti, sqlite3 * db)
117 {
118         sqlite3_stmt *stmt = NULL;
119         char query[NOTIFICATION_QUERY_MAX] = { 0, };
120         int ret = NOTIFICATION_ERROR_NONE, result = 0;
121
122         /* Make query to get max priv_id */
123         snprintf(query, sizeof(query),
124                  "select max(priv_id) from noti_list where caller_pkgname = '%s'",
125                  noti->caller_pkgname);
126
127         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
128         if (ret != SQLITE_OK) {
129                 NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
130                                  sqlite3_errmsg(db));
131                 return NOTIFICATION_ERROR_FROM_DB;
132         }
133
134         ret = sqlite3_step(stmt);
135         if (ret == SQLITE_ROW) {
136                 result = sqlite3_column_int(stmt, 0);
137         } else {
138                 result = 0;
139         }
140
141         sqlite3_finalize(stmt);
142
143         if (result < 0) {
144                 return NOTIFICATION_ERROR_FROM_DB;
145         }
146
147         /* Increase result(max priv_id value) for next priv_id */
148         noti->priv_id = result + 1;
149
150         return NOTIFICATION_ERROR_NONE;
151 }
152
153 static int _notification_noti_get_internal_group_id_by_priv_id(const char *pkgname,
154                                                                int priv_id,
155                                                                sqlite3 * db)
156 {
157         sqlite3_stmt *stmt = NULL;
158         char query[NOTIFICATION_QUERY_MAX] = { 0, };
159         int ret = NOTIFICATION_ERROR_NONE, result = 0;
160
161         snprintf(query, sizeof(query),
162                  "select internal_group_id from noti_list where caller_pkgname = '%s' and priv_id = %d",
163                  pkgname, priv_id);
164
165         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
166         if (ret != SQLITE_OK) {
167                 NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
168                                  sqlite3_errmsg(db));
169                 return NOTIFICATION_ERROR_FROM_DB;
170         }
171
172         ret = sqlite3_step(stmt);
173         if (ret == SQLITE_ROW) {
174                 result = sqlite3_column_int(stmt, 0);
175         } else {
176                 result = 0;
177         }
178
179         sqlite3_finalize(stmt);
180
181         return result;
182 }
183
184 static int _notification_noti_get_max_internal_group_id(notification_h noti,
185                                                         sqlite3 * db)
186 {
187         sqlite3_stmt *stmt = NULL;
188         char query[NOTIFICATION_QUERY_MAX] = { 0, };
189         int ret = NOTIFICATION_ERROR_NONE, result = 0;
190
191         /* Get max internal group id */
192         snprintf(query, sizeof(query),
193                  "select max(internal_group_id) from noti_list");
194
195         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
196         if (ret != SQLITE_OK) {
197                 NOTIFICATION_ERR("Get count DB err(%d) : %s", ret,
198                                  sqlite3_errmsg(db));
199                 return NOTIFICATION_ERROR_FROM_DB;
200         }
201
202         ret = sqlite3_step(stmt);
203         if (ret == SQLITE_ROW) {
204                 result = sqlite3_column_int(stmt, 0);
205         } else {
206                 result = 0;
207         }
208
209         sqlite3_finalize(stmt);
210
211         return result;
212 }
213
214 static int _notification_noti_get_internal_group_id(notification_h noti,
215                                                     sqlite3 * db)
216 {
217         sqlite3_stmt *stmt = NULL;
218         char query[NOTIFICATION_QUERY_MAX] = { 0, };
219         int ret = NOTIFICATION_ERROR_NONE, result = 0;
220         const char *ret_title = NULL;
221         char buf_key[32] = { 0, };
222
223         if (noti->group_id == NOTIFICATION_GROUP_ID_NONE) {
224                 /* If Group ID is NONE Get max internal group ID */
225                 result = _notification_noti_get_max_internal_group_id(noti, db);
226                 if (result < 0) {
227                         return NOTIFICATION_ERROR_FROM_DB;
228                 }
229
230                 /* Internal Group ID is max internal group ID + 1 */
231                 noti->internal_group_id = result + 1;
232
233                 return NOTIFICATION_ERROR_NONE;
234         } else if (noti->group_id == NOTIFICATION_GROUP_ID_DEFAULT) {
235                 /* If Group ID is DEFAULT, Get internal group id if it exist */
236                 if (noti->b_key != NULL) {
237                         snprintf(buf_key, sizeof(buf_key), "%d",
238                                  NOTIFICATION_TEXT_TYPE_TITLE);
239
240                         ret_title = bundle_get_val(noti->b_key, buf_key);
241                 }
242
243                 if (ret_title == NULL && noti->b_text != NULL) {
244                         snprintf(buf_key, sizeof(buf_key), "%d",
245                                  NOTIFICATION_TEXT_TYPE_TITLE);
246
247                         ret_title = bundle_get_val(noti->b_text, buf_key);
248                 }
249
250                 if (ret_title == NULL) {
251                         ret_title = noti->caller_pkgname;
252                 }
253
254                 snprintf(query, sizeof(query),
255                          "select internal_group_id from noti_list where title_key = $title_key and group_id = %d",
256                          NOTIFICATION_GROUP_ID_DEFAULT);
257         } else {
258                 /* If Group ID is > DEFAULT, Get internal group id if it exit */
259                 snprintf(query, sizeof(query),
260                          "select internal_group_id from noti_list where caller_pkgname = '%s' and group_id = %d",
261                          NOTIFICATION_CHECK_STR(noti->caller_pkgname),
262                          noti->group_id);
263         }
264
265         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
266         if (ret != SQLITE_OK) {
267                 NOTIFICATION_ERR("Select Query : %s", query);
268                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
269                                  sqlite3_errmsg(db));
270                 if (stmt) {
271                         sqlite3_finalize(stmt);
272                 }
273                 return NOTIFICATION_ERROR_FROM_DB;
274         }
275
276         /* Bind query */
277         if (ret_title != NULL) {
278                 ret =
279                     _notification_noti_bind_query_text(stmt, "$title_key",
280                                                   NOTIFICATION_CHECK_STR
281                                                   (ret_title));
282                 if (ret != NOTIFICATION_ERROR_NONE) {
283                         NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
284                         if (stmt) {
285                                 sqlite3_finalize(stmt);
286                         }
287                         return ret;
288                 }
289         }
290
291         ret = sqlite3_step(stmt);
292         if (ret == SQLITE_ROW) {
293                 result = sqlite3_column_int(stmt, 0);
294         } else {
295                 /* If there is not internal_group_id, create new one */
296                 result = _notification_noti_get_max_internal_group_id(noti, db);
297                 result++;
298         }
299
300         sqlite3_finalize(stmt);
301
302         noti->internal_group_id = result;
303
304         return NOTIFICATION_ERROR_NONE;
305 }
306
307 static int _notification_noti_make_query(notification_h noti, char *query,
308                                          int query_size)
309 {
310         char *args = NULL;
311         char *group_args = NULL;
312         char *b_image_path = NULL;
313         char *b_execute_option = NULL;
314         char *b_service_responding = NULL;
315         char *b_service_single_launch = NULL;
316         char *b_service_multi_launch = NULL;
317         char *b_text = NULL;
318         char *b_key = NULL;
319         char *b_format_args = NULL;
320         int flag_simmode = 0;
321
322         /* Decode bundle to insert DB */
323         if (noti->args) {
324                 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
325         }
326         if (noti->group_args) {
327                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
328                               NULL);
329         }
330
331         if (noti->b_execute_option) {
332                 bundle_encode(noti->b_execute_option,
333                               (bundle_raw **) & b_execute_option, NULL);
334         }
335         if (noti->b_service_responding) {
336                 bundle_encode(noti->b_service_responding,
337                               (bundle_raw **) & b_service_responding, NULL);
338         }
339         if (noti->b_service_single_launch) {
340                 bundle_encode(noti->b_service_single_launch,
341                               (bundle_raw **) & b_service_single_launch, NULL);
342         }
343         if (noti->b_service_multi_launch) {
344                 bundle_encode(noti->b_service_multi_launch,
345                               (bundle_raw **) & b_service_multi_launch, NULL);
346         }
347
348         if (noti->b_text) {
349                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, NULL);
350         }
351         if (noti->b_key) {
352                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, NULL);
353         }
354         if (noti->b_format_args) {
355                 bundle_encode(noti->b_format_args,
356                               (bundle_raw **) & b_format_args, NULL);
357         }
358
359         if (noti->b_image_path) {
360                 bundle_encode(noti->b_image_path,
361                               (bundle_raw **) & b_image_path, NULL);
362         }
363
364         /* Check only simmode property is enable */
365         if (noti->flags_for_property & NOTIFICATION_PROP_DISPLAY_ONLY_SIMMODE) {
366                 flag_simmode = 1;
367         }
368
369         /* Make query */
370         snprintf(query, query_size, "insert into noti_list ("
371                  "type, "
372                  "layout, "
373                  "caller_pkgname, launch_pkgname, "
374                  "image_path, "
375                  "group_id, internal_group_id, priv_id, "
376                  "title_key, "
377                  "b_text, b_key, b_format_args, num_format_args, "
378                  "text_domain, text_dir, "
379                  "time, insert_time, "
380                  "args, group_args, "
381                  "b_execute_option, "
382                  "b_service_responding, b_service_single_launch, b_service_multi_launch, "
383                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
384                  "flags_for_property, flag_simmode, display_applist, "
385                  "progress_size, progress_percentage) values ("
386                  "%d, "
387                  "%d, "
388                  "'%s', '%s', "
389                  "'%s', "
390                  "%d, %d, %d, "
391                  "$title_key, "
392                  "'%s', '%s', '%s', %d, "
393                  "'%s', '%s', "
394                  "%d, %d, "
395                  "'%s', '%s', "
396                  "'%s', "
397                  "'%s', '%s', '%s', "
398                  "%d, '%s', %d, '%s', %d, %d, %d, %d,"
399                  "%d, %d, %d, "
400                  "$progress_size, $progress_percentage)",
401                  noti->type,
402                  noti->layout,
403                  NOTIFICATION_CHECK_STR(noti->caller_pkgname),
404                  NOTIFICATION_CHECK_STR(noti->launch_pkgname),
405                  NOTIFICATION_CHECK_STR(b_image_path), noti->group_id,
406                  noti->internal_group_id, noti->priv_id,
407                  NOTIFICATION_CHECK_STR(b_text), NOTIFICATION_CHECK_STR(b_key),
408                  NOTIFICATION_CHECK_STR(b_format_args), noti->num_format_args,
409                  NOTIFICATION_CHECK_STR(noti->domain),
410                  NOTIFICATION_CHECK_STR(noti->dir), (int)noti->time,
411                  (int)noti->insert_time, NOTIFICATION_CHECK_STR(args),
412                  NOTIFICATION_CHECK_STR(group_args),
413                  NOTIFICATION_CHECK_STR(b_execute_option),
414                  NOTIFICATION_CHECK_STR(b_service_responding),
415                  NOTIFICATION_CHECK_STR(b_service_single_launch),
416                  NOTIFICATION_CHECK_STR(b_service_multi_launch),
417                  noti->sound_type, NOTIFICATION_CHECK_STR(noti->sound_path),
418                  noti->vibration_type,
419                  NOTIFICATION_CHECK_STR(noti->vibration_path),
420                  noti->led_operation,
421                  noti->led_argb,
422                  noti->led_on_ms,
423                  noti->led_off_ms,
424                  noti->flags_for_property, flag_simmode, noti->display_applist);
425
426         /* Free decoded data */
427         if (args) {
428                 free(args);
429         }
430         if (group_args) {
431                 free(group_args);
432         }
433
434         if (b_execute_option) {
435                 free(b_execute_option);
436         }
437         if (b_service_responding) {
438                 free(b_service_responding);
439         }
440         if (b_service_single_launch) {
441                 free(b_service_single_launch);
442         }
443         if (b_service_multi_launch) {
444                 free(b_service_multi_launch);
445         }
446
447         if (b_text) {
448                 free(b_text);
449         }
450         if (b_key) {
451                 free(b_key);
452         }
453         if (b_format_args) {
454                 free(b_format_args);
455         }
456
457         if (b_image_path) {
458                 free(b_image_path);
459         }
460
461         return NOTIFICATION_ERROR_NONE;
462 }
463
464
465 static int _notification_noti_make_update_query(notification_h noti, char *query,
466                                          int query_size)
467 {
468         char *args = NULL;
469         char *group_args = NULL;
470         char *b_image_path = NULL;
471         char *b_execute_option = NULL;
472         char *b_service_responding = NULL;
473         char *b_service_single_launch = NULL;
474         char *b_service_multi_launch = NULL;
475         char *b_text = NULL;
476         char *b_key = NULL;
477         char *b_format_args = NULL;
478         int flag_simmode = 0;
479
480         /* Decode bundle to update DB */
481         if (noti->args) {
482                 bundle_encode(noti->args, (bundle_raw **) & args, NULL);
483         }
484         if (noti->group_args) {
485                 bundle_encode(noti->group_args, (bundle_raw **) & group_args,
486                               NULL);
487         }
488
489         if (noti->b_execute_option) {
490                 bundle_encode(noti->b_execute_option,
491                               (bundle_raw **) & b_execute_option, NULL);
492         }
493         if (noti->b_service_responding) {
494                 bundle_encode(noti->b_service_responding,
495                               (bundle_raw **) & b_service_responding, NULL);
496         }
497         if (noti->b_service_single_launch) {
498                 bundle_encode(noti->b_service_single_launch,
499                               (bundle_raw **) & b_service_single_launch, NULL);
500         }
501         if (noti->b_service_multi_launch) {
502                 bundle_encode(noti->b_service_multi_launch,
503                               (bundle_raw **) & b_service_multi_launch, NULL);
504         }
505
506         if (noti->b_text) {
507                 bundle_encode(noti->b_text, (bundle_raw **) & b_text, NULL);
508         }
509         if (noti->b_key) {
510                 bundle_encode(noti->b_key, (bundle_raw **) & b_key, NULL);
511         }
512         if (noti->b_format_args) {
513                 bundle_encode(noti->b_format_args,
514                               (bundle_raw **) & b_format_args, NULL);
515         }
516
517         if (noti->b_image_path) {
518                 bundle_encode(noti->b_image_path,
519                               (bundle_raw **) & b_image_path, NULL);
520         }
521
522         /* Check only simmode property is enable */
523         if (noti->flags_for_property & NOTIFICATION_PROP_DISPLAY_ONLY_SIMMODE) {
524                 flag_simmode = 1;
525         }
526
527         /* Make query */
528         snprintf(query, query_size, "update noti_list set "
529                  "type = %d, "
530                  "layout = %d, "
531                  "launch_pkgname = '%s', "
532                  "image_path = '%s', "
533                  "b_text = '%s', b_key = '%s', "
534                  "b_format_args = '%s', num_format_args = %d, "
535                  "text_domain = '%s', text_dir = '%s', "
536                  "time = %d, insert_time = %d, "
537                  "args = '%s', group_args = '%s', "
538                  "b_execute_option = '%s', "
539                  "b_service_responding = '%s', "
540                  "b_service_single_launch = '%s', "
541                  "b_service_multi_launch = '%s', "
542                  "sound_type = %d, sound_path = '%s', "
543                  "vibration_type = %d, vibration_path = '%s', "
544                  "led_operation = %d, led_argb = %d, "
545                  "led_on_ms = %d, led_off_ms = %d, "
546                  "flags_for_property = %d, flag_simmode = %d, "
547                  "display_applist = %d, "
548                  "progress_size = $progress_size, progress_percentage = $progress_percentage "
549                  "where priv_id = %d ",
550                  noti->type,
551                  noti->layout,
552                  NOTIFICATION_CHECK_STR(noti->launch_pkgname),
553                  NOTIFICATION_CHECK_STR(b_image_path),
554                  NOTIFICATION_CHECK_STR(b_text), NOTIFICATION_CHECK_STR(b_key),
555                  NOTIFICATION_CHECK_STR(b_format_args), noti->num_format_args,
556                  NOTIFICATION_CHECK_STR(noti->domain),
557                  NOTIFICATION_CHECK_STR(noti->dir),
558                  (int)noti->time, (int)noti->insert_time,
559                  NOTIFICATION_CHECK_STR(args), NOTIFICATION_CHECK_STR(group_args),
560                  NOTIFICATION_CHECK_STR(b_execute_option),
561                  NOTIFICATION_CHECK_STR(b_service_responding),
562                  NOTIFICATION_CHECK_STR(b_service_single_launch),
563                  NOTIFICATION_CHECK_STR(b_service_multi_launch),
564                  noti->sound_type, NOTIFICATION_CHECK_STR(noti->sound_path),
565                  noti->vibration_type,
566                  NOTIFICATION_CHECK_STR(noti->vibration_path),
567                  noti->led_operation,
568                  noti->led_argb,
569                  noti->led_on_ms,
570                  noti->led_off_ms,
571                  noti->flags_for_property, flag_simmode, noti->display_applist,
572                  noti->priv_id);
573
574         /* Free decoded data */
575         if (args) {
576                 free(args);
577         }
578         if (group_args) {
579                 free(group_args);
580         }
581
582         if (b_execute_option) {
583                 free(b_execute_option);
584         }
585         if (b_service_responding) {
586                 free(b_service_responding);
587         }
588         if (b_service_single_launch) {
589                 free(b_service_single_launch);
590         }
591         if (b_service_multi_launch) {
592                 free(b_service_multi_launch);
593         }
594
595         if (b_text) {
596                 free(b_text);
597         }
598         if (b_key) {
599                 free(b_key);
600         }
601         if (b_format_args) {
602                 free(b_format_args);
603         }
604
605         if (b_image_path) {
606                 free(b_image_path);
607         }
608
609         return NOTIFICATION_ERROR_NONE;
610 }
611
612 static void _notification_noti_populate_from_stmt(sqlite3_stmt * stmt, notification_h noti) {
613         int col = 0;
614
615         if (stmt == NULL || noti == NULL) {
616                 return ;
617         }
618
619         noti->type = sqlite3_column_int(stmt, col++);
620         noti->layout = sqlite3_column_int(stmt, col++);
621         noti->caller_pkgname = notification_db_column_text(stmt, col++);
622         noti->launch_pkgname = notification_db_column_text(stmt, col++);
623         noti->b_image_path = notification_db_column_bundle(stmt, col++);
624         noti->group_id = sqlite3_column_int(stmt, col++);
625         noti->internal_group_id = 0;
626         noti->priv_id = sqlite3_column_int(stmt, col++);
627
628         noti->b_text = notification_db_column_bundle(stmt, col++);
629         noti->b_key = notification_db_column_bundle(stmt, col++);
630         noti->b_format_args = notification_db_column_bundle(stmt, col++);
631         noti->num_format_args = sqlite3_column_int(stmt, col++);
632
633         noti->domain = notification_db_column_text(stmt, col++);
634         noti->dir = notification_db_column_text(stmt, col++);
635         noti->time = sqlite3_column_int(stmt, col++);
636         noti->insert_time = sqlite3_column_int(stmt, col++);
637         noti->args = notification_db_column_bundle(stmt, col++);
638         noti->group_args = notification_db_column_bundle(stmt, col++);
639
640         noti->b_execute_option = notification_db_column_bundle(stmt, col++);
641         noti->b_service_responding = notification_db_column_bundle(stmt, col++);
642         noti->b_service_single_launch =
643             notification_db_column_bundle(stmt, col++);
644         noti->b_service_multi_launch =
645             notification_db_column_bundle(stmt, col++);
646
647         noti->sound_type = sqlite3_column_int(stmt, col++);
648         noti->sound_path = notification_db_column_text(stmt, col++);
649         noti->vibration_type = sqlite3_column_int(stmt, col++);
650         noti->vibration_path = notification_db_column_text(stmt, col++);
651         noti->led_operation = sqlite3_column_int(stmt, col++);
652         noti->led_argb = sqlite3_column_int(stmt, col++);
653         noti->led_on_ms = sqlite3_column_int(stmt, col++);
654         noti->led_off_ms = sqlite3_column_int(stmt, col++);
655
656         noti->flags_for_property = sqlite3_column_int(stmt, col++);
657         noti->display_applist = sqlite3_column_int(stmt, col++);
658         noti->progress_size = sqlite3_column_double(stmt, col++);
659         noti->progress_percentage = sqlite3_column_double(stmt, col++);
660
661         noti->app_icon_path = NULL;
662         noti->app_name = NULL;
663         noti->temp_title = NULL;
664         noti->temp_content = NULL;
665 }
666
667 static notification_h _notification_noti_get_item(sqlite3_stmt * stmt)
668 {
669         notification_h noti = NULL;
670
671         noti = malloc(sizeof(struct _notification));
672         if (noti == NULL) {
673                 return NULL;
674         }
675
676         _notification_noti_populate_from_stmt(stmt, noti);
677
678         return noti;
679 }
680
681 int notification_noti_set_tag(const char *tag, char *value, char *buf, int buf_len)
682 {
683         int len_total = 0;
684
685         len_total += (strlen(tag) * 2) + 5 + strlen(value) + 1;
686
687         if (buf_len <= len_total)
688                 return NOTIFICATION_ERROR_INVALID_DATA;
689
690         snprintf(buf, buf_len, "<%s>%s</%s>", tag, value, tag);
691
692         return NOTIFICATION_ERROR_NONE;
693 }
694
695 char *notification_noti_strip_tag(const char *tagged_str)
696 {
697         if (tagged_str == NULL)
698                 return NULL;
699
700         int len_total = strlen(tagged_str);
701
702         if (len_total == 0)
703                 return NULL;
704
705         char *b_f_e = strstr(tagged_str, ">");
706         char *b_e_s = strstr(tagged_str, "</");
707
708         if (b_f_e == NULL || b_e_s == NULL || (b_e_s - b_f_e - 1) <= 0)
709                 return NULL;
710
711         return strndup(b_f_e + 1, b_e_s - b_f_e - 1);
712 }
713
714 int notification_noti_get_tag_type(const char *tagged_str)
715 {
716         if (tagged_str == NULL)
717                 return TAG_TYPE_INVALID;
718
719         if (strlen(tagged_str)== 0)
720                 return TAG_TYPE_INVALID;
721
722         char *b_f_s = strstr(tagged_str, "<");
723         char *b_f_e = strstr(tagged_str, ">");
724
725         if (b_f_s == NULL || b_f_e == NULL || (b_f_e - b_f_s - 1) <= 0)
726                 return TAG_TYPE_INVALID;
727
728         char *start = b_f_s + 1;
729         int len_tag = b_f_e - b_f_s - 1;
730
731         if (strncmp(start,TAG_TIME,len_tag) == 0) {
732                 return TAG_TYPE_TIME;
733         }
734
735         return TAG_TYPE_INVALID;
736 }
737
738 static int _notification_noti_update_priv_id(sqlite3 * db, int rowid)
739 {
740         char query[128] = { 0, };
741
742         if (db == NULL) {
743                 return NOTIFICATION_ERROR_INVALID_DATA;
744         }
745
746         snprintf(query, sizeof(query), "update noti_list set "
747                         "priv_id = %d, internal_group_id = %d where rowid = %d",
748                         rowid, rowid, rowid);
749
750         return notification_db_exec(db, query, NULL);
751 }
752
753 EXPORT_API int notification_noti_insert(notification_h noti)
754 {
755         sqlite3 *db = NULL;
756         sqlite3_stmt *stmt = NULL;
757         char query[NOTIFICATION_QUERY_MAX] = { 0, };
758         int ret = 0;
759         char buf_key[32] = { 0, };
760         const char *title_key = NULL;
761
762         /* Open DB */
763         db = notification_db_open(DBPATH);
764         if (!db) {
765                 return NOTIFICATION_ERROR_FROM_DB;
766         }
767
768         /* Initialize private ID */
769         noti->priv_id = NOTIFICATION_PRIV_ID_NONE;
770         noti->group_id = NOTIFICATION_GROUP_ID_NONE;
771         noti->internal_group_id = NOTIFICATION_GROUP_ID_NONE;
772
773         /* make query */
774         ret = _notification_noti_make_query(noti, query, sizeof(query));
775         if (ret != NOTIFICATION_ERROR_NONE) {
776                 goto err;
777         }
778
779         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
780         if (ret != SQLITE_OK) {
781                 NOTIFICATION_ERR("Insert Query : %s", query);
782                 NOTIFICATION_ERR("Insert DB error(%d) : %s", ret,
783                                  sqlite3_errmsg(db));
784                 ret = NOTIFICATION_ERROR_FROM_DB;
785                 goto err;
786         }
787
788         /* Get title key */
789         if (noti->b_key != NULL) {
790                 snprintf(buf_key, sizeof(buf_key), "%d",
791                          NOTIFICATION_TEXT_TYPE_TITLE);
792
793                 title_key = bundle_get_val(noti->b_key, buf_key);
794         }
795
796         if (title_key == NULL && noti->b_text != NULL) {
797                 snprintf(buf_key, sizeof(buf_key), "%d",
798                          NOTIFICATION_TEXT_TYPE_TITLE);
799
800                 title_key = bundle_get_val(noti->b_text, buf_key);
801         }
802
803         if (title_key == NULL) {
804                 title_key = noti->caller_pkgname;
805         }
806
807         /* Bind query */
808         ret = _notification_noti_bind_query_text(stmt, "$title_key", title_key);
809         if (ret != NOTIFICATION_ERROR_NONE) {
810                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
811                 goto err;
812         }
813         ret = _notification_noti_bind_query_double(stmt, "$progress_size",noti->progress_size);
814         if (ret != NOTIFICATION_ERROR_NONE) {
815                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
816                 if (stmt) {
817                         sqlite3_finalize(stmt);
818                 }
819                 return ret;
820         }
821         ret = _notification_noti_bind_query_double(stmt, "$progress_percentage",noti->progress_percentage);
822         if (ret != NOTIFICATION_ERROR_NONE) {
823                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
824                 if (stmt) {
825                         sqlite3_finalize(stmt);
826                 }
827                 return ret;
828         }
829
830         ret = sqlite3_step(stmt);
831         if (ret == SQLITE_OK || ret == SQLITE_DONE) {
832                 noti->priv_id = (int)sqlite3_last_insert_rowid(db);
833                 if (_notification_noti_update_priv_id(db, noti->priv_id) == 0) {
834                         ret = NOTIFICATION_ERROR_NONE;
835                 } else {
836                         ret = NOTIFICATION_ERROR_FROM_DB;
837                 }
838         } else {
839                 ret = NOTIFICATION_ERROR_FROM_DB;
840         }
841 err:
842         if (stmt) {
843                 sqlite3_finalize(stmt);
844         }
845
846         /* Close DB */
847         if (db) {
848                 notification_db_close(&db);
849         }
850
851         return ret;
852 }
853
854 int notification_noti_get_by_priv_id(notification_h noti, char *pkgname, int priv_id)
855 {
856         sqlite3 *db = NULL;
857         sqlite3_stmt *stmt = NULL;
858         char query[NOTIFICATION_QUERY_MAX] = { 0, };
859         int ret = 0;
860
861         if (priv_id < 0 || noti == NULL) {
862                 ret = NOTIFICATION_ERROR_INVALID_DATA;
863                 goto err;
864         }
865
866         /* Open DB */
867         db = notification_db_open(DBPATH);
868         if (!db) {
869                 return NOTIFICATION_ERROR_FROM_DB;
870         }
871
872         char *base_query = "select "
873                          "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
874                          "b_text, b_key, b_format_args, num_format_args, "
875                          "text_domain, text_dir, time, insert_time, args, group_args, "
876                          "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
877                          "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
878                          "flags_for_property, display_applist, progress_size, progress_percentage "
879                          "from noti_list ";
880
881         if (pkgname != NULL) {
882                 snprintf(query, sizeof(query), "%s where caller_pkgname = '%s' and priv_id = %d",
883                                 base_query ,pkgname, priv_id);
884         } else {
885                 snprintf(query, sizeof(query), "%s where priv_id = %d", base_query,  priv_id);
886         }
887
888         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
889         if (ret != SQLITE_OK) {
890                 NOTIFICATION_ERR("select Query : %s", query);
891                 NOTIFICATION_ERR("select DB error(%d) : %s", ret,
892                                  sqlite3_errmsg(db));
893                 ret = NOTIFICATION_ERROR_FROM_DB;
894                 goto err;
895         }
896
897         ret = sqlite3_step(stmt);
898         if (ret == SQLITE_ROW) {
899                 _notification_noti_populate_from_stmt(stmt, noti);
900                 ret = NOTIFICATION_ERROR_NONE;
901         } else {
902                 ret = NOTIFICATION_ERROR_FROM_DB;
903         }
904 err:
905         if (stmt) {
906                 sqlite3_finalize(stmt);
907         }
908
909         /* Close DB */
910         if (db != NULL) {
911                 notification_db_close(&db);
912         }
913
914         return ret;
915 }
916
917 EXPORT_API int notification_noti_update(notification_h noti)
918 {
919         sqlite3 *db;
920         sqlite3_stmt *stmt = NULL;
921         char query[NOTIFICATION_QUERY_MAX] = { 0, };
922         int ret = 0;
923
924         /* Open DB */
925         db = notification_db_open(DBPATH);
926         if (!db) {
927                 return NOTIFICATION_ERROR_FROM_DB;
928         }
929
930         /* Check private ID is exist */
931         ret = _notification_noti_check_priv_id(noti, db);
932         if (ret != NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
933                 ret = NOTIFICATION_ERROR_NOT_EXIST_ID;
934                 goto err;
935         }
936
937         /* make update query */
938         ret = _notification_noti_make_update_query(noti, query, sizeof(query));
939         if (ret != NOTIFICATION_ERROR_NONE) {
940                 goto err;
941         }
942
943         ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
944         if (ret != SQLITE_OK) {
945                 NOTIFICATION_ERR("Insert Query : %s", query);
946                 NOTIFICATION_ERR("Insert DB error(%d) : %s", ret,
947                                  sqlite3_errmsg(db));
948                 ret = NOTIFICATION_ERROR_FROM_DB;
949                 goto err;
950         }
951
952         ret = _notification_noti_bind_query_double(stmt, "$progress_size",noti->progress_size);
953         if (ret != NOTIFICATION_ERROR_NONE) {
954                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
955                 goto err;
956         }
957         ret = _notification_noti_bind_query_double(stmt, "$progress_percentage",noti->progress_percentage);
958         if (ret != NOTIFICATION_ERROR_NONE) {
959                 NOTIFICATION_ERR("Bind error : %s", sqlite3_errmsg(db));
960                 goto err;
961         }
962
963         ret = sqlite3_step(stmt);
964         if (ret == SQLITE_OK || ret == SQLITE_DONE) {
965                 ret = NOTIFICATION_ERROR_NONE;
966         } else {
967                 ret = NOTIFICATION_ERROR_FROM_DB;
968         }
969 err:
970         if (stmt) {
971                 sqlite3_finalize(stmt);
972         }
973
974         /* Close DB */
975         if (db) {
976                 notification_db_close(&db);
977         }
978
979         return ret;
980 }
981
982 EXPORT_API int notification_noti_delete_all(notification_type_e type, const char *pkgname, int *num_deleted, int **list_deleted_rowid)
983 {
984         int ret = NOTIFICATION_ERROR_NONE;
985         int ret_tmp = NOTIFICATION_ERROR_NONE;
986         int i = 0, data_cnt = 0;
987         sqlite3 *db = NULL;
988         sqlite3_stmt *stmt = NULL;
989         char buf[128] = { 0, };
990         char query[NOTIFICATION_QUERY_MAX] = { 0, };
991         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
992         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
993
994         /* Open DB */
995         db = notification_db_open(DBPATH);
996         if (!db) {
997                 return NOTIFICATION_ERROR_FROM_DB;
998         }
999
1000         if (pkgname == NULL) {
1001                 if (type != NOTIFICATION_TYPE_NONE) {
1002                         snprintf(query_where, sizeof(query_where),
1003                                  "where type = %d ", type);
1004                 }
1005         } else {
1006                 if (type == NOTIFICATION_TYPE_NONE) {
1007                         snprintf(query_where, sizeof(query_where),
1008                                  "where caller_pkgname = '%s' ", pkgname);
1009                 } else {
1010                         snprintf(query_where, sizeof(query_where),
1011                                  "where caller_pkgname = '%s' and type = %d ",
1012                                  pkgname, type);
1013                 }
1014         }
1015
1016         if (num_deleted != NULL) {
1017                 *num_deleted = 0;
1018         }
1019         if (list_deleted_rowid != NULL) {
1020                 *list_deleted_rowid = NULL;
1021                 snprintf(query, sizeof(query),
1022                                 "select priv_id from noti_list %s ", query_where);
1023
1024                 ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1025                 if (ret != SQLITE_OK) {
1026                         NOTIFICATION_ERR("Select Query : %s", query);
1027                         NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1028                                          sqlite3_errmsg(db));
1029
1030                         ret = NOTIFICATION_ERROR_FROM_DB;
1031                         goto err;
1032                 }
1033
1034                 while(sqlite3_step(stmt) == SQLITE_ROW) {
1035                         if (data_cnt % 8 == 0) {
1036                                 int *tmp;
1037
1038                                 tmp = (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
1039                                 if (tmp) {
1040                                         *list_deleted_rowid = tmp;
1041                                 } else {
1042                                         NOTIFICATION_ERR("Heap: %s\n", strerror(errno));
1043                                         /*!
1044                                          * \TODO
1045                                          * How can I handle this?
1046                                          */
1047                                         free(*list_deleted_rowid);
1048                                         *list_deleted_rowid = NULL;
1049                                         ret = NOTIFICATION_ERROR_NO_MEMORY;
1050                                         goto err;
1051                                 }
1052                         }
1053                         *((*list_deleted_rowid) + data_cnt) = sqlite3_column_int(stmt, 0);
1054                         data_cnt++;
1055                 }
1056
1057                 if (stmt) {
1058                         sqlite3_finalize(stmt);
1059                         stmt = NULL;
1060                 }
1061
1062                 if (data_cnt > 0) {
1063                         query_where[0] = '\0';
1064                         snprintf(query_base, sizeof(query_base) - 1, "delete from noti_list");
1065                         for (i = 0; i < data_cnt ; i++) {
1066                                 if (i % NOTI_BURST_DELETE_UNIT == 0 && i != 0) {
1067                                         snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1068                                         ret_tmp = notification_db_exec(db, query, NULL);
1069                                         query_where[0] = '\0';
1070                                         if (ret == NOTIFICATION_ERROR_NONE) {
1071                                                 ret = ret_tmp;
1072                                         }
1073                                 }
1074                                 snprintf(buf, sizeof(buf) - 1, "%s%d", (i % NOTI_BURST_DELETE_UNIT == 0) ? "" : ",", *((*list_deleted_rowid) + i));
1075                                 strncat(query_where, buf,sizeof(query_where) - strlen(query_where) - 1);
1076                         }
1077                         if ((i <= NOTI_BURST_DELETE_UNIT) || ((i % NOTI_BURST_DELETE_UNIT) > 0) ) {
1078                                 snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1079                                 ret_tmp = notification_db_exec(db, query, NULL);
1080                                 if (ret == NOTIFICATION_ERROR_NONE) {
1081                                         ret = ret_tmp;
1082                                 }
1083                         }
1084                 } else {
1085                         free(*list_deleted_rowid);
1086                         *list_deleted_rowid = NULL;
1087                 }
1088
1089                 if (num_deleted != NULL) {
1090                         *num_deleted = data_cnt;
1091                 }
1092         } else {
1093                 /* Make main query */
1094                 snprintf(query_base, sizeof(query_base), "delete from noti_list ");
1095                 snprintf(query, sizeof(query), "%s %s", query_base, query_where);
1096
1097                 ret = notification_db_exec(db, query, NULL);
1098
1099                 if (num_deleted != NULL) {
1100                         *num_deleted = sqlite3_changes(db);
1101                 }
1102         }
1103
1104 err:
1105         if (stmt) {
1106                 sqlite3_finalize(stmt);
1107         }
1108         /* Close DB */
1109         if (db) {
1110                 notification_db_close(&db);
1111         }
1112
1113         return ret;
1114 }
1115
1116 int notification_noti_delete_group_by_group_id(const char *pkgname,
1117                                                int group_id, int *num_deleted, int **list_deleted_rowid)
1118 {
1119         int ret = NOTIFICATION_ERROR_NONE;
1120         int ret_tmp = NOTIFICATION_ERROR_NONE;
1121         sqlite3 *db = NULL;
1122         int i = 0, data_cnt = 0;
1123         sqlite3_stmt *stmt = NULL;
1124         char buf[128] = { 0, };
1125         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1126         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1127         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1128
1129         /* Check pkgname is valid */
1130         if (pkgname == NULL) {
1131                 return NOTIFICATION_ERROR_INVALID_DATA;
1132         }
1133
1134         snprintf(query_where, sizeof(query_where),
1135                         "where caller_pkgname = '%s' and group_id = %d", pkgname, group_id);
1136
1137         /* Open DB */
1138         db = notification_db_open(DBPATH);
1139         if (!db) {
1140                 return NOTIFICATION_ERROR_FROM_DB;
1141         }
1142
1143         if (num_deleted != NULL) {
1144                 *num_deleted = 0;
1145         }
1146         if (list_deleted_rowid != NULL) {
1147                 *list_deleted_rowid = NULL;
1148                 snprintf(query, sizeof(query),
1149                                 "select priv_id from noti_list %s ", query_where);
1150
1151                 ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1152                 if (ret != SQLITE_OK) {
1153                         NOTIFICATION_ERR("Select Query : %s", query);
1154                         NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1155                                          sqlite3_errmsg(db));
1156
1157                         ret = NOTIFICATION_ERROR_FROM_DB;
1158                         goto err;
1159                 }
1160
1161                 while(sqlite3_step(stmt) == SQLITE_ROW) {
1162                         if (data_cnt % 8 == 0) {
1163                                 int *tmp;
1164                                 tmp = (int *)realloc(*list_deleted_rowid, sizeof(int) * (data_cnt + 8 + 1));
1165                                 if (tmp) {
1166                                         *list_deleted_rowid = tmp;
1167                                 } else {
1168                                         free(*list_deleted_rowid);
1169                                         *list_deleted_rowid = NULL;
1170                                         ret = NOTIFICATION_ERROR_NO_MEMORY;
1171                                         goto err;
1172                                 }
1173                         }
1174                         *((*list_deleted_rowid) + data_cnt) = sqlite3_column_int(stmt, 0);
1175                         data_cnt++;
1176                 }
1177
1178                 if (stmt) {
1179                         sqlite3_finalize(stmt);
1180                         stmt = NULL;
1181                 }
1182
1183                 if (data_cnt > 0) {
1184                         query_where[0] = '\0';
1185                         snprintf(query_base, sizeof(query_base) - 1, "delete from noti_list");
1186                         for (i = 0; i < data_cnt ; i++) {
1187                                 if (i % NOTI_BURST_DELETE_UNIT == 0 && i != 0) {
1188                                         snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1189                                         ret_tmp = notification_db_exec(db, query, NULL);
1190                                         query_where[0] = '\0';
1191                                         if (ret == NOTIFICATION_ERROR_NONE) {
1192                                                 ret = ret_tmp;
1193                                         }
1194                                 }
1195                                 snprintf(buf, sizeof(buf) - 1, "%s%d", (i % NOTI_BURST_DELETE_UNIT == 0) ? "" : ",", *((*list_deleted_rowid) + i));
1196                                 strncat(query_where, buf,sizeof(query_where) - strlen(query_where) - 1);
1197                         }
1198                         if ((i <= NOTI_BURST_DELETE_UNIT) || ((i % NOTI_BURST_DELETE_UNIT) > 0) ) {
1199                                 snprintf(query, sizeof(query) - 1, "%s where priv_id in (%s)", query_base, query_where);
1200                                 ret_tmp = notification_db_exec(db, query, NULL);
1201                                 if (ret == NOTIFICATION_ERROR_NONE) {
1202                                         ret = ret_tmp;
1203                                 }
1204                         }
1205                 } else {
1206                         free(*list_deleted_rowid);
1207                         *list_deleted_rowid = NULL;
1208                 }
1209
1210                 if (num_deleted != NULL) {
1211                         *num_deleted = data_cnt;
1212                 }
1213         } else {
1214                 /* Make query */
1215                 snprintf(query, sizeof(query), "delete from noti_list %s", query_where);
1216
1217                 /* execute DB */
1218                 ret = notification_db_exec(db, query, NULL);
1219         }
1220
1221 err:
1222         if (stmt) {
1223                 sqlite3_finalize(stmt);
1224         }
1225         /* Close DB */
1226         if (db) {
1227                 notification_db_close(&db);
1228         }
1229
1230         return ret;
1231 }
1232
1233 int notification_noti_delete_group_by_priv_id(const char *pkgname, int priv_id)
1234 {
1235         sqlite3 *db = NULL;
1236         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1237         int internal_group_id = 0;
1238         int ret;
1239
1240         /* Check pkgname is valid */
1241         if (pkgname == NULL) {
1242                 return NOTIFICATION_ERROR_INVALID_DATA;
1243         }
1244
1245         /* Open DB */
1246         db = notification_db_open(DBPATH);
1247         if (!db) {
1248                 return NOTIFICATION_ERROR_FROM_DB;
1249         }
1250
1251         /* Get internal group id using priv id */
1252         internal_group_id =
1253             _notification_noti_get_internal_group_id_by_priv_id(pkgname,
1254                                                                 priv_id, db);
1255
1256         /* Make query */
1257         snprintf(query, sizeof(query), "delete from noti_list "
1258                  "where caller_pkgname = '%s' and internal_group_id = %d",
1259                  pkgname, internal_group_id);
1260
1261         /* execute DB */
1262         ret = notification_db_exec(db, query, NULL);
1263
1264         /* Close DB */
1265         notification_db_close(&db);
1266
1267         return ret;
1268 }
1269
1270 EXPORT_API int notification_noti_delete_by_priv_id(const char *pkgname, int priv_id)
1271 {
1272         sqlite3 *db = NULL;
1273         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1274         int ret;
1275
1276         /* Check pkgname is valid */
1277         if (pkgname == NULL) {
1278                 return NOTIFICATION_ERROR_INVALID_DATA;
1279         }
1280
1281         /* Open DB */
1282         db = notification_db_open(DBPATH);
1283         if (!db) {
1284                 return NOTIFICATION_ERROR_FROM_DB;
1285         }
1286
1287         /* Make query */
1288         snprintf(query, sizeof(query), "delete from noti_list "
1289                  "where caller_pkgname = '%s' and priv_id = %d", pkgname,
1290                  priv_id);
1291
1292         /* execute DB */
1293         ret = notification_db_exec(db, query, NULL);
1294
1295         /* Close DB */
1296         if (db) {
1297                 notification_db_close(&db);
1298         }
1299
1300         return ret;
1301 }
1302
1303 EXPORT_API int notification_noti_delete_by_priv_id_get_changes(const char *pkgname, int priv_id, int *num_changes)
1304 {
1305         sqlite3 *db = NULL;
1306         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1307         int ret;
1308
1309         /* Check pkgname is valid */
1310         if (pkgname == NULL) {
1311                 return NOTIFICATION_ERROR_INVALID_DATA;
1312         }
1313
1314         /* Open DB */
1315         db = notification_db_open(DBPATH);
1316         if (!db) {
1317                 return NOTIFICATION_ERROR_FROM_DB;
1318         }
1319
1320         /* Make query */
1321         snprintf(query, sizeof(query), "delete from noti_list "
1322                  "where caller_pkgname = '%s' and priv_id = %d", pkgname,
1323                  priv_id);
1324
1325         /* execute DB */
1326         ret = notification_db_exec(db, query, num_changes);
1327
1328         if (num_changes != NULL) {
1329                 NOTIFICATION_DBG("deleted num:%d", *num_changes);
1330         }
1331
1332         /* Close DB */
1333         if (db) {
1334                 notification_db_close(&db);
1335         }
1336
1337         return ret;
1338 }
1339
1340 notification_error_e notification_noti_get_count(notification_type_e type,
1341                                                  const char *pkgname,
1342                                                  int group_id, int priv_id,
1343                                                  int *count)
1344 {
1345         sqlite3 *db = NULL;
1346         sqlite3_stmt *stmt = NULL;
1347         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1348         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1349         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1350         char query_where_more[NOTIFICATION_QUERY_MAX] = { 0, };
1351
1352         int ret = 0, get_count = 0, internal_group_id = 0;
1353         int status = VCONFKEY_TELEPHONY_SIM_UNKNOWN;
1354         int flag_where = 0;
1355         int flag_where_more = 0;
1356         int ret_vconf = 0;
1357
1358         /* Open DB */
1359         db = notification_db_open(DBPATH);
1360         if (!db) {
1361                 return NOTIFICATION_ERROR_FROM_DB;
1362         }
1363
1364         /* Check current sim status */
1365         ret_vconf = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1366
1367         /* Make query */
1368         snprintf(query_base, sizeof(query_base),
1369                  "select count(*) from noti_list ");
1370
1371         if (pkgname != NULL) {
1372                 if (group_id == NOTIFICATION_GROUP_ID_NONE) {
1373                         if (priv_id == NOTIFICATION_PRIV_ID_NONE) {
1374                                 snprintf(query_where, sizeof(query_where),
1375                                          "where caller_pkgname = '%s' ",
1376                                          pkgname);
1377                                 flag_where = 1;
1378                         } else {
1379                                 internal_group_id =
1380                                     _notification_noti_get_internal_group_id_by_priv_id
1381                                     (pkgname, priv_id, db);
1382                                 snprintf(query_where, sizeof(query_where),
1383                                          "where caller_pkgname = '%s' and internal_group_id = %d ",
1384                                          pkgname, internal_group_id);
1385                                 flag_where = 1;
1386                         }
1387                 } else {
1388                         if (priv_id == NOTIFICATION_PRIV_ID_NONE) {
1389                                 snprintf(query_where, sizeof(query_where),
1390                                          "where caller_pkgname = '%s' and group_id = %d ",
1391                                          pkgname, group_id);
1392                                 flag_where = 1;
1393                         } else {
1394                                 internal_group_id =
1395                                     _notification_noti_get_internal_group_id_by_priv_id
1396                                     (pkgname, priv_id, db);
1397                                 snprintf(query_where, sizeof(query_where),
1398                                          "where caller_pkgname = '%s' and internal_group_id = %d ",
1399                                          pkgname, internal_group_id);
1400                                 flag_where = 1;
1401                         }
1402                 }
1403
1404         }
1405
1406         if (ret_vconf == 0 && status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1407                 if (type != NOTIFICATION_TYPE_NONE) {
1408                         snprintf(query_where_more, sizeof(query_where_more),
1409                                  "type = %d ", type);
1410                         flag_where_more = 1;
1411                 }
1412         } else {
1413                 if (type != NOTIFICATION_TYPE_NONE) {
1414                         snprintf(query_where_more, sizeof(query_where_more),
1415                                  "type = %d and flag_simmode = 0 ", type);
1416                         flag_where_more = 1;
1417                 } else {
1418                         snprintf(query_where_more, sizeof(query_where_more),
1419                                  "flag_simmode = 0 ");
1420                         flag_where_more = 1;
1421                 }
1422         }
1423
1424         if (flag_where == 1) {
1425                 if (flag_where_more == 1) {
1426                         snprintf(query, sizeof(query), "%s %s and %s",
1427                                  query_base, query_where, query_where_more);
1428                 } else {
1429                         snprintf(query, sizeof(query), "%s %s", query_base,
1430                                  query_where);
1431                 }
1432
1433         } else {
1434                 if (flag_where_more == 1) {
1435                         snprintf(query, sizeof(query), "%s where %s",
1436                                  query_base, query_where_more);
1437                 } else {
1438                         snprintf(query, sizeof(query), "%s", query_base);
1439                 }
1440         }
1441
1442         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1443         if (ret != SQLITE_OK) {
1444                 NOTIFICATION_ERR("Select Query : %s", query);
1445                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1446                                  sqlite3_errmsg(db));
1447
1448                 ret = NOTIFICATION_ERROR_FROM_DB;
1449                 goto err;
1450         }
1451
1452         ret = sqlite3_step(stmt);
1453         if (ret == SQLITE_ROW) {
1454                 get_count = sqlite3_column_int(stmt, 0);
1455         }
1456
1457         ret = NOTIFICATION_ERROR_NONE;
1458
1459 err:
1460         if (stmt) {
1461                 sqlite3_finalize(stmt);
1462         }
1463
1464         /* Close DB */
1465         if (db) {
1466                 notification_db_close(&db);
1467         }
1468
1469         *count = get_count;
1470
1471         return ret;
1472 }
1473
1474 notification_error_e notification_noti_get_grouping_list(notification_type_e type,
1475                                                          int count,
1476                                                          notification_list_h *
1477                                                          list)
1478 {
1479         sqlite3 *db = NULL;
1480         sqlite3_stmt *stmt = NULL;
1481         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1482         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1483         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1484
1485         int ret = 0;
1486         notification_list_h get_list = NULL;
1487         notification_h noti = NULL;
1488         int internal_count = 0;
1489         int status;
1490
1491         /* Open DB */
1492         db = notification_db_open(DBPATH);
1493         if (!db) {
1494                 return NOTIFICATION_ERROR_FROM_DB;
1495         }
1496
1497         /* Check current sim status */
1498         ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1499
1500         /* Make query */
1501         snprintf(query_base, sizeof(query_base), "select "
1502                  "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1503                  "b_text, b_key, b_format_args, num_format_args, "
1504                  "text_domain, text_dir, time, insert_time, args, group_args, "
1505                  "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1506                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1507                  "flags_for_property, display_applist, progress_size, progress_percentage "
1508                  "from noti_list ");
1509
1510         if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1511                 if (type != NOTIFICATION_TYPE_NONE) {
1512                         snprintf(query_where, sizeof(query_where),
1513                                  "where type = %d ", type);
1514                 }
1515         } else {
1516                 if (type != NOTIFICATION_TYPE_NONE) {
1517                         snprintf(query_where, sizeof(query_where),
1518                                  "where type = %d and flag_simmode = 0 ", type);
1519                 } else {
1520                         snprintf(query_where, sizeof(query_where),
1521                                  "where flag_simmode = 0 ");
1522                 }
1523         }
1524
1525         snprintf(query, sizeof(query),
1526                  "%s %s "
1527                  "group by internal_group_id "
1528                  "order by rowid desc, time desc", query_base, query_where);
1529
1530         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1531         if (ret != SQLITE_OK) {
1532                 NOTIFICATION_ERR("Select Query : %s", query);
1533                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1534                                  sqlite3_errmsg(db));
1535
1536                 ret = NOTIFICATION_ERROR_FROM_DB;
1537                 goto err;
1538         }
1539
1540         while (sqlite3_step(stmt) == SQLITE_ROW) {
1541                 /* Make notification list */
1542                 noti = _notification_noti_get_item(stmt);
1543                 if (noti != NULL) {
1544                         internal_count++;
1545
1546                         get_list = notification_list_append(get_list, noti);
1547
1548                         if (count != -1 && internal_count >= count) {
1549                                 NOTIFICATION_INFO
1550                                     ("internal count %d >= count %d",
1551                                      internal_count, count);
1552                                 break;
1553                         }
1554                 }
1555         }
1556
1557         ret = NOTIFICATION_ERROR_NONE;
1558
1559 err:
1560         if (stmt) {
1561                 sqlite3_finalize(stmt);
1562         }
1563
1564         /* Close DB */
1565         if (db) {
1566                 notification_db_close(&db);
1567         }
1568
1569         if (get_list != NULL) {
1570                 *list = notification_list_get_head(get_list);
1571         }
1572
1573         return ret;
1574 }
1575
1576 notification_error_e notification_noti_get_detail_list(const char *pkgname,
1577                                                        int group_id,
1578                                                        int priv_id, int count,
1579                                                        notification_list_h *list)
1580 {
1581         sqlite3 *db = NULL;
1582         sqlite3_stmt *stmt = NULL;
1583         char query_base[NOTIFICATION_QUERY_MAX] = { 0, };
1584         char query_where[NOTIFICATION_QUERY_MAX] = { 0, };
1585
1586         char query[NOTIFICATION_QUERY_MAX] = { 0, };
1587         int ret = 0;
1588         notification_list_h get_list = NULL;
1589         notification_h noti = NULL;
1590         int internal_count = 0;
1591         int internal_group_id = 0;
1592         int status = 0; /* If the vconf_get_int failed, the status will be the garbage value */
1593
1594         /* Open DB */
1595         db = notification_db_open(DBPATH);
1596         if (!db) {
1597                 return NOTIFICATION_ERROR_FROM_DB;
1598         }
1599
1600         /* Check current sim status */
1601         ret = vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT, &status);
1602
1603         /* Make query */
1604         snprintf(query_base, sizeof(query_base), "select "
1605                  "type, layout, caller_pkgname, launch_pkgname, image_path, group_id, priv_id, "
1606                  "b_text, b_key, b_format_args, num_format_args, "
1607                  "text_domain, text_dir, time, insert_time, args, group_args, "
1608                  "b_execute_option, b_service_responding, b_service_single_launch, b_service_multi_launch, "
1609                  "sound_type, sound_path, vibration_type, vibration_path, led_operation, led_argb, led_on_ms, led_off_ms, "
1610                  "flags_for_property, display_applist, progress_size, progress_percentage "
1611                  "from noti_list ");
1612
1613         if (priv_id == NOTIFICATION_PRIV_ID_NONE && group_id == NOTIFICATION_GROUP_ID_NONE) {
1614                 if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1615                         snprintf(query_where, sizeof(query_where),
1616                                  "where  caller_pkgname = '%s' ",
1617                                  pkgname, internal_group_id);
1618                 } else {
1619                         snprintf(query_where, sizeof(query_where),
1620                                  "where  caller_pkgname = '%s' and flag_simmode = 0 ",
1621                                  pkgname, internal_group_id);
1622                 }
1623         } else {
1624                 internal_group_id =
1625                     _notification_noti_get_internal_group_id_by_priv_id(pkgname,
1626                                                                         priv_id, db);
1627
1628                 if (status == VCONFKEY_TELEPHONY_SIM_INSERTED) {
1629                         snprintf(query_where, sizeof(query_where),
1630                                  "where  caller_pkgname = '%s' and internal_group_id = %d ",
1631                                  pkgname, internal_group_id);
1632                 } else {
1633                         snprintf(query_where, sizeof(query_where),
1634                                  "where  caller_pkgname = '%s' and internal_group_id = %d and flag_simmode = 0 ",
1635                                  pkgname, internal_group_id);
1636                 }
1637         }
1638
1639         snprintf(query, sizeof(query),
1640                  "%s %s "
1641                  "order by rowid desc, time desc", query_base, query_where);
1642
1643         ret = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
1644         if (ret != SQLITE_OK) {
1645                 NOTIFICATION_ERR("Select Query : %s", query);
1646                 NOTIFICATION_ERR("Select DB error(%d) : %s", ret,
1647                                  sqlite3_errmsg(db));
1648
1649                 ret = NOTIFICATION_ERROR_FROM_DB;
1650                 goto err;
1651         }
1652
1653         while (sqlite3_step(stmt) == SQLITE_ROW) {
1654                 /* Make notification list */
1655                 noti = _notification_noti_get_item(stmt);
1656                 if (noti != NULL) {
1657                         internal_count++;
1658
1659                         get_list = notification_list_append(get_list, noti);
1660
1661                         if (count != -1 && internal_count >= count) {
1662                                 NOTIFICATION_INFO
1663                                     ("internal count %d >= count %d",
1664                                      internal_count, count);
1665                                 break;
1666                         }
1667                 }
1668         }
1669
1670         ret = NOTIFICATION_ERROR_NONE;
1671
1672 err:
1673         if (stmt) {
1674                 sqlite3_finalize(stmt);
1675         }
1676
1677         /* Close DB */
1678         if (db) {
1679                 notification_db_close(&db);
1680         }
1681
1682         if (get_list != NULL) {
1683                 *list = notification_list_get_head(get_list);
1684         }
1685
1686         return ret;
1687 }