Version 1.0
[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         _D("db_file : %s", db_file);
50         ret = sqlite3_open(db_file, &db);
51         if (SQLITE_OK != ret) {
52                 _E("%s", sqlite3_errmsg(db));
53                 return NULL;
54         }
55
56         return db;
57 }
58
59
60
61 HAPI void db_close(sqlite3 *db)
62 {
63         ret_if(!db);
64         sqlite3_close(db);
65 }
66
67
68
69 HAPI sqlite3_stmt *db_prepare(sqlite3 *db, const char *query)
70 {
71         sqlite3_stmt *stmt = NULL;
72         int ret = SQLITE_OK;
73
74         retv_if(!query, NULL);
75
76         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
77         if (SQLITE_OK != ret) {
78                 _E("%s, %s", query, sqlite3_errmsg(db));
79                 return NULL;
80         }
81
82         return stmt;
83 }
84
85
86
87 HAPI int db_next(sqlite3 *db, sqlite3_stmt *stmt)
88 {
89         int ret = SQLITE_OK;
90
91         retv_if(!stmt, APPL_ERROR_FAIL);
92
93         ret = sqlite3_step(stmt);
94         switch (ret) {
95         case SQLITE_ROW: /* SQLITE_ROW : 100 */
96                 return SQLITE_ROW;
97         case SQLITE_DONE: /* SQLITE_ROW : 101 */
98                 return SQLITE_DONE;
99         default:
100                 _E("%s", sqlite3_errmsg(db));
101                 return -1;
102         }
103
104         return -1;
105 }
106
107
108
109 HAPI int db_reset(sqlite3 *db, sqlite3_stmt *stmt)
110 {
111         int ret = SQLITE_OK;
112
113         retv_if(!stmt, APPL_ERROR_INVALID_PARAMETER);
114
115         ret = sqlite3_reset(stmt);
116         if (SQLITE_OK != ret) {
117                 _E("%s", sqlite3_errmsg(db));
118                 return APPL_ERROR_FAIL;
119         }
120
121         sqlite3_clear_bindings(stmt);
122
123         return APPL_ERROR_NONE;
124 }
125
126
127
128 HAPI int db_bind_bool(sqlite3 *db, sqlite3_stmt *stmt, int idx, bool value)
129 {
130         int ret = SQLITE_OK;
131
132         retv_if(!stmt, APPL_ERROR_FAIL);
133
134         ret = sqlite3_bind_int(stmt, idx, (int) value);
135         if (SQLITE_OK != ret) {
136                 _E("%s", sqlite3_errmsg(db));
137                 return APPL_ERROR_FAIL;
138         }
139
140         return APPL_ERROR_NONE;
141 }
142
143
144
145 HAPI int db_bind_int(sqlite3 *db, sqlite3_stmt *stmt, int idx, int value)
146 {
147         int ret = SQLITE_OK;
148
149         retv_if(!stmt, APPL_ERROR_FAIL);
150
151         ret = sqlite3_bind_int(stmt, idx, value);
152         if (SQLITE_OK != ret) {
153                 _E("%s", sqlite3_errmsg(db));
154                 return APPL_ERROR_FAIL;
155         }
156
157         return APPL_ERROR_NONE;
158 }
159
160
161
162 HAPI int db_bind_long(sqlite3 *db, sqlite3_stmt *stmt, int idx, long value)
163 {
164         int ret = SQLITE_OK;
165
166         retv_if(!stmt, APPL_ERROR_FAIL);
167
168         ret = sqlite3_bind_int64(stmt, idx, value);
169         if (SQLITE_OK != ret) {
170                 _E("%s", sqlite3_errmsg(db));
171                 return APPL_ERROR_FAIL;
172         }
173
174         return APPL_ERROR_NONE;
175 }
176
177
178
179 HAPI int db_bind_double(sqlite3 *db, sqlite3_stmt *stmt, int idx, double value)
180 {
181         int ret = SQLITE_OK;
182
183         retv_if(!stmt, APPL_ERROR_FAIL);
184
185         ret = sqlite3_bind_double(stmt, idx, value);
186         if (SQLITE_OK != ret) {
187                 _E("%s", sqlite3_errmsg(db));
188                 return APPL_ERROR_FAIL;
189         }
190
191         return APPL_ERROR_NONE;
192 }
193
194
195
196 HAPI int db_bind_str(sqlite3 *db, sqlite3_stmt *stmt, int idx, const char *str)
197 {
198         int ret = SQLITE_OK;
199
200         retv_if(!stmt, APPL_ERROR_FAIL);
201
202         if (str) {
203                 ret = sqlite3_bind_text(stmt, idx, str, -1, SQLITE_TRANSIENT);
204         } else {
205                 ret = sqlite3_bind_null(stmt, idx);
206         }
207
208         if (SQLITE_OK != ret) {
209                 _E("%s", sqlite3_errmsg(db));
210                 return APPL_ERROR_FAIL;
211         }
212
213         return APPL_ERROR_NONE;
214 }
215
216
217
218 HAPI bool db_get_bool(sqlite3_stmt *stmt, int index)
219 {
220         retv_if(!stmt, false);
221         return (bool) (!!sqlite3_column_int(stmt, index));
222 }
223
224
225
226 HAPI int db_get_int(sqlite3_stmt *stmt, int index)
227 {
228         retv_if(!stmt, 0);
229         return sqlite3_column_int(stmt, index);
230 }
231
232
233
234 HAPI int db_get_long(sqlite3_stmt *stmt, int index)
235 {
236         retv_if(!stmt, 0);
237         return sqlite3_column_int64(stmt, index);
238 }
239
240
241
242 HAPI int db_get_double(sqlite3_stmt *stmt, int index)
243 {
244         retv_if(!stmt, 0);
245         return sqlite3_column_double(stmt, index);
246 }
247
248
249
250 HAPI const char *db_get_str(sqlite3_stmt *stmt, int index)
251 {
252         retv_if(!stmt, NULL);
253         return (const char *) sqlite3_column_text(stmt, index);
254 }
255
256
257
258 HAPI int db_finalize(sqlite3 *db, sqlite3_stmt *stmt)
259 {
260         int ret = SQLITE_OK;
261
262         retv_if(!stmt, APPL_ERROR_INVALID_PARAMETER);
263
264         ret = sqlite3_finalize(stmt);
265         if (SQLITE_OK != ret) {
266                 _E("%s", sqlite3_errmsg(db));
267                 return APPL_ERROR_FAIL;
268         }
269
270         return APPL_ERROR_NONE;
271 }
272
273
274
275 HAPI int db_exec(sqlite3 *db, const char *query)
276 {
277         sqlite3_stmt *stmt = NULL;
278
279         retv_if(!query, APPL_ERROR_INVALID_PARAMETER);
280
281         stmt = db_prepare(db, query);
282         retv_if(!stmt, APPL_ERROR_FAIL);
283
284         goto_if(APPL_ERROR_FAIL == db_next(db, stmt), ERROR);
285         goto_if(APPL_ERROR_FAIL == db_finalize(db, stmt), ERROR);
286
287         return APPL_ERROR_NONE;
288
289 ERROR:
290         if (stmt) db_finalize(db, stmt);
291         return APPL_ERROR_FAIL;
292 }
293
294
295
296 HAPI int db_create_table(sqlite3 *db)
297 {
298         const char *TABLES[] = {
299                 "CREATE TABLE IF NOT EXISTS db_checksum (version INT);",
300                 "CREATE TABLE IF NOT EXISTS gr ("
301                         "id INTEGER PRIMARY KEY AUTOINCREMENT"
302                         ", title TEXT"
303                         ", city1 INTEGER"
304                         ", city2 INTEGER"
305                         ", city3 INTEGER"
306                         ", city4 INTEGER"
307                         ", city5 INTEGER"
308                         ");",
309         };
310         int count = 0;
311         int i = 0;
312
313         count = sizeof(TABLES) / sizeof(char *);
314         for (; i < count; i++) {
315                 _D("Create a table[%s]", TABLES[i]);
316                 break_if(db_exec(db, TABLES[i]) != APPL_ERROR_NONE);
317         }
318
319         return APPL_ERROR_FAIL;
320 }
321
322
323
324 HAPI int db_drop_table(sqlite3 *db)
325 {
326         const char *TABLES[] = {
327                 "DROP TABLE IF EXISTS db_checksum;",
328                 "DROP TABLE IF EXISTS gr;",
329         };
330         int count = 0;
331         int i = 0;
332
333         count = sizeof(TABLES) / sizeof(char *);
334         for (; i < count; i++) {
335                 _D("Drop a table[%s]", TABLES[i]);
336                 break_if(db_exec(db, TABLES[i]) != APPL_ERROR_NONE);
337         }
338
339         return APPL_ERROR_FAIL;
340 }
341
342
343
344 HAPI int db_insert_version(sqlite3 *db, int version)
345 {
346         const char *const QUERY_SYNTAX = "INSERT INTO db_checksum (version) VALUES (?);";
347         sqlite3_stmt *st = NULL;
348
349         st = db_prepare(db, QUERY_SYNTAX);
350         retv_if(!st, APPL_ERROR_DB_FAILED);
351
352         goto_if(db_bind_int(db, st, 1, version) != APPL_ERROR_NONE, error);
353         goto_if(db_next(db, st) == -1, error);
354
355         db_reset(db, st);
356         db_finalize(db, st);
357
358         /* keep this DB opened */
359
360         return APPL_ERROR_NONE;
361
362 error:
363         db_finalize(db, st);
364         return APPL_ERROR_DB_FAILED;
365 }
366
367
368
369 HAPI int db_remove_version(sqlite3 *db, int version)
370 {
371         const char *const QUERY_SYNTAX = "DELETE FROM db_checksum WHERE version = ?;";
372         sqlite3_stmt *st = NULL;
373
374         st = db_prepare(db, QUERY_SYNTAX);
375         retv_if(!st, APPL_ERROR_DB_FAILED);
376
377         goto_if(db_bind_int(db, st, 1, version) != APPL_ERROR_NONE, error);
378         goto_if(db_next(db, st) == -1, error);
379
380         db_reset(db, st);
381         db_finalize(db, st);
382
383         /* keep this DB opened */
384
385         return APPL_ERROR_NONE;
386
387 error:
388         db_finalize(db, st);
389         return APPL_ERROR_DB_FAILED;
390 }
391
392
393
394 HAPI int db_update_version(sqlite3 *db, int version)
395 {
396         const char *const QUERY_SYNTAX = "UPDATE db_checksum SET version = ?;";
397         sqlite3_stmt *st = NULL;
398
399         st = db_prepare(db, QUERY_SYNTAX);
400         retv_if(!st, APPL_ERROR_DB_FAILED);
401
402         goto_if(db_bind_int(db, st, 1, version) != APPL_ERROR_NONE, error);
403         goto_if(db_next(db, st) == -1, error);
404
405         db_reset(db, st);
406         db_finalize(db, st);
407
408         /* keep this DB opened */
409
410         return APPL_ERROR_NONE;
411
412 error:
413         db_finalize(db, st);
414         return APPL_ERROR_DB_FAILED;
415 }
416
417
418
419 HAPI int db_count_version(sqlite3 *db)
420 {
421         const char *const QUERY_SYNTAX = "SELECT COUNT(*) FROM db_checksum;";
422         sqlite3_stmt *st = NULL;
423         int count = 0;
424
425         st = db_prepare(db, QUERY_SYNTAX);
426         retv_if(!st, APPL_ERROR_DB_FAILED);
427
428         if (db_next(db, st) == -1) {
429                 _E("db_next error");
430                 db_finalize(db, st);
431                 return -1;
432         }
433
434         count = db_get_int(st, 0);
435         db_reset(db, st);
436         db_finalize(db, st);
437
438         /* keep this DB opened */
439
440         return count;
441 }
442
443
444
445 HAPI int db_count_group(sqlite3 *db, int *count)
446 {
447         const char *const QUERY_SYNTAX = "SELECT COUNT(*) FROM gr;";
448         sqlite3_stmt *st = NULL;
449
450         st = db_prepare(db, QUERY_SYNTAX);
451         retv_if(!st, APPL_ERROR_FAIL);
452
453         goto_if(db_next(db, st) == -1, error);
454
455         *count = db_get_int(st, 0);
456
457         db_reset(db, st);
458         db_finalize(db, st);
459
460         /* keep this DB opened */
461
462         return APPL_ERROR_NONE;
463
464 error:
465         db_finalize(db, st);
466         return APPL_ERROR_FAIL;
467 }
468
469
470
471 HAPI int db_max_group(sqlite3 *db, int *max)
472 {
473         const char *const QUERY_SYNTAX = "SELECT MAX(id) FROM gr;";
474         sqlite3_stmt *st = NULL;
475
476         st = db_prepare(db, QUERY_SYNTAX);
477         retv_if(!st, APPL_ERROR_FAIL);
478
479         goto_if(db_next(db, st) == -1, error);
480
481         *max = db_get_int(st, 0);
482
483         db_reset(db, st);
484         db_finalize(db, st);
485
486         /* keep this DB opened */
487
488         return APPL_ERROR_NONE;
489
490 error:
491         db_finalize(db, st);
492         return APPL_ERROR_FAIL;
493 }
494
495
496
497 HAPI int db_insert_group(sqlite3 *db, const char *title, int city1, int city2, int city3, int city4, int city5)
498 {
499         const char *const QUERY_INSERT = "INSERT INTO gr (id, title, city1, city2, city3, city4, city5) VALUES (?, ?, ?, ?, ?, ?, ?);";
500         sqlite3_stmt *st = NULL;
501         int max = 0;
502         _D("HELLO, %s %d:%d:%d", title, city1, city2, city3);
503
504         db_max_group(db, &max);
505         max++;
506
507         st = db_prepare(db, QUERY_INSERT);
508         retv_if(!st, -1);
509
510         goto_if(db_bind_int(db, st, 1, max) != APPL_ERROR_NONE, error);
511         goto_if(db_bind_str(db, st, 2, title) != APPL_ERROR_NONE, error);
512         goto_if(db_bind_int(db, st, 3, city1) != APPL_ERROR_NONE, error);
513         goto_if(db_bind_int(db, st, 4, city2) != APPL_ERROR_NONE, error);
514         goto_if(db_bind_int(db, st, 5, city3) != APPL_ERROR_NONE, error);
515         goto_if(db_bind_int(db, st, 6, city4) != APPL_ERROR_NONE, error);
516         goto_if(db_bind_int(db, st, 7, city5) != APPL_ERROR_NONE, error);
517         goto_if(db_next(db, st) == -1, error);
518
519         db_reset(db, st);
520         db_finalize(db, st);
521
522         /* keep the sticker panel DB opened */
523
524         return max;
525
526 error:
527         db_finalize(db, st);
528         return -1;
529 }
530
531
532
533 HAPI int db_update_group(sqlite3 *db, int id, const char *title, int city1, int city2, int city3, int city4, int city5)
534 {
535         const char *const QUERY_UPDATE = "UPDATE gr SET title = ?, city1 = ?, city2 = ?, city3 = ?, city4 = ?, city5 = ? WHERE id = ?;";
536         sqlite3_stmt *st = NULL;
537
538         st = db_prepare(db, QUERY_UPDATE);
539         retv_if(!st, APPL_ERROR_FAIL);
540
541         goto_if(db_bind_str(db, st, 1, title) != APPL_ERROR_NONE, error);
542         goto_if(db_bind_int(db, st, 2, city1) != APPL_ERROR_NONE, error);
543         goto_if(db_bind_int(db, st, 3, city2) != APPL_ERROR_NONE, error);
544         goto_if(db_bind_int(db, st, 4, city3) != APPL_ERROR_NONE, error);
545         goto_if(db_bind_int(db, st, 5, city4) != APPL_ERROR_NONE, error);
546         goto_if(db_bind_int(db, st, 6, city5) != APPL_ERROR_NONE, error);
547         goto_if(db_bind_int(db, st, 7, id) != APPL_ERROR_NONE, error);
548         goto_if(db_next(db, st) == -1, error);
549
550         db_reset(db, st);
551         db_finalize(db, st);
552
553         /* keep the sticker panel DB opened */
554
555         return APPL_ERROR_NONE;
556
557 error:
558         db_finalize(db, st);
559         return APPL_ERROR_FAIL;
560 }
561
562
563
564 HAPI int db_delete_group(sqlite3 *db, int id)
565 {
566         const char *const QUERY_SYNTAX = "DELETE FROM gr WHERE id = ?;";
567         sqlite3_stmt *st = NULL;
568
569         st = db_prepare(db, QUERY_SYNTAX);
570         retv_if(!st, APPL_ERROR_FAIL);
571
572         goto_if(db_bind_int(db, st, 1, id) != APPL_ERROR_NONE, error);
573         goto_if(db_next(db, st) == -1, error);
574
575         db_reset(db, st);
576         db_finalize(db, st);
577
578         /* keep the sticker panel DB opened */
579
580         return APPL_ERROR_NONE;
581
582 error:
583         db_finalize(db, st);
584         return APPL_ERROR_FAIL;
585 }
586
587
588
589 HAPI int db_list_group(sqlite3 *db, Eina_List **group_list)
590 {
591         const char *const QUERY_LIST = "SELECT id, title, city1, city2, city3, city4, city5 FROM gr ORDER BY id ASC";
592         sqlite3_stmt *st = NULL;
593         group_info_s *group_info = NULL;
594
595         int ret = -1;
596
597         st = db_prepare(db, QUERY_LIST);
598         retv_if(!st, APPL_ERROR_FAIL);
599
600         do {
601                 int id = 0;
602                 const char *title = NULL;
603                 int city1 = 0, city2 = 0, city3 = 0, city4 = 0, city5 = 0;
604                 ret = db_next(db, st);
605                 if (SQLITE_DONE == ret) {
606                         break;
607                 } else if (-1 == ret) {
608                         _E("db_next() error");
609                         goto error;
610                 }
611
612                 id = db_get_int(st, 0);
613                 title = db_get_str(st, 1);
614                 city1 = db_get_int(st, 2);
615                 city2 = db_get_int(st, 3);
616                 city3 = db_get_int(st, 4);
617                 city4 = db_get_int(st, 5);
618                 city5 = db_get_int(st, 6);
619
620                 group_info = group_info_create(id, title, city1, city2, city3, city4, city5);
621                 continue_if(!group_info);
622
623                 *group_list = eina_list_append(*group_list, group_info);
624         } while (SQLITE_ROW == ret);
625
626         db_reset(db, st);
627         db_finalize(db, st);
628
629         /* keep the sticker panel DB opened */
630
631         return APPL_ERROR_NONE;
632
633 error:
634         EINA_LIST_FREE(*group_list, group_info) {
635                 group_info_destroy(group_info);
636         }
637
638         db_finalize(db, st);
639         return APPL_ERROR_FAIL;
640 }
641
642
643
644 // End of file.