Add new api to set schedule for do_not_disturb
[platform/core/api/notification.git] / src / notification_db.c
1 /*
2  * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <errno.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <string.h>
21
22 #include <sqlite3.h>
23 #include <db-util.h>
24 #include <tizen.h>
25 #include <tzplatform_config.h>
26
27 #include <notification_error.h>
28 #include <notification_debug.h>
29 #include <notification_db.h>
30
31 #define NOTIFICATION_DB_NAME ".notification.db"
32 #define CREATE_NOTIFICATION_TABLE " \
33 PRAGMA journal_mode = PERSIST; \
34 PRAGMA synchronous = FULL; \
35 create  table if not exists noti_list ( \
36                         type INTEGER NOT NULL, \
37                         layout INTEGER NOT NULL default 0, \
38                         caller_pkgname TEXT NOT NULL, \
39                         launch_pkgname TEXT, \
40                         image_path TEXT, \
41                         group_id INTEGER default 0,  \
42                         internal_group_id INTEGER default 0,  \
43                         priv_id INTEGER PRIMARY KEY AUTOINCREMENT,  \
44                         title_key TEXT, \
45                         b_text TEXT, \
46                         b_key TEXT, \
47                         tag TEXT, \
48                         b_format_args TEXT, \
49                         num_format_args INTEGER default 0, \
50                         text_domain TEXT, \
51                         text_dir TEXT, \
52                         time INTEGER default 0, \
53                         insert_time INTEGER default 0, \
54                         args TEXT, \
55                         group_args TEXT, \
56                         b_execute_option TEXT, \
57                         b_service_responding TEXT, \
58                         b_service_single_launch TEXT, \
59                         b_service_multi_launch TEXT, \
60                         b_event_handler_click_on_button_1 TEXT, \
61                         b_event_handler_click_on_button_2 TEXT, \
62                         b_event_handler_click_on_button_3 TEXT, \
63                         b_event_handler_click_on_button_4 TEXT, \
64                         b_event_handler_click_on_button_5 TEXT, \
65                         b_event_handler_click_on_button_6 TEXT, \
66                         b_event_handler_click_on_icon TEXT, \
67                         b_event_handler_click_on_thumbnail TEXT, \
68                         sound_type INTEGER default 0, \
69                         sound_path TEXT, \
70                         vibration_type INTEGER default 0, \
71                         vibration_path TEXT, \
72                         led_operation INTEGER default 0, \
73                         led_argb INTEGER default 0, \
74                         led_on_ms INTEGER default -1, \
75                         led_off_ms INTEGER default -1, \
76                         flags_for_property INTEGER default 0, \
77                         flag_simmode INTEGER default 0, \
78                         display_applist INTEGER, \
79                         progress_size DOUBLE default 0, \
80                         progress_percentage DOUBLE default 0, \
81                         ongoing_flag INTEGER default 0, \
82                         auto_remove INTEGER default 1, \
83                         uid INTEGER \
84                 ); \
85                 create table if not exists noti_group_data ( \
86                         caller_pkgname TEXT NOT NULL, \
87                         group_id INTEGER default 0, \
88                         badge INTEGER default 0, \
89                         title TEXT, \
90                         content TEXT, \
91                         loc_title TEXT, \
92                         loc_content TEXT, \
93                         count_display_title INTEGER, \
94                         count_display_content INTEGER, \
95                         rowid INTEGER PRIMARY KEY AUTOINCREMENT, \
96                         UNIQUE (caller_pkgname, group_id) \
97                 ); \
98                 create table if not exists ongoing_list ( \
99                         caller_pkgname TEXT NOT NULL, \
100                         launch_pkgname TEXT, \
101                         icon_path TEXT, \
102                         group_id INTEGER default 0, \
103                         internal_group_id INTEGER default 0, \
104                         priv_id INTERGER NOT NULL, \
105                         title TEXT, \
106                         content TEXT, \
107                         default_content TEXT, \
108                         loc_title TEXT, \
109                         loc_content TEXT, \
110                         loc_default_content TEXT, \
111                         text_domain TEXT, \
112                         text_dir TEXT, \
113                         args TEXT, \
114                         group_args TEXT, \
115                         flag INTEGER default 0, \
116                         progress_size DOUBLE default 0, \
117                         progress_percentage DOUBLE default 0, \
118                         rowid INTEGER PRIMARY KEY AUTOINCREMENT, \
119                         UNIQUE (caller_pkgname, priv_id) \
120                 ); \
121                 CREATE TABLE IF NOT EXISTS notification_setting ( \
122                         uid INTEGER, \
123                         package_name TEXT NOT NULL, \
124                         allow_to_notify INTEGER DEFAULT 1, \
125                         do_not_disturb_except INTEGER DEFAULT 0, \
126                         visibility_class INTEGER DEFAULT 0, \
127                         UNIQUE (uid, package_name) \
128                 ); \
129                 CREATE TABLE IF NOT EXISTS notification_system_setting ( \
130                         uid INTEGER, \
131                         do_not_disturb INTEGER DEFAULT 0, \
132                         visibility_class INTEGER DEFAULT 0, \
133                         dnd_schedule_enabled INTEGER DEFAULT 0, \
134                         dnd_schedule_day INTEGER DEFAULT 0, \
135                         dnd_start_hour INTEGER DEFAULT 0, \
136                         dnd_start_min INTEGER DEFAULT 0, \
137                         dnd_end_hour INTEGER DEFAULT 0, \
138                         dnd_end_min INTEGER DEFAULT 0, \
139                         UNIQUE (uid) \
140                 );"
141
142 EXPORT_API int notification_db_init()
143 {
144         int r;
145         sqlite3 *db = NULL;
146         char *errmsg = NULL;
147         char defname[FILENAME_MAX];
148         char *query = NULL;
149         const char *db_path = tzplatform_getenv(TZ_SYS_DB);
150         if (db_path == NULL) {
151                 NOTIFICATION_ERR("fail to get db_path"); /* LCOV_EXCL_LINE */
152                 return NOTIFICATION_ERROR_OUT_OF_MEMORY;
153         }
154         snprintf(defname, sizeof(defname), "%s/%s", db_path, NOTIFICATION_DB_NAME);
155
156         NOTIFICATION_DBG("db path : %s", defname);
157         r = sqlite3_open_v2(defname, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
158         if (r) {
159                 /* LCOV_EXCL_START */
160                 db_util_close(db);
161                 NOTIFICATION_ERR("fail to open notification db %d", r);
162                 return NOTIFICATION_ERROR_IO_ERROR;
163                 /* LCOV_EXCL_STOP */
164         }
165         query = sqlite3_mprintf(CREATE_NOTIFICATION_TABLE, tzplatform_getuid(TZ_SYS_DEFAULT_USER));
166         NOTIFICATION_DBG("@@@ query : %s", query);
167
168         r = sqlite3_exec(db, CREATE_NOTIFICATION_TABLE, NULL, NULL, &errmsg);
169         if (query)
170                 sqlite3_free(query);
171         if (r != SQLITE_OK) {
172                 /* LCOV_EXCL_START */
173                 NOTIFICATION_ERR("query error(%d)(%s)", r, errmsg);
174                 sqlite3_free(errmsg);
175                 db_util_close(db);
176                 return NOTIFICATION_ERROR_IO_ERROR;
177                 /* LCOV_EXCL_STOP */
178         }
179
180         db_util_close(db);
181         return NOTIFICATION_ERROR_NONE;
182 }
183
184 sqlite3 *notification_db_open(const char *dbfile)
185 {
186         int ret = 0;
187         sqlite3 *db = 0;
188
189         ret = db_util_open(dbfile, &db, 0);
190         if (ret != SQLITE_OK) {
191                 /* LCOV_EXCL_START */
192                 if (ret == SQLITE_PERM)
193                         set_last_result(NOTIFICATION_ERROR_PERMISSION_DENIED);
194                 else
195                         set_last_result(NOTIFICATION_ERROR_FROM_DB);
196
197                 return NULL;
198                 /* LCOV_EXCL_STOP */
199         }
200
201         return db;
202 }
203
204 int notification_db_close(sqlite3 **db)
205 {
206         int ret = 0;
207
208         if (db == NULL || *db == NULL)
209                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
210
211         ret = db_util_close(*db);
212         if (ret != SQLITE_OK) {
213                 /* LCOV_EXCL_START */
214                 NOTIFICATION_ERR("DB close error(%d)", ret);
215                 return NOTIFICATION_ERROR_FROM_DB;
216                 /* LCOV_EXCL_STOP */
217         }
218
219         *db = NULL;
220
221         return NOTIFICATION_ERROR_NONE;
222 }
223
224 int notification_db_exec(sqlite3 *db, const char *query, int *num_changes)
225 {
226         int ret = 0;
227         sqlite3_stmt *stmt = NULL;
228
229         if (db == NULL)
230                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
231
232         if (query == NULL)
233                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
234
235         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
236         if (ret != SQLITE_OK) {
237                 /* LCOV_EXCL_START */
238                 NOTIFICATION_ERR("DB err(%d) : %s", ret,
239                                  sqlite3_errmsg(db));
240                 return NOTIFICATION_ERROR_FROM_DB;
241                 /* LCOV_EXCL_STOP */
242         }
243
244         if (stmt != NULL) {
245                 ret = sqlite3_step(stmt);
246                 if (ret == SQLITE_OK || ret == SQLITE_DONE) {
247                         if (num_changes != NULL)
248                                 *num_changes = sqlite3_changes(db);
249
250                         sqlite3_finalize(stmt);
251                 } else {
252                         /* LCOV_EXCL_START */
253                         NOTIFICATION_ERR("DB err(%d) : %s", ret,
254                                          sqlite3_errmsg(db));
255                         sqlite3_finalize(stmt);
256                         return NOTIFICATION_ERROR_FROM_DB;
257                         /* LCOV_EXCL_STOP */
258                 }
259         } else {
260                         return NOTIFICATION_ERROR_FROM_DB;
261         }
262
263         return NOTIFICATION_ERROR_NONE;
264 }
265
266 char *notification_db_column_text(sqlite3_stmt * stmt, int col)
267 {
268         const unsigned char *col_text = NULL;
269
270         col_text = sqlite3_column_text(stmt, col);
271         if (col_text == NULL || col_text[0] == '\0')
272                 return NULL;
273
274         return strdup((char *)col_text);
275 }
276
277 bundle *notification_db_column_bundle(sqlite3_stmt * stmt, int col)
278 {
279         const unsigned char *col_bundle = NULL;
280
281         col_bundle = sqlite3_column_text(stmt, col);
282         if (col_bundle == NULL || col_bundle[0] == '\0')
283                 return NULL;
284
285         return bundle_decode(col_bundle, strlen((char *)col_bundle));
286 }
287