68250228fe5ac914e78bf7ae8718d8512171c5c4
[apps/native/sample/adventure.git] / src / db.c
1 /*
2  * Samsung API
3  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/license/
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an AS IS BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <Evas.h>
19 #include <sqlite3.h>
20 #include <stdbool.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <app_common.h>
25
26 #include "db.h"
27 #include "log.h"
28 #include "util.h"
29 #include "group_info.h"
30
31 #define APP_DB_FILE ".app.db"
32
33
34
35
36 HAPI sqlite3 *db_open(void)
37 {
38         sqlite3 *db = NULL;
39         char *path = NULL;
40         char db_file[FILE_LEN] = {0, };
41         int ret = SQLITE_OK;
42
43         path = app_get_data_path();
44         retv_if(!path, NULL);
45         
46         snprintf(db_file, sizeof(db_file), "%s/%s", path, APP_DB_FILE);
47         free(path);
48
49         ret = sqlite3_open(db_file, &db);
50         if (SQLITE_OK != ret) {
51                 _E("%s", sqlite3_errmsg(db));
52                 return NULL;
53         }
54
55         return db;
56 }
57
58
59
60 HAPI void db_close(sqlite3 *db)
61 {
62         ret_if(!db);
63         sqlite3_close(db);
64 }
65
66
67
68 HAPI sqlite3_stmt *db_prepare(sqlite3 *db, const char *query)
69 {
70         sqlite3_stmt *stmt = NULL;
71         int ret = SQLITE_OK;
72
73         retv_if(!query, NULL);
74
75         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
76         if (SQLITE_OK != ret) {
77                 _E("%s, %s", query, sqlite3_errmsg(db));
78                 return NULL;
79         }
80
81         return stmt;
82 }
83
84
85
86 HAPI int db_next(sqlite3 *db, sqlite3_stmt *stmt)
87 {
88         int ret = SQLITE_OK;
89
90         retv_if(!stmt, APPL_ERROR_FAIL);
91
92         ret = sqlite3_step(stmt);
93         switch (ret) {
94         case SQLITE_ROW: /* SQLITE_ROW : 100 */
95                 return APPL_ERROR_NONE;
96         case SQLITE_DONE: /* SQLITE_ROW : 101 */
97                 return APPL_ERROR_NO_DATA;
98         default:
99                 _E("%s", sqlite3_errmsg(db));
100                 return APPL_ERROR_FAIL;
101         }
102
103         return APPL_ERROR_NONE;
104 }
105
106
107
108 HAPI int db_reset(sqlite3 *db, sqlite3_stmt *stmt)
109 {
110         int ret = SQLITE_OK;
111
112         retv_if(!stmt, APPL_ERROR_INVALID_PARAMETER);
113
114         ret = sqlite3_reset(stmt);
115         if (SQLITE_OK != ret) {
116                 _E("%s", sqlite3_errmsg(db));
117                 return APPL_ERROR_FAIL;
118         }
119
120         sqlite3_clear_bindings(stmt);
121
122         return APPL_ERROR_NONE;
123 }
124
125
126
127 HAPI int db_bind_bool(sqlite3 *db, sqlite3_stmt *stmt, int idx, bool value)
128 {
129         int ret = SQLITE_OK;
130
131         retv_if(!stmt, APPL_ERROR_FAIL);
132
133         ret = sqlite3_bind_int(stmt, idx, (int) value);
134         if (SQLITE_OK != ret) {
135                 _E("%s", sqlite3_errmsg(db));
136                 return APPL_ERROR_FAIL;
137         }
138
139         return APPL_ERROR_NONE;
140 }
141
142
143
144 HAPI int db_bind_int(sqlite3 *db, sqlite3_stmt *stmt, int idx, int value)
145 {
146         int ret = SQLITE_OK;
147
148         retv_if(!stmt, APPL_ERROR_FAIL);
149
150         ret = sqlite3_bind_int(stmt, idx, value);
151         if (SQLITE_OK != ret) {
152                 _E("%s", sqlite3_errmsg(db));
153                 return APPL_ERROR_FAIL;
154         }
155
156         return APPL_ERROR_NONE;
157 }
158
159
160
161 HAPI int db_bind_double(sqlite3 *db, sqlite3_stmt *stmt, int idx, double value)
162 {
163         int ret = SQLITE_OK;
164
165         retv_if(!stmt, APPL_ERROR_FAIL);
166
167         ret = sqlite3_bind_double(stmt, idx, value);
168         if (SQLITE_OK != ret) {
169                 _E("%s", sqlite3_errmsg(db));
170                 return APPL_ERROR_FAIL;
171         }
172
173         return APPL_ERROR_NONE;
174 }
175
176
177
178 HAPI int db_bind_str(sqlite3 *db, sqlite3_stmt *stmt, int idx, const char *str)
179 {
180         int ret = SQLITE_OK;
181
182         retv_if(!stmt, APPL_ERROR_FAIL);
183
184         if (str) {
185                 ret = sqlite3_bind_text(stmt, idx, str, -1, SQLITE_TRANSIENT);
186         } else {
187                 ret = sqlite3_bind_null(stmt, idx);
188         }
189
190         if (SQLITE_OK != ret) {
191                 _E("%s", sqlite3_errmsg(db));
192                 return APPL_ERROR_FAIL;
193         }
194
195         return APPL_ERROR_NONE;
196 }
197
198
199
200 HAPI bool db_get_bool(sqlite3_stmt *stmt, int index)
201 {
202         retv_if(!stmt, false);
203         return (bool) (!!sqlite3_column_int(stmt, index));
204 }
205
206
207
208 HAPI int db_get_int(sqlite3_stmt *stmt, int index)
209 {
210         retv_if(!stmt, 0);
211         return sqlite3_column_int(stmt, index);
212 }
213
214
215
216 HAPI int db_get_double(sqlite3_stmt *stmt, int index)
217 {
218         retv_if(!stmt, 0);
219         return sqlite3_column_double(stmt, index);
220 }
221
222
223
224 HAPI const char *db_get_str(sqlite3_stmt *stmt, int index)
225 {
226         retv_if(!stmt, NULL);
227         return (const char *) sqlite3_column_text(stmt, index);
228 }
229
230
231
232 HAPI int db_finalize(sqlite3 *db, sqlite3_stmt *stmt)
233 {
234         int ret = SQLITE_OK;
235
236         retv_if(!stmt, APPL_ERROR_INVALID_PARAMETER);
237
238         ret = sqlite3_finalize(stmt);
239         if (SQLITE_OK != ret) {
240                 _E("%s", sqlite3_errmsg(db));
241                 return APPL_ERROR_FAIL;
242         }
243
244         return APPL_ERROR_NONE;
245 }
246
247
248
249 HAPI int db_exec(sqlite3 *db, const char *query)
250 {
251         sqlite3_stmt *stmt = NULL;
252
253         retv_if(!query, APPL_ERROR_INVALID_PARAMETER);
254
255         stmt = db_prepare(db, query);
256         retv_if(!stmt, APPL_ERROR_FAIL);
257
258         goto_if(APPL_ERROR_FAIL == db_next(db, stmt), ERROR);
259         goto_if(APPL_ERROR_FAIL == db_finalize(db, stmt), ERROR);
260
261         return APPL_ERROR_NONE;
262
263 ERROR:
264         if (stmt) db_finalize(db, stmt);
265         return APPL_ERROR_FAIL;
266 }
267
268
269
270 HAPI int db_create_table(sqlite3 *db)
271 {
272         const char *TABLES[] = {
273                 "CREATE TABLE IF NOT EXIST db_checksum (version INT);",
274                 "CREATE TABLE IF NOT EXIST group ("
275                         "time INTEGER PRIMARY KEY"
276                         ", title TEXT"
277                         ", city1 INT"
278                         ", city2 INT"
279                         ", city3 INT"
280                         ", city4 INT"
281                         ", city5 INT"
282                         ");",
283         };
284         int count = 0;
285         int i = 0;
286
287         count = sizeof(TABLES) / sizeof(char *);
288         for (; i < count; i++) {
289                 _D("Create a table[%s]", TABLES[i]);
290                 break_if(db_exec(db, TABLES[i]) != APPL_ERROR_NONE);
291         }
292
293         return APPL_ERROR_FAIL;
294 }
295
296
297
298 HAPI int db_drop_table(sqlite3 *db)
299 {
300         const char *TABLES[] = {
301                 "DROP TABLE IF EXIST db_checksum;",
302                 "DROP TABLE IF EXIST group;",
303         };
304         int count = 0;
305         int i = 0;
306
307         count = sizeof(TABLES) / sizeof(char *);
308         for (; i < count; i++) {
309                 _D("Drop a table[%s]", TABLES[i]);
310                 break_if(db_exec(db, TABLES[i]) != APPL_ERROR_NONE);
311         }
312
313         return APPL_ERROR_FAIL;
314 }
315
316
317
318 HAPI int db_insert_version(sqlite3 *db, int version)
319 {
320         const char *const QUERY_SYNTAX = "INSERT INTO db_checksum (version) VALUES (?);";
321         sqlite3_stmt *st = NULL;
322
323         st = db_prepare(db, QUERY_SYNTAX);
324         retv_if(!st, APPL_ERROR_DB_FAILED);
325
326         goto_if(db_bind_int(db, st, 1, version) != APPL_ERROR_NONE, error);
327         goto_if(db_next(db, st) == -1, error);
328
329         db_reset(db, st);
330         db_finalize(db, st);
331
332         /* keep this DB opened */
333
334         return APPL_ERROR_NONE;
335
336 error:
337         db_finalize(db, st);
338         return APPL_ERROR_DB_FAILED;
339 }
340
341
342
343 HAPI int db_remove_version(sqlite3 *db, int version)
344 {
345         const char *const QUERY_SYNTAX = "DELETE FROM db_checksum WHERE version = ?;";
346         sqlite3_stmt *st = NULL;
347
348         st = db_prepare(db, QUERY_SYNTAX);
349         retv_if(!st, APPL_ERROR_DB_FAILED);
350
351         goto_if(db_bind_int(db, st, 1, version) != APPL_ERROR_NONE, error);
352         goto_if(db_next(db, st) == -1, error);
353
354         db_reset(db, st);
355         db_finalize(db, st);
356
357         /* keep this DB opened */
358
359         return APPL_ERROR_NONE;
360
361 error:
362         db_finalize(db, st);
363         return APPL_ERROR_DB_FAILED;
364 }
365
366
367
368 HAPI int db_update_version(sqlite3 *db, int version)
369 {
370         const char *const QUERY_SYNTAX = "UPDATE db_checksum SET version = ?;";
371         sqlite3_stmt *st = NULL;
372
373         st = db_prepare(db, QUERY_SYNTAX);
374         retv_if(!st, APPL_ERROR_DB_FAILED);
375
376         goto_if(db_bind_int(db, st, 1, version) != APPL_ERROR_NONE, error);
377         goto_if(db_next(db, st) == -1, error);
378
379         db_reset(db, st);
380         db_finalize(db, st);
381
382         /* keep this DB opened */
383
384         return APPL_ERROR_NONE;
385
386 error:
387         db_finalize(db, st);
388         return APPL_ERROR_DB_FAILED;
389 }
390
391
392
393 HAPI int db_count_version(sqlite3 *db)
394 {
395         const char *const QUERY_SYNTAX = "SELECT COUNT(*) FROM db_checksum;";
396         sqlite3_stmt *st = NULL;
397         int count = 0;
398
399         st = db_prepare(db, QUERY_SYNTAX);
400         retv_if(!st, APPL_ERROR_DB_FAILED);
401
402         if (db_next(db, st) == -1) {
403                 _E("db_next error");
404                 db_finalize(db, st);
405                 return -1;
406         }
407
408         count = db_get_int(st, 0);
409         db_reset(db, st);
410         db_finalize(db, st);
411
412         /* keep this DB opened */
413
414         return count;
415 }
416
417
418
419 HAPI int db_count_group(sqlite3 *db, int *count)
420 {
421         const char *const QUERY_SYNTAX = "SELECT COUNT(*) FROM group;";
422         sqlite3_stmt *st = NULL;
423
424         st = db_prepare(db, QUERY_SYNTAX);
425         retv_if(!st, APPL_ERROR_FAIL);
426
427         goto_if(db_next(db, st) == -1, error);
428
429         *count = db_get_int(st, 0);
430
431         db_reset(db, st);
432         db_finalize(db, st);
433
434         /* keep this DB opened */
435
436         return APPL_ERROR_NONE;
437
438 error:
439         db_finalize(db, st);
440         return APPL_ERROR_FAIL;
441 }
442
443
444
445 HAPI int db_insert_group(sqlite3 *db, const char *title, int city1, int city2, int city3, int city4, int city5)
446 {
447         const char *const QUERY_INSERT = "INSERT INTO group (time, title, city1, city2, city3, city4, city5) VALUES (DATETIME('now'), ?, ?, ?, ?, ?, ?);";
448         sqlite3_stmt *st = NULL;
449
450         st = db_prepare(db, QUERY_INSERT);
451         retv_if(!st, APPL_ERROR_FAIL);
452
453         goto_if(db_bind_str(db, st, 1, title) != APPL_ERROR_NONE, error);
454         goto_if(db_bind_int(db, st, 2, city1) != APPL_ERROR_NONE, error);
455         goto_if(db_bind_int(db, st, 3, city2) != APPL_ERROR_NONE, error);
456         goto_if(db_bind_int(db, st, 4, city3) != APPL_ERROR_NONE, error);
457         goto_if(db_bind_int(db, st, 5, city4) != APPL_ERROR_NONE, error);
458         goto_if(db_bind_int(db, st, 6, city5) != APPL_ERROR_NONE, error);
459         goto_if(db_next(db, st) == -1, error);
460
461         db_reset(db, st);
462         db_finalize(db, st);
463
464         /* keep the sticker panel DB opened */
465
466         return APPL_ERROR_NONE;
467
468 error:
469         db_finalize(db, st);
470         return APPL_ERROR_FAIL;
471 }
472
473
474
475 HAPI int db_update_group(sqlite3 *db, int time, const char *title, int city1, int city2, int city3, int city4, int city5)
476 {
477         const char *const QUERY_UPDATE = "UPDATE group SET title = ?, city1 = ?, city2 = ?, city3 = ?, city4 = ?, city5 = ? WHERE time = ?;";
478         sqlite3_stmt *st = NULL;
479
480         st = db_prepare(db, QUERY_UPDATE);
481         retv_if(!st, APPL_ERROR_FAIL);
482
483         goto_if(db_bind_str(db, st, 1, title) != APPL_ERROR_NONE, error);
484         goto_if(db_bind_int(db, st, 2, city1) != APPL_ERROR_NONE, error);
485         goto_if(db_bind_int(db, st, 3, city2) != APPL_ERROR_NONE, error);
486         goto_if(db_bind_int(db, st, 4, city3) != APPL_ERROR_NONE, error);
487         goto_if(db_bind_int(db, st, 5, city4) != APPL_ERROR_NONE, error);
488         goto_if(db_bind_int(db, st, 6, city5) != APPL_ERROR_NONE, error);
489         goto_if(db_bind_int(db, st, 7, time) != APPL_ERROR_NONE, error);
490         goto_if(db_next(db, st) == -1, error);
491
492         db_reset(db, st);
493         db_finalize(db, st);
494
495         /* keep the sticker panel DB opened */
496
497         return APPL_ERROR_NONE;
498
499 error:
500         db_finalize(db, st);
501         return APPL_ERROR_FAIL;
502 }
503
504
505
506 HAPI int db_delete_group(sqlite3 *db, int time)
507 {
508         const char *const QUERY_SYNTAX = "DELETE FROM group WHERE time = ?;";
509         sqlite3_stmt *st = NULL;
510
511         st = db_prepare(db, QUERY_SYNTAX);
512         retv_if(!st, APPL_ERROR_FAIL);
513
514         goto_if(db_bind_int(db, st, 1, time) != APPL_ERROR_NONE, error);
515         goto_if(db_next(db, st) == -1, error);
516
517         db_reset(db, st);
518         db_finalize(db, st);
519
520         /* keep the sticker panel DB opened */
521
522         return APPL_ERROR_NONE;
523
524 error:
525         db_finalize(db, st);
526         return APPL_ERROR_FAIL;
527 }
528
529
530
531 struct _group_s {
532         char *title;
533         int time;
534         int city1;
535         int city2;
536         int city3;
537         int city4;
538         int city5;
539 };
540 typedef struct _group_s group_s;
541
542
543
544 HAPI int db_list_group(sqlite3 *db, Eina_List **group_list, int limit)
545 {
546         const char *const QUERY_LIST = "SELECT time, title, city1, city2, city3, city4, city5 FROM group ORDER BY time ASC";
547         sqlite3_stmt *st = NULL;
548         group_info_s *group_info = NULL;
549
550         int ret = -1;
551
552         st = db_prepare(db, QUERY_LIST);
553         retv_if(!st, APPL_ERROR_FAIL);
554
555         do {
556                 int time = 0;
557                 const char *title = NULL;
558                 int city1 = 0, city2 = 0, city3 = 0, city4 = 0, city5 = 0;
559                 ret = db_next(db, st);
560                 if (SQLITE_DONE == ret) {
561                         break;
562                 } else if (-1 == ret) {
563                         _E("db_next() error");
564                         goto error;
565                 }
566
567                 time = db_get_int(st, 0);
568                 title = db_get_str(st, 1);
569                 city1 = db_get_int(st, 2);
570                 city2 = db_get_int(st, 3);
571                 city3 = db_get_int(st, 4);
572                 city4 = db_get_int(st, 5);
573                 city5 = db_get_int(st, 6);
574
575                 group_info = group_info_create(time, title, city1, city2, city3, city4, city5);
576                 continue_if(!group_info);
577
578                 *group_list = eina_list_append(*group_list, group_info);
579         } while (SQLITE_ROW == ret);
580
581         db_reset(db, st);
582         db_finalize(db, st);
583
584         /* keep the sticker panel DB opened */
585
586         return APPL_ERROR_NONE;
587
588 error:
589         EINA_LIST_FREE(*group_list, group_info) {
590                 group_info_destroy(group_info);
591         }
592
593         db_finalize(db, st);
594         return APPL_ERROR_FAIL;
595 }
596
597
598
599 // End of file.