Add database APIs to update device service payload info
[platform/core/connectivity/ua-manager.git] / ua-daemon / src / ua-manager-service-db.c
1 /*
2  * Copyright (c) 2018 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
18 #include <sqlite3.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <dlfcn.h>
23
24 #include "ua-manager-common.h"
25 #include "ua-manager-database.h"
26
27 #define SELECT_ALL_SERVICES "SELECT service_number, service_name, " \
28         "cycle, presence_threshold, absence_threshold FROM services"
29
30 #define SELECT_SERVICE "SELECT service_number, service_name, " \
31         "cycle, presence_threshold, absence_threshold FROM services " \
32         "where service_name = ?"
33
34 #define INSERT_SERVICE "insert into services (service_name, cycle, " \
35         "presence_threshold, absence_threshold) " \
36         "values (?, ?, ?, ?)"
37
38 #define UPDATE_CYCLE "UPDATE services SET cycle = ? WHERE service_name = ?"
39
40 #define UPDATE_SERVICE "UPDATE services SET (presence_threshold, absence_threshold) " \
41         "= (?, ?) WHERE service_name = ?"
42
43 #define DELETE_ALL_SERVICES "delete from services"
44
45 #define DELETE_SERVICE_INFO "delete from services WHERE service_name = ?"
46
47 /* DELETE statements */
48 static sqlite3_stmt *delete_all_services;
49 static sqlite3_stmt *delete_service_info;
50
51 /* SELECT statements */
52 static sqlite3_stmt *select_all_services;
53 static sqlite3_stmt *select_service;
54
55 /* UPDATE statements */
56 static sqlite3_stmt *update_cycle;
57 static sqlite3_stmt *update_service_info;
58
59 /* INSERT statements */
60 static sqlite3_stmt *insert_service_info;
61
62 extern sqlite3 *database_handle;
63
64 static void __uam_service_finalize_delete(void)
65 {
66         FUNC_ENTRY;
67
68         FINALIZE(delete_all_services);
69         FINALIZE(delete_service_info);
70
71         FUNC_EXIT;
72 }
73
74 static void __uam_service_finalize_select(void)
75 {
76         FUNC_ENTRY;
77
78         FINALIZE(select_all_services);
79         FINALIZE(select_service);
80
81         FUNC_EXIT;
82 }
83
84 static void __uam_service_finalize_insert(void)
85 {
86         FUNC_ENTRY;
87
88         FINALIZE(insert_service_info);
89
90         FUNC_EXIT;
91 }
92
93 static void __uam_service_finalize_update(void)
94 {
95         FUNC_ENTRY;
96
97         FINALIZE(update_cycle);
98         FINALIZE(update_service_info);
99
100         FUNC_EXIT;
101 }
102
103 static int __uam_service_prepare_delete(sqlite3 *db)
104 {
105         FUNC_ENTRY;
106         int rc;
107         static int initialized;
108
109         if (initialized) {
110                 FUNC_EXIT;
111                 return SQLITE_OK;
112         }
113
114         PREPARE_QUERY(rc, db, delete_all_services,
115                 DELETE_ALL_SERVICES, __uam_service_finalize_delete);
116         PREPARE_QUERY(rc, db, delete_service_info,
117                 DELETE_SERVICE_INFO, __uam_service_finalize_delete);
118
119         initialized = 1;
120         FUNC_EXIT;
121         return rc;
122 }
123
124 static int __uam_service_prepare_select(sqlite3 *db)
125 {
126         FUNC_ENTRY;
127         int rc;
128         static int initialized;
129
130         if (initialized) {
131                 FUNC_EXIT;
132                 return SQLITE_OK;
133         }
134
135         PREPARE_QUERY(rc, db, select_all_services,
136                 SELECT_ALL_SERVICES, __uam_service_finalize_select);
137         PREPARE_QUERY(rc, db, select_service,
138                 SELECT_SERVICE, __uam_service_finalize_select);
139
140         initialized = 1;
141         FUNC_EXIT;
142         return rc;
143 }
144
145 static int __uam_service_prepare_update(sqlite3 *db)
146 {
147         FUNC_ENTRY;
148         int rc;
149         static int initialized;
150
151         if (initialized) {
152                 FUNC_EXIT;
153                 return SQLITE_OK;
154         }
155
156         PREPARE_QUERY(rc, db, update_cycle,
157                 UPDATE_CYCLE, __uam_service_finalize_update);
158         PREPARE_QUERY(rc, db, update_service_info,
159                 UPDATE_SERVICE, __uam_service_finalize_update);
160
161         initialized = 1;
162         FUNC_EXIT;
163         return rc;
164 }
165
166 static int __uam_service_prepare_insert(sqlite3 *db)
167 {
168         FUNC_ENTRY;
169         int rc;
170         static int initialized;
171
172         if (initialized) {
173                 FUNC_EXIT;
174                 return SQLITE_OK;
175         }
176
177         PREPARE_QUERY(rc, db, insert_service_info,
178                 INSERT_SERVICE, __uam_service_finalize_insert);
179
180         initialized = 1;
181         FUNC_EXIT;
182         return rc;
183 }
184
185 static int __uam_service_table_servicesinfo_prepare(sqlite3 *db)
186 {
187         FUNC_ENTRY;
188
189         int error_code = UAM_ERROR_NONE;
190
191         if (db == NULL) {
192                 FUNC_EXIT;
193                 return UAM_ERROR_DB_FAILED;
194         }
195
196         DB_ACTION(__uam_service_prepare_delete(db), error_code, handle_error);
197         DB_ACTION(__uam_service_prepare_select(db), error_code, handle_error);
198         DB_ACTION(__uam_service_prepare_update(db), error_code, handle_error);
199         DB_ACTION(__uam_service_prepare_insert(db), error_code, handle_error);
200
201 handle_error:
202
203         FUNC_EXIT;
204         return error_code;
205 }
206
207 static void __uam_service_table_servicesinfo_finalize(void)
208 {
209         FUNC_ENTRY;
210         __uam_service_finalize_delete();
211         __uam_service_finalize_select();
212         __uam_service_finalize_insert();
213         FUNC_EXIT;
214 }
215
216 int _uam_service_db_deinitialize(void)
217 {
218         FUNC_ENTRY;
219
220         retv_if(NULL == database_handle, UAM_ERROR_NONE);
221
222         __uam_service_table_servicesinfo_finalize();
223         sqlite3_close(database_handle);
224
225         FUNC_EXIT;
226         return UAM_ERROR_NONE;
227 }
228
229 int _uam_service_db_initialize(void)
230 {
231         FUNC_ENTRY;
232
233         EXEC(UAM_ERROR_NONE, __uam_service_table_servicesinfo_prepare(database_handle), handle_error);
234
235         FUNC_EXIT;
236         return UAM_ERROR_NONE;
237
238 handle_error:
239         _uam_service_db_deinitialize();
240         FUNC_EXIT;
241         return UAM_ERROR_DB_FAILED;
242 }
243
244 int _uam_db_insert_service_info(
245         int *service_number, uam_service_info_s *svc, int cycle)
246 {
247         FUNC_ENTRY;
248         int error_code = UAM_ERROR_NONE;
249         sqlite3_stmt *stmt = insert_service_info;
250         int sql_ret = SQLITE_OK;
251
252         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
253
254         UAM_INFO("%s-%d-%d-%d", svc->name, cycle, svc->presence_threshold,
255                                 svc->absence_threshold);
256
257         DB_ACTION(sqlite3_bind_text(stmt, 1, svc->name, -1, SQLITE_TRANSIENT),
258                 error_code, handle_error);
259         DB_ACTION(sqlite3_bind_int(stmt, 2, cycle),
260                 error_code, handle_error);
261         DB_ACTION(sqlite3_bind_int(stmt, 3, svc->presence_threshold),
262                 error_code, handle_error);
263         DB_ACTION(sqlite3_bind_int(stmt, 4, svc->absence_threshold),
264                 error_code, handle_error);
265
266         sql_ret = sqlite3_step(stmt);
267         if (sql_ret != SQLITE_DONE) {
268                 UAM_ERR("Failed to insert service info [%d:%s]",
269                         sql_ret, sqlite3_errmsg(database_handle));
270                 error_code = UAM_ERROR_DB_FAILED;
271                 goto handle_error;
272         }
273
274         UAM_DBG("Service info inserted");
275
276 handle_error:
277         sqlite3_reset(stmt);
278         FUNC_EXIT;
279         return error_code;
280 }
281
282 int _uam_db_update_service_info(uam_db_service_info_t *svc)
283 {
284         FUNC_ENTRY;
285         int error_code = UAM_ERROR_NONE;
286         sqlite3_stmt *stmt = update_service_info;
287         int sql_ret = SQLITE_OK;
288
289         retv_if(NULL == svc->name, UAM_ERROR_INVALID_PARAMETER);
290
291         UAM_INFO("%s-%d-%d-%d", svc->name, svc->cycle, svc->presence_threshold,
292                                 svc->absence_threshold);
293
294         DB_ACTION(sqlite3_bind_int(stmt, 1, svc->presence_threshold),
295                 error_code, handle_error);
296         DB_ACTION(sqlite3_bind_int(stmt, 2, svc->absence_threshold),
297                 error_code, handle_error);
298         DB_ACTION(sqlite3_bind_text(stmt, 3, svc->name, -1, SQLITE_TRANSIENT),
299                 error_code, handle_error);
300
301         sql_ret = sqlite3_step(stmt);
302         if (sql_ret != SQLITE_DONE) {
303                 UAM_ERR("Failed to update service info [%d:%s]",
304                         sql_ret, sqlite3_errmsg(database_handle));
305                 error_code = UAM_ERROR_DB_FAILED;
306                 goto handle_error;
307         }
308
309         UAM_DBG("Service info updated");
310
311 handle_error:
312         sqlite3_reset(stmt);
313         FUNC_EXIT;
314         return error_code;
315 }
316
317 int _uam_db_delete_service_info(const char *service_name)
318 {
319         FUNC_ENTRY;
320         int error_code = UAM_ERROR_NONE;
321         sqlite3_stmt *stmt = delete_service_info;
322         int sql_ret = SQLITE_OK;
323
324         error_code = _uam_db_delete_device_service(service_name);
325         if (UAM_ERROR_NONE != error_code) {
326                 UAM_ERR("_uam_db_delete_device_service failed");
327                 return error_code;
328         }
329
330         DB_ACTION(sqlite3_bind_text(stmt, 1, service_name, -1, SQLITE_STATIC),
331                 error_code, handle_error);
332
333         sql_ret = sqlite3_step(stmt);
334         if (sql_ret != SQLITE_DONE) {
335                 UAM_ERR("Failed to delete service info [%d:%s]",
336                         sql_ret, sqlite3_errmsg(database_handle));
337                 error_code = UAM_ERROR_DB_FAILED;
338         } else
339                 UAM_DBG("Service info deleted");
340
341 handle_error:
342         sqlite3_reset(stmt);
343         FUNC_EXIT;
344         return error_code;
345 }
346
347 int _uam_service_db_clear(void)
348 {
349         int error_code = UAM_ERROR_NONE;
350         sqlite3_stmt *stmt = delete_all_services;
351         int sql_ret = SQLITE_OK;
352
353         sql_ret = sqlite3_step(stmt);
354         if (sql_ret != SQLITE_DONE) {
355                 UAM_ERR("Failed to delete service data [%d:%s]",
356                         sql_ret, sqlite3_errmsg(database_handle));
357                 error_code = UAM_ERROR_DB_FAILED;
358                 goto handle_error;
359         }
360
361         UAM_DBG("Service data deleted ");
362
363 handle_error:
364
365         sqlite3_reset(stmt);
366         return error_code;
367 }
368
369 int _uam_db_update_service_cycle(const char *service_name, int cycle)
370 {
371         int error_code = UAM_ERROR_NONE;
372         sqlite3_stmt *stmt = update_cycle;
373         int sql_ret = SQLITE_OK;
374
375         retv_if(NULL == service_name, UAM_ERROR_INVALID_PARAMETER);
376
377         DB_ACTION(sqlite3_bind_int64(stmt, 1, cycle),
378                 error_code, handle_error);
379         DB_ACTION(sqlite3_bind_text(stmt, 2, service_name, -1, SQLITE_TRANSIENT),
380                 error_code, handle_error);
381
382         sql_ret = sqlite3_step(stmt);
383         if (sql_ret != SQLITE_DONE) {
384                 UAM_ERR("Failed to update service cycle [%d:%s]",
385                         sql_ret, sqlite3_errmsg(database_handle));
386
387                 error_code = UAM_ERROR_DB_FAILED;
388                 goto handle_error;
389         }
390
391         UAM_DBG("Service cycle updated [%d]", cycle);
392
393 handle_error:
394         sqlite3_reset(stmt);
395         return error_code;
396 }
397
398 int _uam_db_get_service_info(const char *service_name, db_service_info_t *info)
399 {
400         FUNC_ENTRY;
401         int error_code = UAM_ERROR_NOT_FOUND;
402         sqlite3_stmt *stmt = select_service;
403         int sql_ret = SQLITE_OK;
404
405         retv_if(!service_name, UAM_ERROR_INVALID_PARAMETER);
406         retv_if(!info, UAM_ERROR_INVALID_PARAMETER);
407
408         UAM_INFO("Service Name: %s", service_name);
409
410         DB_ACTION(sqlite3_bind_text(stmt, 1, service_name, -1, SQLITE_STATIC),
411                 error_code, handle_error);
412
413         do {
414                 sql_ret = sqlite3_step(stmt);
415                 switch (sql_ret) {
416                 case SQLITE_DONE:
417                         break;
418                 case SQLITE_ROW:
419                         UAM_DBG("Service info found");
420                         info->service_number = sqlite3_column_int(stmt, 0);
421                         g_strlcpy(info->service_name, (char *)sqlite3_column_text(stmt, 1),
422                                 UAM_SERVICE_MAX_STRING_LEN);
423                         info->cycle = sqlite3_column_int(stmt, 2);
424                         info->presence_threshold = sqlite3_column_int(stmt, 3);
425                         info->absence_threshold = sqlite3_column_int(stmt, 4);
426
427                         UAM_INFO("%d-%s-%d", info->service_number, info->service_name, info->cycle);
428                         error_code = UAM_ERROR_NONE;
429                         break;
430                 case SQLITE_ERROR:
431                 default:
432                         UAM_ERR("Failed to enumerate service info [%d:%s]",
433                                 sql_ret, sqlite3_errmsg(database_handle));
434                         error_code = UAM_ERROR_DB_FAILED;
435                 }
436         } while (sql_ret == SQLITE_ROW);
437
438 handle_error:
439         sqlite3_reset(stmt);
440         FUNC_EXIT;
441         return error_code;
442 }
443
444 GSList *_uam_service_db_get_all_services(void)
445 {
446         FUNC_ENTRY;
447         sqlite3_stmt *stmt = select_all_services;
448         GSList *service_list = NULL;
449         db_service_info_t *info = NULL;
450         int sql_ret = SQLITE_OK;
451
452         do {
453                 sql_ret = sqlite3_step(stmt);
454                 switch (sql_ret) {
455                 case SQLITE_DONE:
456                         break;
457                 case SQLITE_ROW:
458                         info = g_new0(db_service_info_t, 1);
459                         info->service_number = sqlite3_column_int(stmt, 0);
460                         g_strlcpy(info->service_name, (char *)sqlite3_column_text(stmt, 1),
461                                 UAM_SERVICE_MAX_STRING_LEN);
462                         info->cycle = sqlite3_column_int(stmt, 2);
463                         info->presence_threshold = sqlite3_column_int(stmt, 3);
464                         info->absence_threshold = sqlite3_column_int(stmt, 4);
465
466                         UAM_INFO("%d-%s-%d-%d-%d", info->service_number, info->service_name,
467                                  info->cycle, info->presence_threshold, info->absence_threshold);
468
469                         service_list = g_slist_append(service_list, info);
470                         break;
471                 case SQLITE_ERROR:
472                 default:
473                         UAM_ERR("Failed to enumerate service info [%d:%s]",
474                                 sql_ret, sqlite3_errmsg(database_handle));
475                 }
476         } while (sql_ret == SQLITE_ROW);
477
478         sqlite3_reset(stmt);
479         FUNC_EXIT;
480         return service_list;
481 }